refactor: alarms api; add: alarms format function
This commit is contained in:
parent
9642bcce88
commit
e96bac87ce
|
@ -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
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -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.
|
|
||||||
|
|
|
@ -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).
|
Loading…
Reference in New Issue