Kaynağa Gözat

fix(bridge_v1_api): fill defaults for v2 raw configs

Fixes https://emqx.atlassian.net/browse/EMQX-11593
Thales Macedo Garitezi 2 yıl önce
ebeveyn
işleme
f94b943ec2

+ 4 - 10
apps/emqx_bridge/src/emqx_bridge_api.erl

@@ -895,25 +895,19 @@ aggregate_metrics(
 
 format_resource(
     #{
-        type := Type,
+        type := ActionType,
         name := BridgeName,
         raw_config := RawConf,
         resource_data := ResourceData
     },
     Node
 ) ->
-    RawConfFull =
-        case emqx_bridge_v2:is_bridge_v2_type(Type) of
-            true ->
-                %% The defaults are already filled in
-                RawConf;
-            false ->
-                fill_defaults(Type, RawConf)
-        end,
+    BridgeV1Type = downgrade_type(ActionType, emqx_bridge_lib:get_conf(ActionType, BridgeName)),
+    RawConfFull = fill_defaults(BridgeV1Type, RawConf),
     redact(
         maps:merge(
             RawConfFull#{
-                type => downgrade_type(Type, emqx_bridge_lib:get_conf(Type, BridgeName)),
+                type => BridgeV1Type,
                 name => maps:get(<<"name">>, RawConf, BridgeName),
                 node => Node
             },

+ 2 - 2
apps/emqx_bridge/src/schema/emqx_bridge_schema.erl

@@ -36,7 +36,7 @@
 ]).
 
 %% for testing only
--export([enterprise_api_schemas/1]).
+-export([enterprise_api_schemas/1, enterprise_fields_bridges/0]).
 
 %%======================================================================================
 %% Hocon Schema Definitions
@@ -191,7 +191,7 @@ fields(bridges) ->
                     end
                 }
             )}
-    ] ++ enterprise_fields_bridges();
+    ] ++ ?MODULE:enterprise_fields_bridges();
 fields("metrics") ->
     [
         {"dropped", mk(integer(), #{desc => ?DESC("metric_dropped")})},

+ 65 - 4
apps/emqx_bridge/test/emqx_bridge_v1_compatibility_layer_SUITE.erl

@@ -106,7 +106,9 @@ setup_mocks() ->
         emqx_bridge_v2_schema,
         registered_api_schemas,
         1,
-        fun(Method) -> [{bridge_type_bin(), hoconsc:ref(?MODULE, "api_" ++ Method)}] end
+        fun(Method) ->
+            [{bridge_type_bin(), hoconsc:ref(?MODULE, "api_v2_" ++ Method)}]
+        end
     ),
 
     catch meck:new(emqx_bridge_schema, MeckOpts),
@@ -114,7 +116,24 @@ setup_mocks() ->
         emqx_bridge_schema,
         enterprise_api_schemas,
         1,
-        fun(Method) -> [{bridge_type_bin(), hoconsc:ref(?MODULE, "api_" ++ Method)}] end
+        fun(Method) ->
+            [{bridge_type_bin(), hoconsc:ref(?MODULE, "api_v1_" ++ Method)}]
+        end
+    ),
+    meck:expect(
+        emqx_bridge_schema,
+        enterprise_fields_bridges,
+        0,
+        fun() ->
+            [
+                {
+                    bridge_type_bin(),
+                    hoconsc:mk(
+                        hoconsc:map(name, hoconsc:ref(?MODULE, v1_bridge)), #{}
+                    )
+                }
+            ]
+        end
     ),
 
     ok.
@@ -156,7 +175,7 @@ fields("connector") ->
         {on_start_fun, hoconsc:mk(binary(), #{})},
         {ssl, hoconsc:ref(ssl)}
     ];
-fields("api_post") ->
+fields("api_v2_post") ->
     [
         {connector, hoconsc:mk(binary(), #{})},
         {name, hoconsc:mk(binary(), #{})},
@@ -164,6 +183,20 @@ fields("api_post") ->
         {send_to, hoconsc:mk(atom(), #{})}
         | fields("connector")
     ];
+fields("api_v1_post") ->
+    ConnectorFields = proplists:delete(resource_opts, fields("connector")),
+    [
+        {connector, hoconsc:mk(binary(), #{})},
+        {name, hoconsc:mk(binary(), #{})},
+        {type, hoconsc:mk(bridge_type(), #{})},
+        {send_to, hoconsc:mk(atom(), #{})},
+        {resource_opts, hoconsc:mk(hoconsc:ref(?MODULE, v1_resource_opts), #{})}
+        | ConnectorFields
+    ];
+fields(v1_bridge) ->
+    lists:foldl(fun proplists:delete/2, fields("api_v1_post"), [name, type]);
+fields(v1_resource_opts) ->
+    emqx_resource_schema:create_opts(_Overrides = []);
 fields(ssl) ->
     emqx_schema:client_ssl_opts_schema(#{required => false}).
 
@@ -333,9 +366,11 @@ get_connector_http(Name) ->
 create_bridge_http_api_v1(Opts) ->
     Name = maps:get(name, Opts),
     Overrides = maps:get(overrides, Opts, #{}),
+    OverrideFn = maps:get(override_fn, Opts, fun(X) -> X end),
     BridgeConfig0 = emqx_utils_maps:deep_merge(bridge_config(), Overrides),
     BridgeConfig = maps:without([<<"connector">>], BridgeConfig0),
-    Params = BridgeConfig#{<<"type">> => bridge_type_bin(), <<"name">> => Name},
+    Params0 = BridgeConfig#{<<"type">> => bridge_type_bin(), <<"name">> => Name},
+    Params = OverrideFn(Params0),
     Path = emqx_mgmt_api_test_util:api_path(["bridges"]),
     ct:pal("creating bridge (http v1): ~p", [Params]),
     Res = request(post, Path, Params),
@@ -919,3 +954,29 @@ t_obfuscated_secrets_probe(_Config) ->
     ),
 
     ok.
+
+t_v1_api_fill_defaults(_Config) ->
+    %% Ensure only one sub-field is used, but we get back the defaults filled in.
+    BridgeName = ?FUNCTION_NAME,
+    OverrideFn = fun(Params) ->
+        ResourceOpts = #{<<"resume_interval">> => 100},
+        maps:put(<<"resource_opts">>, ResourceOpts, Params)
+    end,
+    ?assertMatch(
+        {ok,
+            {{_, 201, _}, _, #{
+                <<"resource_opts">> :=
+                    #{
+                        <<"resume_interval">> := _,
+                        <<"query_mode">> := _,
+                        <<"inflight_window">> := _,
+                        <<"start_timeout">> := _,
+                        <<"start_after_created">> := _,
+                        <<"max_buffer_bytes">> := _,
+                        <<"batch_size">> := _
+                    }
+            }}},
+        create_bridge_http_api_v1(#{name => BridgeName, override_fn => OverrideFn})
+    ),
+
+    ok.