diff --git a/apps/emqx_bridge/test/emqx_bridge_api_SUITE.erl b/apps/emqx_bridge/test/emqx_bridge_api_SUITE.erl index 86f088855..3c68baa0b 100644 --- a/apps/emqx_bridge/test/emqx_bridge_api_SUITE.erl +++ b/apps/emqx_bridge/test/emqx_bridge_api_SUITE.erl @@ -79,7 +79,8 @@ groups() -> SingleOnlyTests = [ t_broken_bpapi_vsn, t_old_bpapi_vsn, - t_bridges_probe + t_bridges_probe, + t_auto_restart_interval ], ClusterLaterJoinOnlyTCs = [t_cluster_later_join_metrics], [ @@ -550,6 +551,89 @@ t_http_crud_apis(Config) -> {ok, 204, <<>>} = request(delete, uri(["bridges", BridgeID]), Config). +t_auto_restart_interval(Config) -> + Port = ?config(port, Config), + %% assert we there's no bridges at first + {ok, 200, []} = request_json(get, uri(["bridges"]), Config), + + meck:new(emqx_resource, [passthrough]), + meck:expect(emqx_resource, call_start, fun(_, _, _) -> {error, fake_error} end), + + %% then we add a webhook bridge, using POST + %% POST /bridges/ will create a bridge + URL1 = ?URL(Port, "path1"), + Name = ?BRIDGE_NAME, + BridgeID = emqx_bridge_resource:bridge_id(?BRIDGE_TYPE_HTTP, Name), + BridgeParams = ?HTTP_BRIDGE(URL1, Name)#{ + <<"resource_opts">> => #{<<"auto_restart_interval">> => "1s"} + }, + ?check_trace( + begin + ?assertMatch( + {ok, 201, #{ + <<"type">> := ?BRIDGE_TYPE_HTTP, + <<"name">> := Name, + <<"enable">> := true, + <<"status">> := _, + <<"node_status">> := [_ | _], + <<"url">> := URL1 + }}, + request_json( + post, + uri(["bridges"]), + BridgeParams, + Config + ) + ), + ?block_until(#{?snk_kind := resource_disconnected_enter}), + ?block_until(#{?snk_kind := resource_auto_reconnect}, 1500) + end, + fun(Trace0) -> + Trace = ?of_kind(resource_auto_reconnect, Trace0), + ?assertMatch([#{}], Trace), + ok + end + ), + %% delete the bridge + {ok, 204, <<>>} = request(delete, uri(["bridges", BridgeID]), Config), + {ok, 200, []} = request_json(get, uri(["bridges"]), Config), + + %% auto_retry_interval=infinity + BridgeParams1 = BridgeParams#{ + <<"resource_opts">> => #{<<"auto_restart_interval">> => "infinity"} + }, + ?check_trace( + begin + ?assertMatch( + {ok, 201, #{ + <<"type">> := ?BRIDGE_TYPE_HTTP, + <<"name">> := Name, + <<"enable">> := true, + <<"status">> := _, + <<"node_status">> := [_ | _], + <<"url">> := URL1 + }}, + request_json( + post, + uri(["bridges"]), + BridgeParams1, + Config + ) + ), + ?block_until(#{?snk_kind := resource_disconnected_enter}), + ?block_until(#{?snk_kind := resource_auto_reconnect}, 1500) + end, + fun(Trace0) -> + Trace = ?of_kind(resource_auto_reconnect, Trace0), + ?assertMatch([], Trace), + ok + end + ), + %% delete the bridge + {ok, 204, <<>>} = request(delete, uri(["bridges", BridgeID]), Config), + {ok, 200, []} = request_json(get, uri(["bridges"]), Config), + meck:unload(emqx_resource). + t_http_bridges_local_topic(Config) -> Port = ?config(port, Config), %% assert we there's no bridges at first diff --git a/apps/emqx_resource/src/emqx_resource_manager.erl b/apps/emqx_resource/src/emqx_resource_manager.erl index 6382a53a8..6d70422cf 100644 --- a/apps/emqx_resource/src/emqx_resource_manager.erl +++ b/apps/emqx_resource/src/emqx_resource_manager.erl @@ -389,8 +389,10 @@ handle_event(state_timeout, health_check, connected, Data) -> %% State: DISCONNECTED handle_event(enter, _OldState, disconnected = State, Data) -> ok = log_state_consistency(State, Data), + ?tp(resource_disconnected_enter, #{}), {keep_state_and_data, retry_actions(Data)}; handle_event(state_timeout, auto_retry, disconnected, Data) -> + ?tp(resource_auto_reconnect, #{}), start_resource(Data, undefined); %% State: STOPPED %% The stopped state is entered after the resource has been explicitly stopped diff --git a/changes/ce/fix-10817.en.md b/changes/ce/fix-10817.en.md new file mode 100644 index 000000000..f377269cb --- /dev/null +++ b/changes/ce/fix-10817.en.md @@ -0,0 +1 @@ +Fix the error of not being able to configure `auto_restart_interval` as infinity