Procházet zdrojové kódy

refactor: unify probe ID generate and match

zmstone před 1 rokem
rodič
revize
c15c12fc7e

+ 1 - 1
apps/emqx_bridge/src/emqx_bridge_resource.erl

@@ -282,7 +282,7 @@ create_dry_run(Type0, Conf0) ->
     end.
 
 create_dry_run_bridge_v1(Type, Conf0) ->
-    TmpName = iolist_to_binary([?TEST_ID_PREFIX, emqx_utils:gen_id(8)]),
+    TmpName = ?PROBE_ID_NEW(),
     TmpPath = emqx_utils:safe_filename(TmpName),
     %% Already type checked, no need to catch errors
     TypeBin = bin(Type),

+ 2 - 2
apps/emqx_bridge/src/emqx_bridge_v2.erl

@@ -781,7 +781,7 @@ create_dry_run(ConfRootKey, Type, Conf0) ->
     end.
 
 create_dry_run_helper(ConfRootKey, BridgeV2Type, ConnectorRawConf, BridgeV2RawConf) ->
-    BridgeName = iolist_to_binary([?TEST_ID_PREFIX, emqx_utils:gen_id(8)]),
+    BridgeName = ?PROBE_ID_NEW(),
     ConnectorType = connector_type(BridgeV2Type),
     OnReadyCallback =
         fun(ConnectorId) ->
@@ -1708,7 +1708,7 @@ get_conf_root_key(_NoMatch) ->
 
 bridge_v1_create_dry_run(BridgeType, RawConfig0) ->
     RawConf = maps:without([<<"name">>], RawConfig0),
-    TmpName = iolist_to_binary([?TEST_ID_PREFIX, emqx_utils:gen_id(8)]),
+    TmpName = ?PROBE_ID_NEW(),
     PreviousRawConf = undefined,
     try
         #{

+ 0 - 9
apps/emqx_bridge_kafka/test/emqx_bridge_kafka_impl_producer_SUITE.erl

@@ -234,14 +234,6 @@ t_rest_api(Config) ->
     },
     ok = kafka_bridge_rest_api_helper(Cfg).
 
-%% So that we can check if new atoms are created when they are not supposed to be created
-pre_create_atoms() ->
-    [
-        kafka_producer__probe_,
-        probedryrun,
-        kafka__probe_
-    ].
-
 http_get_bridges(UrlPath, Name0) ->
     Name = iolist_to_binary(Name0),
     {ok, _Code, BridgesData} = http_get(UrlPath),
