feat(actions_api): add `/action_types` API
This commit is contained in:
parent
a828eea613
commit
eabd09051a
|
@ -40,7 +40,8 @@
|
||||||
'/actions/:id/enable/:enable'/2,
|
'/actions/:id/enable/:enable'/2,
|
||||||
'/actions/:id/:operation'/2,
|
'/actions/:id/:operation'/2,
|
||||||
'/nodes/:node/actions/:id/:operation'/2,
|
'/nodes/:node/actions/:id/:operation'/2,
|
||||||
'/actions_probe'/2
|
'/actions_probe'/2,
|
||||||
|
'/action_types'/2
|
||||||
]).
|
]).
|
||||||
|
|
||||||
%% BpAPI
|
%% BpAPI
|
||||||
|
@ -79,7 +80,8 @@ paths() ->
|
||||||
"/actions/:id/enable/:enable",
|
"/actions/:id/enable/:enable",
|
||||||
"/actions/:id/:operation",
|
"/actions/:id/:operation",
|
||||||
"/nodes/:node/actions/:id/:operation",
|
"/nodes/:node/actions/:id/:operation",
|
||||||
"/actions_probe"
|
"/actions_probe",
|
||||||
|
"/action_types"
|
||||||
].
|
].
|
||||||
|
|
||||||
error_schema(Code, Message) when is_atom(Code) ->
|
error_schema(Code, Message) when is_atom(Code) ->
|
||||||
|
@ -338,6 +340,27 @@ schema("/actions_probe") ->
|
||||||
400 => error_schema(['TEST_FAILED'], "bridge test failed")
|
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}) ->
|
'/actions'(post, #{body := #{<<"type">> := BridgeType, <<"name">> := BridgeName} = Conf0}) ->
|
||||||
|
@ -486,6 +509,9 @@ schema("/actions_probe") ->
|
||||||
redact(BadRequest)
|
redact(BadRequest)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
'/action_types'(get, _Request) ->
|
||||||
|
?OK(emqx_bridge_v2_schema:types()).
|
||||||
|
|
||||||
maybe_deobfuscate_bridge_probe(#{<<"type">> := BridgeType, <<"name">> := BridgeName} = Params) ->
|
maybe_deobfuscate_bridge_probe(#{<<"type">> := BridgeType, <<"name">> := BridgeName} = Params) ->
|
||||||
case emqx_bridge:lookup(BridgeType, BridgeName) of
|
case emqx_bridge:lookup(BridgeType, BridgeName) of
|
||||||
{ok, #{raw_config := RawConf}} ->
|
{ok, #{raw_config := RawConf}} ->
|
||||||
|
|
|
@ -30,9 +30,18 @@
|
||||||
post_request/0
|
post_request/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
-export([types/0, types_sc/0]).
|
||||||
|
|
||||||
-export([enterprise_api_schemas/1]).
|
-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).
|
-if(?EMQX_RELEASE_EDITION == ee).
|
||||||
|
-spec enterprise_api_schemas(Method) -> [{_Type :: binary(), ?R_REF(module(), Method)}] when
|
||||||
|
Method :: string().
|
||||||
enterprise_api_schemas(Method) ->
|
enterprise_api_schemas(Method) ->
|
||||||
%% We *must* do this to ensure the module is really loaded, especially when we use
|
%% We *must* do this to ensure the module is really loaded, especially when we use
|
||||||
%% `call_hocon' from `nodetool' to generate initial configurations.
|
%% `call_hocon' from `nodetool' to generate initial configurations.
|
||||||
|
@ -55,6 +64,8 @@ enterprise_fields_actions() ->
|
||||||
|
|
||||||
-else.
|
-else.
|
||||||
|
|
||||||
|
-spec enterprise_api_schemas(Method) -> [{_Type :: binary(), ?R_REF(module(), Method)}] when
|
||||||
|
Method :: string().
|
||||||
enterprise_api_schemas(_Method) -> [].
|
enterprise_api_schemas(_Method) -> [].
|
||||||
|
|
||||||
enterprise_fields_actions() -> [].
|
enterprise_fields_actions() -> [].
|
||||||
|
@ -129,6 +140,14 @@ desc(actions) ->
|
||||||
desc(_) ->
|
desc(_) ->
|
||||||
undefined.
|
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).
|
-ifdef(TEST).
|
||||||
-include_lib("hocon/include/hocon_types.hrl").
|
-include_lib("hocon/include/hocon_types.hrl").
|
||||||
schema_homogeneous_test() ->
|
schema_homogeneous_test() ->
|
||||||
|
|
|
@ -236,6 +236,14 @@ end_per_group(_, Config) ->
|
||||||
emqx_cth_suite:stop(?config(group_apps, Config)),
|
emqx_cth_suite:stop(?config(group_apps, Config)),
|
||||||
ok.
|
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) ->
|
init_per_testcase(_TestCase, Config) ->
|
||||||
case ?config(cluster_nodes, Config) of
|
case ?config(cluster_nodes, Config) of
|
||||||
undefined ->
|
undefined ->
|
||||||
|
@ -260,8 +268,14 @@ end_per_testcase(_TestCase, Config) ->
|
||||||
|
|
||||||
-define(CONNECTOR_IMPL, emqx_bridge_v2_dummy_connector).
|
-define(CONNECTOR_IMPL, emqx_bridge_v2_dummy_connector).
|
||||||
init_mocks() ->
|
init_mocks() ->
|
||||||
|
case emqx_release:edition() of
|
||||||
|
ee ->
|
||||||
meck:new(emqx_connector_ee_schema, [passthrough, no_link]),
|
meck:new(emqx_connector_ee_schema, [passthrough, no_link]),
|
||||||
meck:expect(emqx_connector_ee_schema, resource_type, 1, ?CONNECTOR_IMPL),
|
meck:expect(emqx_connector_ee_schema, resource_type, 1, ?CONNECTOR_IMPL),
|
||||||
|
ok;
|
||||||
|
ce ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
meck:new(?CONNECTOR_IMPL, [non_strict, no_link]),
|
meck:new(?CONNECTOR_IMPL, [non_strict, no_link]),
|
||||||
meck:expect(?CONNECTOR_IMPL, callback_mode, 0, async_if_possible),
|
meck:expect(?CONNECTOR_IMPL, callback_mode, 0, async_if_possible),
|
||||||
meck:expect(
|
meck:expect(
|
||||||
|
@ -289,7 +303,7 @@ init_mocks() ->
|
||||||
ok = meck:expect(?CONNECTOR_IMPL, on_get_channels, fun(ResId) ->
|
ok = meck:expect(?CONNECTOR_IMPL, on_get_channels, fun(ResId) ->
|
||||||
emqx_bridge_v2:get_channels_for_connector(ResId)
|
emqx_bridge_v2:get_channels_for_connector(ResId)
|
||||||
end),
|
end),
|
||||||
[?CONNECTOR_IMPL, emqx_connector_ee_schema].
|
ok.
|
||||||
|
|
||||||
clear_resources() ->
|
clear_resources() ->
|
||||||
lists:foreach(
|
lists:foreach(
|
||||||
|
@ -886,6 +900,14 @@ t_cascade_delete_actions(Config) ->
|
||||||
),
|
),
|
||||||
{ok, 200, []} = request_json(get, uri([?ROOT]), 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
|
%%% helpers
|
||||||
listen_on_random_port() ->
|
listen_on_random_port() ->
|
||||||
SockOpts = [binary, {active, false}, {packet, raw}, {reuseaddr, true}, {backlog, 1000}],
|
SockOpts = [binary, {active, false}, {packet, raw}, {reuseaddr, true}, {backlog, 1000}],
|
||||||
|
|
|
@ -54,6 +54,12 @@ desc_api9.desc:
|
||||||
desc_api9.label:
|
desc_api9.label:
|
||||||
"""Test Bridge Creation"""
|
"""Test Bridge Creation"""
|
||||||
|
|
||||||
|
desc_api10.desc:
|
||||||
|
"""Lists the available action types."""
|
||||||
|
|
||||||
|
desc_api10.label:
|
||||||
|
"""List action types"""
|
||||||
|
|
||||||
desc_bridge_metrics.desc:
|
desc_bridge_metrics.desc:
|
||||||
"""Get bridge metrics by id."""
|
"""Get bridge metrics by id."""
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue