refactor: alarms api; add: alarms format function

This commit is contained in:
DDDHuang 2021-07-23 09:51:47 +08:00 committed by turtleDeng
parent 9642bcce88
commit e96bac87ce
3 changed files with 197 additions and 104 deletions

View File

@ -36,6 +36,8 @@
, stop/0 , stop/0
]). ]).
-export([format/1]).
%% API %% API
-export([ activate/1 -export([ activate/1
, activate/2 , activate/2
@ -157,6 +159,27 @@ handle_update_config(#{<<"validity_period">> := Period0} = NewConf, OldConf) ->
handle_update_config(NewConf, OldConf) -> handle_update_config(NewConf, OldConf) ->
maps:merge(OldConf, NewConf). maps:merge(OldConf, NewConf).
format(#activated_alarm{name = Name, message = Message, activate_at = At, details = Details}) ->
Now = erlang:system_time(microsecond),
#{
node => node(),
name => Name,
message => Message,
duration => Now - At,
details => Details
};
format(#deactivated_alarm{name = Name, message = Message, activate_at = At, details = Details,
deactivate_at = DAt}) ->
#{
node => node(),
name => Name,
message => Message,
duration => DAt - At,
details => Details
};
format(_) ->
{error, unknow_alarm}.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% gen_server callbacks %% gen_server callbacks
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------

View File

@ -16,122 +16,119 @@
-module(emqx_mgmt_api_alarms). -module(emqx_mgmt_api_alarms).
-include("emqx_mgmt.hrl"). -behavior(minirest_api).
-include_lib("emqx/include/emqx.hrl"). -export([api_spec/0]).
-rest_api(#{name => list_all_alarms, -export([alarms/2]).
method => 'GET',
path => "/alarms",
func => list,
descr => "List all alarms in the cluster"}).
-rest_api(#{name => list_node_alarms, -export([ query_activated/3
method => 'GET', , query_deactivated/3]).
path => "nodes/:atom:node/alarms", %% notice: from emqx_alarms
func => list, -define(ACTIVATED_ALARM, emqx_activated_alarm).
descr => "List all alarms on a node"}). -define(DEACTIVATED_ALARM, emqx_deactivated_alarm).
-rest_api(#{name => list_all_activated_alarms, api_spec() ->
method => 'GET', {[alarms_api()], [alarm_schema()]}.
path => "/alarms/activated",
func => list_activated,
descr => "List all activated alarm in the cluster"}).
-rest_api(#{name => list_node_activated_alarms, alarm_schema() ->
method => 'GET', #{
path => "nodes/:atom:node/alarms/activated", alarm => #{
func => list_activated, type => object,
descr => "List all activated alarm on a node"}). properties => #{
node => #{
type => string,
description => <<"Alarm in node">>},
name => #{
type => string,
description => <<"Alarm name">>},
message => #{
type => string,
description => <<"Alarm readable information">>},
details => #{
type => object,
description => <<"Alarm detail">>},
duration => #{
type => integer,
description => <<"Alarms duration time; UNIX time stamp">>}
}
}
}.
-rest_api(#{name => list_all_deactivated_alarms, alarms_api() ->
method => 'GET', Metadata = #{
path => "/alarms/deactivated", get => #{
func => list_deactivated, description => "EMQ X alarms",
descr => "List all deactivated alarm in the cluster"}). parameters => [#{
name => activated,
in => query,
description => <<"All alarms, if not specified">>,
required => false,
schema => #{type => boolean, default => true}
}],
responses => #{
<<"200">> =>
emqx_mgmt_util:response_array_schema(<<"List all alarms">>, <<"alarm">>)}},
delete => #{
description => "Remove all deactivated alarms",
responses => #{
<<"200">> =>
emqx_mgmt_util:response_schema(<<"Remove all deactivated alarms ok">>)}}},
{"/alarms", Metadata, alarms}.
-rest_api(#{name => list_node_deactivated_alarms, %%%==============================================================================================
method => 'GET', %% parameters trans
path => "nodes/:atom:node/alarms/deactivated", alarms(get, Request) ->
func => list_deactivated, case proplists:get_value(<<"activated">>, cowboy_req:parse_qs(Request), undefined) of
descr => "List all deactivated alarm on a node"}). undefined ->
list(#{activated => undefined});
<<"true">> ->
list(#{activated => true});
<<"false">> ->
list(#{activated => false})
end;
-rest_api(#{name => deactivate_alarm, alarms(delete, _Request) ->
method => 'POST', delete().
path => "/alarms/deactivated",
func => deactivate,
descr => "Delete the special alarm on a node"}).
-rest_api(#{name => delete_all_deactivated_alarms, %%%==============================================================================================
method => 'DELETE', %% api apply
path => "/alarms/deactivated", list(#{activated := true}) ->
func => delete_deactivated, do_list(activated);
descr => "Delete all deactivated alarm in the cluster"}). list(#{activated := false}) ->
do_list(deactivated);
list(#{activated := undefined}) ->
do_list(activated).
-rest_api(#{name => delete_node_deactivated_alarms, delete() ->
method => 'DELETE',
path => "nodes/:atom:node/alarms/deactivated",
func => delete_deactivated,
descr => "Delete all deactivated alarm on a node"}).
-export([ list/2
, deactivate/2
, list_activated/2
, list_deactivated/2
, delete_deactivated/2
]).
list(Bindings, _Params) when map_size(Bindings) == 0 ->
{ok, #{code => ?SUCCESS,
data => [#{node => Node, alarms => Alarms} || {Node, Alarms} <- emqx_mgmt:get_alarms(all)]}};
list(#{node := Node}, _Params) ->
{ok, #{code => ?SUCCESS,
data => emqx_mgmt:get_alarms(Node, all)}}.
list_activated(Bindings, _Params) when map_size(Bindings) == 0 ->
{ok, #{code => ?SUCCESS,
data => [#{node => Node, alarms => Alarms} || {Node, Alarms} <- emqx_mgmt:get_alarms(activated)]}};
list_activated(#{node := Node}, _Params) ->
{ok, #{code => ?SUCCESS,
data => emqx_mgmt:get_alarms(Node, activated)}}.
list_deactivated(Bindings, _Params) when map_size(Bindings) == 0 ->
{ok, #{code => ?SUCCESS,
data => [#{node => Node, alarms => Alarms} || {Node, Alarms} <- emqx_mgmt:get_alarms(deactivated)]}};
list_deactivated(#{node := Node}, _Params) ->
{ok, #{code => ?SUCCESS,
data => emqx_mgmt:get_alarms(Node, deactivated)}}.
deactivate(_Bindings, Params) ->
Node = get_node(Params),
Name = get_name(Params),
do_deactivate(Node, Name).
delete_deactivated(Bindings, _Params) when map_size(Bindings) == 0 ->
_ = emqx_mgmt:delete_all_deactivated_alarms(), _ = emqx_mgmt:delete_all_deactivated_alarms(),
{ok, #{code => ?SUCCESS}}; {200}.
delete_deactivated(#{node := Node}, _Params) -> %%%==============================================================================================
emqx_mgmt:delete_all_deactivated_alarms(Node), %% internal
{ok, #{code => ?SUCCESS}}. do_list(Type) ->
{Table, Function} =
case Type of
activated ->
{?ACTIVATED_ALARM, query_activated};
deactivated ->
{?DEACTIVATED_ALARM, query_deactivated}
end,
Response = emqx_mgmt_api:cluster_query([], {Table, []}, {?MODULE, Function}),
{200, Response}.
get_node(Params) -> query_activated(_, Start, Limit) ->
binary_to_atom(proplists:get_value(<<"node">>, Params, undefined), utf8). query(?ACTIVATED_ALARM, Start, Limit).
get_name(Params) -> query_deactivated(_, Start, Limit) ->
binary_to_atom(proplists:get_value(<<"name">>, Params, undefined), utf8). query(?DEACTIVATED_ALARM, Start, Limit).
do_deactivate(undefined, _) -> query(Table, Start, Limit) ->
emqx_mgmt:return({error, missing_param}); Ms = [{'$1',[],['$1']}],
do_deactivate(_, undefined) -> emqx_mgmt_api:select_table(Table, Ms, Start, Limit, fun format_alarm/1).
emqx_mgmt:return({error, missing_param});
do_deactivate(Node, Name) -> format_alarm(Alarms) when is_list(Alarms) ->
case emqx_mgmt:deactivate(Node, Name) of [emqx_alarm:format(Alarm) || Alarm <- Alarms];
ok ->
emqx_mgmt:return(); format_alarm(Alarm) ->
{error, Reason} -> emqx_alarm:format(Alarm).
emqx_mgmt:return({error, Reason})
end.

View File

@ -0,0 +1,73 @@
%%--------------------------------------------------------------------
%% Copyright (c) 2020-2021 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_mgmt_alarms_api_SUITE).
-compile(export_all).
-compile(nowarn_export_all).
-include_lib("eunit/include/eunit.hrl").
-define(ACT_ALARM, test_act_alarm).
-define(DE_ACT_ALARM, test_de_act_alarm).
all() ->
[t_alarms_api, t_delete_alarms_api].
init_per_suite(Config) ->
ekka_mnesia:start(),
emqx_mgmt_auth:mnesia(boot),
emqx_ct_helpers:start_apps([emqx_management], fun set_special_configs/1),
Config.
end_per_suite(_) ->
emqx_ct_helpers:stop_apps([emqx_management]).
set_special_configs(emqx_management) ->
emqx_config:put([emqx_management], #{listeners => [#{protocol => http, port => 8081}],
applications =>[#{id => "admin", secret => "public"}]}),
ok;
set_special_configs(_App) ->
ok.
t_alarms_api(_) ->
ok = emqx_alarm:activate(?ACT_ALARM),
ok = emqx_alarm:activate(?DE_ACT_ALARM),
ok = emqx_alarm:deactivate(?DE_ACT_ALARM),
get_alarms(1, true),
get_alarms(1, false).
t_delete_alarms_api(_) ->
Path = emqx_mgmt_api_test_util:api_path(["alarms"]),
{ok, _} = emqx_mgmt_api_test_util:request_api(delete, Path),
get_alarms(1, true),
get_alarms(0, false).
get_alarms(AssertCount, Activated) when is_atom(Activated) ->
get_alarms(AssertCount, atom_to_list(Activated));
get_alarms(AssertCount, Activated) ->
Path = emqx_mgmt_api_test_util:api_path(["alarms"]),
Qs = "activated=" ++ Activated,
Headers = emqx_mgmt_api_test_util:auth_header_(),
{ok, Response} = emqx_mgmt_api_test_util:request_api(get, Path, Qs, Headers),
Data = emqx_json:decode(Response, [return_maps]),
Meta = maps:get(<<"meta">>, Data),
Page = maps:get(<<"page">>, Meta),
Limit = maps:get(<<"limit">>, Meta),
Count = maps:get(<<"count">>, Meta),
?assertEqual(Page, 1),
?assertEqual(Limit, emqx_mgmt:max_row_limit()),
?assert(Count >= AssertCount).