From bd6e9503e6980eec352ccea93cb7698587dd9067 Mon Sep 17 00:00:00 2001 From: JianBo He Date: Tue, 28 Nov 2023 16:15:46 +0800 Subject: [PATCH 1/4] fix(http): compose the url and path in correctly format --- apps/emqx_bridge_http/src/emqx_bridge_http_action_info.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/emqx_bridge_http/src/emqx_bridge_http_action_info.erl b/apps/emqx_bridge_http/src/emqx_bridge_http_action_info.erl index 3b0543ace..6d676beb8 100644 --- a/apps/emqx_bridge_http/src/emqx_bridge_http_action_info.erl +++ b/apps/emqx_bridge_http/src/emqx_bridge_http_action_info.erl @@ -58,7 +58,7 @@ connector_action_config_to_bridge_v1_config(ConnectorConfig, ActionConfig) -> Url1 = case Path of <<>> -> Url; - _ -> emqx_bridge_http_connector:join_paths(Url, Path) + _ -> iolist_to_binary(emqx_bridge_http_connector:join_paths(Url, Path)) end, BridgeV1Config4#{ From d7bf8e97d2fa6e81742faa34da10733d6c71369f Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 29 Nov 2023 11:18:51 +0800 Subject: [PATCH 2/4] chore: add tests case --- .../test/emqx_bridge_http_SUITE.erl | 1 - .../test/emqx_bridge_http_v2_SUITE.erl | 140 ++++++++++++++++++ 2 files changed, 140 insertions(+), 1 deletion(-) create mode 100644 apps/emqx_bridge_http/test/emqx_bridge_http_v2_SUITE.erl diff --git a/apps/emqx_bridge_http/test/emqx_bridge_http_SUITE.erl b/apps/emqx_bridge_http/test/emqx_bridge_http_SUITE.erl index 2ff7d184b..3b7303300 100644 --- a/apps/emqx_bridge_http/test/emqx_bridge_http_SUITE.erl +++ b/apps/emqx_bridge_http/test/emqx_bridge_http_SUITE.erl @@ -130,7 +130,6 @@ end_per_testcase(TestCase, _Config) when -> ok = emqx_bridge_http_connector_test_server:stop(), persistent_term:erase({?MODULE, times_called}), - %emqx_bridge_testlib:delete_all_bridges(), emqx_bridge_v2_testlib:delete_all_bridges(), emqx_bridge_v2_testlib:delete_all_connectors(), emqx_common_test_helpers:call_janitor(), diff --git a/apps/emqx_bridge_http/test/emqx_bridge_http_v2_SUITE.erl b/apps/emqx_bridge_http/test/emqx_bridge_http_v2_SUITE.erl new file mode 100644 index 000000000..38d1d5a68 --- /dev/null +++ b/apps/emqx_bridge_http/test/emqx_bridge_http_v2_SUITE.erl @@ -0,0 +1,140 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2023 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_bridge_http_v2_SUITE). + +-compile(nowarn_export_all). +-compile(export_all). + +-import(emqx_mgmt_api_test_util, [request/3]). +-import(emqx_common_test_helpers, [on_exit/1]). +-import(emqx_bridge_http_SUITE, [start_http_server/1, stop_http_server/1]). + +-include_lib("eunit/include/eunit.hrl"). +-include_lib("common_test/include/ct.hrl"). +-include_lib("snabbkaffe/include/snabbkaffe.hrl"). +-include_lib("emqx/include/asserts.hrl"). + +-define(BRIDGE_TYPE, <<"http">>). +-define(BRIDGE_NAME, atom_to_binary(?MODULE)). +-define(CONNECTOR_NAME, atom_to_binary(?MODULE)). + +all() -> + emqx_common_test_helpers:all(?MODULE). + +groups() -> + []. + +init_per_suite(Config0) -> + Config = + case os:getenv("DEBUG_CASE") of + [_ | _] = DebugCase -> + CaseName = list_to_atom(DebugCase), + [{debug_case, CaseName} | Config0]; + _ -> + Config0 + end, + Apps = emqx_cth_suite:start( + [ + emqx, + emqx_conf, + emqx_connector, + emqx_bridge_http, + emqx_bridge, + emqx_rule_engine + ], + #{work_dir => emqx_cth_suite:work_dir(Config)} + ), + emqx_mgmt_api_test_util:init_suite(), + [{apps, Apps} | Config]. + +end_per_suite(Config) -> + Apps = ?config(apps, Config), + emqx_mgmt_api_test_util:end_suite(), + ok = emqx_cth_suite:stop(Apps), + ok. + +suite() -> + [{timetrap, {seconds, 60}}]. + +init_per_testcase(_TestCase, Config) -> + Server = start_http_server(#{response_delay_ms => 0}), + [{http_server, Server} | Config]. + +end_per_testcase(_TestCase, Config) -> + case ?config(http_server, Config) of + undefined -> ok; + Server -> stop_http_server(Server) + end, + emqx_bridge_v2_testlib:delete_all_bridges(), + emqx_bridge_v2_testlib:delete_all_connectors(), + emqx_common_test_helpers:call_janitor(), + ok. + +%%-------------------------------------------------------------------- +%% tests +%%-------------------------------------------------------------------- + +t_compose_connector_url_and_action_path(Config) -> + Path = <<"/foo/bar">>, + ConnectorCfg = make_connector_config(Config), + ActionCfg = make_action_config([{path, Path} | Config]), + CreateConfig = [ + {bridge_type, ?BRIDGE_TYPE}, + {bridge_name, ?BRIDGE_NAME}, + {bridge_config, ActionCfg}, + {connector_type, ?BRIDGE_TYPE}, + {connector_name, ?CONNECTOR_NAME}, + {connector_config, ConnectorCfg} + ], + {ok, _} = emqx_bridge_v2_testlib:create_bridge(CreateConfig), + + %% assert: the url returned v1 api is composed by the url of the connector and the + %% path of the action + #{port := Port} = ?config(http_server, Config), + ExpectedUrl = iolist_to_binary(io_lib:format("http://localhost:~p/foo/bar", [Port])), + {ok, {_, _, [Bridge]}} = emqx_bridge_testlib:list_bridges_api(), + ?assertMatch( + #{<<"url">> := ExpectedUrl}, + Bridge + ), + ok. + +%%-------------------------------------------------------------------- +%% helpers +%%-------------------------------------------------------------------- + +make_connector_config(Config) -> + #{port := Port} = ?config(http_server, Config), + #{ + <<"enable">> => true, + <<"url">> => iolist_to_binary(io_lib:format("http://localhost:~p", [Port])), + <<"headers">> => #{}, + <<"pool_type">> => <<"hash">>, + <<"pool_size">> => 1 + }. + +make_action_config(Config) -> + Path = ?config(path, Config), + #{ + <<"enable">> => true, + <<"connector">> => ?CONNECTOR_NAME, + <<"parameters">> => #{ + <<"path">> => Path, + <<"method">> => <<"post">>, + <<"headers">> => #{}, + <<"body">> => <<"${.}">> + } + }. From 72bc0460634136ad6a7878a348e73b8a672c66a4 Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 29 Nov 2023 12:00:42 +0800 Subject: [PATCH 3/4] chore: avoid unnecessary default values being filled when querying via the v1 api. see: https://emqx.atlassian.net/browse/EMQX-11482 --- apps/emqx_bridge_http/src/emqx_bridge_http_action_info.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/emqx_bridge_http/src/emqx_bridge_http_action_info.erl b/apps/emqx_bridge_http/src/emqx_bridge_http_action_info.erl index 6d676beb8..457d8ff4b 100644 --- a/apps/emqx_bridge_http/src/emqx_bridge_http_action_info.erl +++ b/apps/emqx_bridge_http/src/emqx_bridge_http_action_info.erl @@ -73,7 +73,7 @@ bridge_v1_config_to_connector_config(BridgeV1Conf) -> bridge_v1_config_to_action_config(BridgeV1Conf, ConnectorName) -> Parameters = maps:with(?PARAMETER_KEYS, BridgeV1Conf), - Parameters1 = Parameters#{<<"path">> => <<>>}, + Parameters1 = Parameters#{<<"path">> => <<>>, <<"headers">> => #{}}, CommonKeys = [<<"enable">>, <<"description">>], ActionConfig = maps:with(?ACTION_KEYS ++ CommonKeys, BridgeV1Conf), ActionConfig#{<<"parameters">> => Parameters1, <<"connector">> => ConnectorName}. From d2e5f302a81c460d709765a8a54381aae26e758f Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 29 Nov 2023 13:47:32 +0800 Subject: [PATCH 4/4] chore(http): add description for bridges v1 --- apps/emqx_bridge_http/src/emqx_bridge_http_schema.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/emqx_bridge_http/src/emqx_bridge_http_schema.erl b/apps/emqx_bridge_http/src/emqx_bridge_http_schema.erl index 958fef4ac..935c8e470 100644 --- a/apps/emqx_bridge_http/src/emqx_bridge_http_schema.erl +++ b/apps/emqx_bridge_http/src/emqx_bridge_http_schema.erl @@ -168,7 +168,8 @@ basic_config() -> desc => ?DESC("config_enable_bridge"), default => true } - )} + )}, + {description, emqx_schema:description_schema()} ] ++ http_resource_opts() ++ connector_opts(). request_config() ->