refactor(exhook_api): unified move position style

This commit is contained in:
JimMoen 2022-03-11 17:49:02 +08:00
parent f6ee45b2e6
commit 7f595f3988
1 changed files with 73 additions and 29 deletions

View File

@ -104,10 +104,13 @@ schema("/exhooks/:name/hooks") ->
schema("/exhooks/:name/move") -> schema("/exhooks/:name/move") ->
#{'operationId' => move, #{'operationId' => move,
post => #{tags => ?TAGS, post => #{tags => ?TAGS,
description => <<"Move the server">>, description => <<"Move the server.\n"
"NOTE: The position should be \"top|bottom|before:{name}\"\n">>,
parameters => params_server_name_in_path(), parameters => params_server_name_in_path(),
'requestBody' => mk(ref(move_req), #{}), 'requestBody' => emqx_dashboard_swagger:schema_with_examples(
responses => #{200 => <<>>, ref(move_req),
position_example()),
responses => #{204 => <<"No Content">>,
400 => error_codes([?BAD_REQUEST], <<"Bad Request">>), 400 => error_codes([?BAD_REQUEST], <<"Bad Request">>),
500 => error_codes([?BAD_RPC], <<"Bad RPC">>) 500 => error_codes([?BAD_RPC], <<"Bad RPC">>)
} }
@ -115,12 +118,8 @@ schema("/exhooks/:name/move") ->
}. }.
fields(move_req) -> fields(move_req) ->
[ {position, mk(enum([top, bottom, before, 'after']), #{})} [{position, mk(string(), #{ desc => <<"The target position to be moved.">>
, {related, mk(string(), #{desc => <<"Relative position of movement">>, , example => <<"top">>})}];
default => <<>>,
example => <<>>
})}
];
fields(detail_server_info) -> fields(detail_server_info) ->
[ {metrics, mk(ref(metrics), #{})} [ {metrics, mk(ref(metrics), #{})}
@ -210,7 +209,8 @@ action_with_name(put, #{bindings := #{name := Name}, body := Body}) ->
}}; }};
{ok, {error, Reason}} -> {ok, {error, Reason}} ->
{400, #{code => <<"BAD_REQUEST">>, {400, #{code => <<"BAD_REQUEST">>,
message => unicode:characters_to_binary(io_lib:format("Error Reason:~p~n", [Reason])) message => unicode:characters_to_binary(
io_lib:format("Error Reason:~p~n", [Reason]))
}}; }};
{ok, _} -> {ok, _} ->
{200}; {200};
@ -231,14 +231,15 @@ action_with_name(delete, #{bindings := #{name := Name}}) ->
}} }}
end. end.
move(post, #{bindings := #{name := Name}, body := Body}) -> move(post, #{bindings := #{name := Name}, body := #{<<"position">> := RawPosition}}) ->
#{<<"position">> := PositionT, <<"related">> := Related} = Body, case parse_position(RawPosition) of
Position = erlang:binary_to_atom(PositionT), {ok, {Position, Related}} ->
case emqx_exhook_mgr:update_config([exhook, servers], case emqx_exhook_mgr:update_config([exhook, servers],
{move, Name, Position, Related}) of {move, Name, Position, Related}) of
{ok, ok} -> {ok, ok} ->
{200}; {204};
{ok, not_found} -> {ok, not_found} ->
%% TODO: unify status code
{400, #{code => <<"BAD_REQUEST">>, {400, #{code => <<"BAD_REQUEST">>,
message => <<"Server not found">> message => <<"Server not found">>
}}; }};
@ -246,6 +247,11 @@ move(post, #{bindings := #{name := Name}, body := Body}) ->
{500, #{code => <<"BAD_RPC">>, {500, #{code => <<"BAD_RPC">>,
message => Error message => Error
}} }}
end;
{error, invalid_position} ->
{400, #{code => <<"BAD_REQUEST">>,
message => <<"Invalid Position">>
}}
end. end.
server_hooks(get, #{bindings := #{name := Name}}) -> server_hooks(get, #{bindings := #{name := Name}}) ->
@ -297,7 +303,8 @@ fill_cluster_server_info([{Node, {error, _}} | T], StatusL, MetricsL, ServerName
fill_cluster_server_info([{Node, Result} | T], StatusL, MetricsL, ServerName, Default) -> fill_cluster_server_info([{Node, Result} | T], StatusL, MetricsL, ServerName, Default) ->
#{status := Status, metrics := Metrics} = Result, #{status := Status, metrics := Metrics} = Result,
fill_cluster_server_info(T, fill_cluster_server_info(
T,
[#{node => Node, status => maps:get(ServerName, Status, error)} | StatusL], [#{node => Node, status => maps:get(ServerName, Status, error)} | StatusL],
[#{node => Node, metrics => maps:get(ServerName, Metrics, Default)} | MetricsL], [#{node => Node, metrics => maps:get(ServerName, Metrics, Default)} | MetricsL],
ServerName, ServerName,
@ -350,7 +357,9 @@ get_nodes_server_hooks_info(Name) ->
case emqx_exhook_mgr:hooks(Name) of case emqx_exhook_mgr:hooks(Name) of
[] -> []; [] -> [];
Hooks -> Hooks ->
AllInfos = call_cluster(fun(Nodes) -> emqx_exhook_proto_v1:server_hooks_metrics(Nodes, Name) end), AllInfos = call_cluster(fun(Nodes) ->
emqx_exhook_proto_v1:server_hooks_metrics(Nodes, Name)
end),
Default = emqx_exhook_metrics:new_metrics_info(), Default = emqx_exhook_metrics:new_metrics_info(),
get_nodes_server_hooks_info(Hooks, AllInfos, Default, []) get_nodes_server_hooks_info(Hooks, AllInfos, Default, [])
end. end.
@ -385,3 +394,38 @@ call_cluster(Fun) ->
Nodes = mria_mnesia:running_nodes(), Nodes = mria_mnesia:running_nodes(),
Ret = Fun(Nodes), Ret = Fun(Nodes),
lists:zip(Nodes, lists:map(fun emqx_rpc:unwrap_erpc/1, Ret)). lists:zip(Nodes, lists:map(fun emqx_rpc:unwrap_erpc/1, Ret)).
%%--------------------------------------------------------------------
%% Internal Funcs
%%--------------------------------------------------------------------
position_example() ->
#{ top =>
#{ summary => <<"absolute position 'top'">>
, value => #{<<"position">> => <<"top">>}}
, bottom =>
#{ summary => <<"absolute position 'bottom'">>
, value => #{<<"position">> => <<"bottom">>}}
, related_before =>
#{ summary => <<"relative position 'before'">>
, value => #{<<"position">> => <<"before:default">>}}
, related_after =>
#{ summary => <<"relative position 'after'">>
, value => #{<<"position">> => <<"after:default">>}}
}.
parse_position(<<"top">>) ->
{ok, {top, <<>>}};
parse_position(<<"bottom">>) ->
{ok, {bottom, <<>>}};
parse_position(<<"before:", Related/binary>>) ->
{ok, {before, Related}};
parse_position(<<"after:", Related/binary>>) ->
{ok, {'after', Related}};
parse_position(<<"before:">>) ->
{error, invalid_position};
parse_position(<<"after:">>) ->
{error, invalid_position};
parse_position(_) ->
{error, invalid_position}.