@@ -307,7 +299,6 @@ kafka_bridge_rest_api_helper(Config) ->
         ?assertMatch([#{<<"type">> := <<"kafka">>}], http_get_bridges(BridgesParts, BridgeName)),
         %% Probe should work
         %% no extra atoms should be created when probing
-        %% See pre_create_atoms() above
         AtomsBefore = erlang:system_info(atom_count),
         {ok, 204, _} = http_post(BridgesProbeParts, CreateBody),
         AtomsAfter = erlang:system_info(atom_count),

+ 6 - 4
apps/emqx_connector/src/emqx_connector_resource.erl

@@ -52,6 +52,8 @@
 
 -export([parse_url/1]).
 
+-define(PROBE_ID_SEP, $_).
+
 -callback connector_config(ParsedConfig, Context) ->
     ParsedConfig
 when
@@ -90,7 +92,8 @@ parse_connector_id(ConnectorId) ->
     {atom(), atom() | binary()}.
 parse_connector_id(<<"connector:", ConnectorId/binary>>, Opts) ->
     parse_connector_id(ConnectorId, Opts);
-parse_connector_id(<<?TEST_ID_PREFIX, _:16/binary, ConnectorId/binary>>, Opts) ->
+parse_connector_id(?PROBE_ID_MATCH(Suffix), Opts) ->
+    <<?PROBE_ID_SEP, ConnectorId/binary>> = Suffix,
     parse_connector_id(ConnectorId, Opts);
 parse_connector_id(ConnectorId, Opts) ->
     emqx_resource:parse_resource_id(ConnectorId, Opts).
@@ -214,9 +217,8 @@ create_dry_run(Type, Conf0, Callback) ->
     TypeAtom = safe_atom(Type),
     %% We use a fixed name here to avoid creating an atom
     %% to avoid potential race condition, the resource id should be unique
-    Prefix = emqx_resource_manager:make_test_id(),
-    TmpName =
-        iolist_to_binary([Prefix, TypeBin, ":", <<"probedryrun">>]),
+    Prefix = ?PROBE_ID_NEW(),
+    TmpName = iolist_to_binary([Prefix, ?PROBE_ID_SEP, TypeBin, $:, "dryrun"]),
     TmpPath = emqx_utils:safe_filename(TmpName),
     Conf1 = maps:without([<<"name">>], Conf0),
     RawConf = #{<<"connectors">> => #{TypeBin => #{<<"temp_name">> => Conf1}}},

+ 6 - 1
apps/emqx_resource/include/emqx_resource.hrl

@@ -159,7 +159,12 @@
 
 %% Keep this test_id_prefix is match "^[A-Za-z0-9]+[A-Za-z0-9-_]*$".
 %% See `hocon_tconf`
--define(TEST_ID_PREFIX, "t_probe_").
+-define(PROBE_ID_PREFIX, "PROBE_").
+-define(PROBE_ID_RAND_BYTES, 8).
+-define(PROBE_ID_NEW(),
+    iolist_to_binary([?PROBE_ID_PREFIX, emqx_utils:rand_id(?PROBE_ID_RAND_BYTES)])
+).
+-define(PROBE_ID_MATCH(Suffix), <<?PROBE_ID_PREFIX, _:?PROBE_ID_RAND_BYTES/binary, Suffix/binary>>).
 -define(RES_METRICS, resource_metrics).
 -define(LOG_LEVEL(_L_),
     case _L_ of

+ 7 - 5
apps/emqx_resource/src/emqx_resource.erl

@@ -799,11 +799,13 @@ validate_name(Name) ->
     ok.
 
 -spec is_dry_run(resource_id()) -> boolean().
-is_dry_run(ResId) ->
-    case string:find(ResId, ?TEST_ID_PREFIX) of
-        nomatch -> false;
-        TestIdStart -> string:equal(TestIdStart, ResId)
-    end.
+is_dry_run(?PROBE_ID_MATCH(_)) ->
+    %% A probe connector
+    true;
+is_dry_run(ID) ->
+    %% A probe action/source
+    RE = ":" ++ ?PROBE_ID_PREFIX ++ "[a-zA-Z0-9]{8}:",
+    match =:= re:run(ID, RE, [{capture, none}]).
 
 validate_name(<<>>, _Opts) ->
     invalid_data("Name cannot be empty string");

+ 2 - 7
apps/emqx_resource/src/emqx_resource_manager.erl

@@ -55,8 +55,7 @@
 ]).
 
 -export([
-    set_resource_status_connecting/1,
-    make_test_id/0
+    set_resource_status_connecting/1
 ]).
 
 % Server
@@ -231,7 +230,7 @@ create(ResId, Group, ResourceType, Config, Opts) ->
 -spec create_dry_run(resource_module(), resource_config()) ->
     ok | {error, Reason :: term()}.
 create_dry_run(ResourceType, Config) ->
-    ResId = make_test_id(),
+    ResId = ?PROBE_ID_NEW(),
     create_dry_run(ResId, ResourceType, Config).
 
 create_dry_run(ResId, ResourceType, Config) ->
@@ -1007,10 +1006,6 @@ terminate_health_check_workers(Data) ->
         Pending
     ).
 
-make_test_id() ->
-    RandId = iolist_to_binary(emqx_utils:gen_id(16)),
-    <<?TEST_ID_PREFIX, RandId/binary>>.
-
 handle_add_channel(From, Data, ChannelId, Config) ->
     Channels = Data#data.added_channels,
     case

+ 39 - 0
apps/emqx_resource/test/emqx_resource_tests.erl

@@ -0,0 +1,39 @@
+%%--------------------------------------------------------------------
+%% Copyright (c) 2024 EMQ Technologies Co., Ltd. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%%     http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%--------------------------------------------------------------------
+
+-module(emqx_resource_tests).
+
+-include_lib("eunit/include/eunit.hrl").
+-include("emqx_resource.hrl").
+
+is_dry_run_test_() ->
+    [
+        ?_assert(emqx_resource:is_dry_run(?PROBE_ID_NEW())),
+        ?_assertNot(emqx_resource:is_dry_run("foobar")),
+        ?_assert(emqx_resource:is_dry_run(bin([?PROBE_ID_NEW(), "_abc"]))),
+        ?_assert(
+            emqx_resource:is_dry_run(
+                bin(["acton:typeA:", ?PROBE_ID_NEW(), ":connector:typeB:dryrun"])
+            )
+        ),
+        ?_assertNot(
+            emqx_resource:is_dry_run(
+                bin(["acton:type1:dryrun:connector:typeb:dryrun"])
+            )
+        )
+    ].
+
+bin(X) -> iolist_to_binary(X).