Merge pull request #11918 from thalesmg/add-action-types-api-r53-20231109
feat(actions_api): add `/action_types` API
This commit is contained in:
commit
8df6ce812b
|
@ -40,7 +40,8 @@
|
|||
'/actions/:id/enable/:enable'/2,
|
||||
'/actions/:id/:operation'/2,
|
||||
'/nodes/:node/actions/:id/:operation'/2,
|
||||
'/actions_probe'/2
|
||||
'/actions_probe'/2,
|
||||
'/action_types'/2
|
||||
]).
|
||||
|
||||
%% BpAPI
|
||||
|
@ -79,7 +80,8 @@ paths() ->
|
|||
"/actions/:id/enable/:enable",
|
||||
"/actions/:id/:operation",
|
||||
"/nodes/:node/actions/:id/:operation",
|
||||
"/actions_probe"
|
||||
"/actions_probe",
|
||||
"/action_types"
|
||||
].
|
||||
|
||||
error_schema(Code, Message) when is_atom(Code) ->
|
||||
|
@ -338,6 +340,27 @@ schema("/actions_probe") ->
|
|||
400 => error_schema(['TEST_FAILED'], "bridge test failed")
|
||||
}
|
||||
}
|
||||
};
|
||||
schema("/action_types") ->
|
||||
#{
|
||||
'operationId' => '/action_types',
|
||||
get => #{
|
||||
tags => [<<"actions">>],
|
||||
desc => ?DESC("desc_api10"),
|
||||
summary => <<"List available action types">>,
|
||||
responses => #{
|
||||
200 => emqx_dashboard_swagger:schema_with_examples(
|
||||
array(emqx_bridge_v2_schema:types_sc()),
|
||||
#{
|
||||
<<"types">> =>
|
||||
#{
|
||||
summary => <<"Action types">>,
|
||||
value => emqx_bridge_v2_schema:types()
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}.
|
||||
|
||||
'/actions'(post, #{body := #{<<"type">> := BridgeType, <<"name">> := BridgeName} = Conf0}) ->
|
||||
|
@ -486,6 +509,9 @@ schema("/actions_probe") ->
|
|||
redact(BadRequest)
|
||||
end.
|
||||
|
||||
'/action_types'(get, _Request) ->
|
||||
?OK(emqx_bridge_v2_schema:types()).
|
||||
|
||||
maybe_deobfuscate_bridge_probe(#{<<"type">> := BridgeType, <<"name">> := BridgeName} = Params) ->
|
||||
case emqx_bridge:lookup(BridgeType, BridgeName) of
|
||||
{ok, #{raw_config := RawConf}} ->
|
||||
|
|
|
@ -30,9 +30,18 @@
|
|||
post_request/0
|
||||
]).
|
||||
|
||||
-export([types/0, types_sc/0]).
|
||||
|
||||
-export([enterprise_api_schemas/1]).
|
||||
|
||||
-export_type([action_type/0]).
|
||||
|
||||
%% Should we explicitly list them here so dialyzer may be more helpful?
|
||||
-type action_type() :: atom().
|
||||
|
||||
-if(?EMQX_RELEASE_EDITION == ee).
|
||||
-spec enterprise_api_schemas(Method) -> [{_Type :: binary(), ?R_REF(module(), Method)}] when
|
||||
Method :: string().
|
||||
enterprise_api_schemas(Method) ->
|
||||
%% We *must* do this to ensure the module is really loaded, especially when we use
|
||||
%% `call_hocon' from `nodetool' to generate initial configurations.
|
||||
|
@ -55,6 +64,8 @@ enterprise_fields_actions() ->
|
|||
|
||||
-else.
|
||||
|
||||
-spec enterprise_api_schemas(Method) -> [{_Type :: binary(), ?R_REF(module(), Method)}] when
|
||||
Method :: string().
|
||||
enterprise_api_schemas(_Method) -> [].
|
||||
|
||||
enterprise_fields_actions() -> [].
|
||||
|
@ -129,6 +140,14 @@ desc(actions) ->
|
|||
desc(_) ->
|
||||
undefined.
|
||||
|
||||
-spec types() -> [action_type()].
|
||||
types() ->
|
||||
proplists:get_keys(?MODULE:fields(actions)).
|
||||
|
||||
-spec types_sc() -> ?ENUM([action_type()]).
|
||||
types_sc() ->
|
||||
hoconsc:enum(types()).
|
||||
|
||||
-ifdef(TEST).
|
||||
-include_lib("hocon/include/hocon_types.hrl").
|
||||
schema_homogeneous_test() ->
|
||||
|
|
|
@ -236,6 +236,14 @@ end_per_group(_, Config) ->
|
|||
emqx_cth_suite:stop(?config(group_apps, Config)),
|
||||
ok.
|
||||
|
||||
init_per_testcase(t_action_types, Config) ->
|
||||
case ?config(cluster_nodes, Config) of
|
||||
undefined ->
|
||||
init_mocks();
|
||||
Nodes ->
|
||||
[erpc:call(Node, ?MODULE, init_mocks, []) || Node <- Nodes]
|
||||
end,
|
||||
Config;
|
||||
init_per_testcase(_TestCase, Config) ->
|
||||
case ?config(cluster_nodes, Config) of
|
||||
undefined ->
|
||||
|
@ -260,8 +268,14 @@ end_per_testcase(_TestCase, Config) ->
|
|||
|
||||
-define(CONNECTOR_IMPL, emqx_bridge_v2_dummy_connector).
|
||||
init_mocks() ->
|
||||
meck:new(emqx_connector_ee_schema, [passthrough, no_link]),
|
||||
meck:expect(emqx_connector_ee_schema, resource_type, 1, ?CONNECTOR_IMPL),
|
||||
case emqx_release:edition() of
|
||||
ee ->
|
||||
meck:new(emqx_connector_ee_schema, [passthrough, no_link]),
|
||||
meck:expect(emqx_connector_ee_schema, resource_type, 1, ?CONNECTOR_IMPL),
|
||||
ok;
|
||||
ce ->
|
||||
ok
|
||||
end,
|
||||
meck:new(?CONNECTOR_IMPL, [non_strict, no_link]),
|
||||
meck:expect(?CONNECTOR_IMPL, callback_mode, 0, async_if_possible),
|
||||
meck:expect(
|
||||
|
@ -289,7 +303,7 @@ init_mocks() ->
|
|||
ok = meck:expect(?CONNECTOR_IMPL, on_get_channels, fun(ResId) ->
|
||||
emqx_bridge_v2:get_channels_for_connector(ResId)
|
||||
end),
|
||||
[?CONNECTOR_IMPL, emqx_connector_ee_schema].
|
||||
ok.
|
||||
|
||||
clear_resources() ->
|
||||
lists:foreach(
|
||||
|
@ -886,6 +900,14 @@ t_cascade_delete_actions(Config) ->
|
|||
),
|
||||
{ok, 200, []} = request_json(get, uri([?ROOT]), Config).
|
||||
|
||||
t_action_types(Config) ->
|
||||
Res = request_json(get, uri(["action_types"]), Config),
|
||||
?assertMatch({ok, 200, _}, Res),
|
||||
{ok, 200, Types} = Res,
|
||||
?assert(is_list(Types), #{types => Types}),
|
||||
?assert(lists:all(fun is_binary/1, Types), #{types => Types}),
|
||||
ok.
|
||||
|
||||
%%% helpers
|
||||
listen_on_random_port() ->
|
||||
SockOpts = [binary, {active, false}, {packet, raw}, {reuseaddr, true}, {backlog, 1000}],
|
||||
|
|
|
@ -54,6 +54,12 @@ desc_api9.desc:
|
|||
desc_api9.label:
|
||||
"""Test Bridge Creation"""
|
||||
|
||||
desc_api10.desc:
|
||||
"""Lists the available action types."""
|
||||
|
||||
desc_api10.label:
|
||||
"""List action types"""
|
||||
|
||||
desc_bridge_metrics.desc:
|
||||
"""Get bridge metrics by id."""
|
||||
|
||||
|
|
Loading…
Reference in New Issue