Sfoglia il codice sorgente

chore(mgmt): callback query function with table name param

JianBo He 4 anni fa
parent
commit
0a7a14f4cd

+ 16 - 15
apps/emqx_management/src/emqx_mgmt_api.erl

@@ -22,13 +22,13 @@
 
 %% first_next query APIs
 -export([ params2qs/2
-        , node_query/4
-        , cluster_query/3
+        , node_query/5
+        , cluster_query/4
         , traverse_table/5
         , select_table/5
         ]).
 
--export([do_query/5]).
+-export([do_query/6]).
 
 paginate(Tables, Params, RowFun) ->
     Qh = query_handle(Tables),
@@ -78,14 +78,14 @@ limit(Params) ->
 %% Node Query
 %%--------------------------------------------------------------------
 
-node_query(Node, Params, {Tab, QsSchema}, QueryFun) ->
+node_query(Node, Params, Tab, QsSchema, QueryFun) ->
     {CodCnt, Qs} = params2qs(Params, QsSchema),
     Limit = b2i(limit(Params)),
     Page  = b2i(page(Params)),
     Start = if Page > 1 -> (Page-1) * Limit;
                true -> 0
             end,
-    {_, Rows} = do_query(Node, Qs, QueryFun, Start, Limit+1),
+    {_, Rows} = do_query(Node, Tab, Qs, QueryFun, Start, Limit+1),
     Meta = #{page => Page, limit => Limit},
     NMeta = case CodCnt =:= 0 of
                 true -> Meta#{count => count(Tab)};
@@ -94,10 +94,11 @@ node_query(Node, Params, {Tab, QsSchema}, QueryFun) ->
     #{meta => NMeta, data => lists:sublist(Rows, Limit)}.
 
 %% @private
-do_query(Node, Qs, {M,F}, Start, Limit) when Node =:= node() ->
-    M:F(Qs, Start, Limit);
-do_query(Node, Qs, QueryFun, Start, Limit) ->
-    rpc_call(Node, ?MODULE, do_query, [Node, Qs, QueryFun, Start, Limit], 50000).
+do_query(Node, Tab, Qs, {M,F}, Start, Limit) when Node =:= node() ->
+    M:F(Tab, Qs, Start, Limit);
+do_query(Node, Tab, Qs, QueryFun, Start, Limit) ->
+    rpc_call(Node, ?MODULE, do_query,
+             [Node, Tab, Qs, QueryFun, Start, Limit], 50000).
 
 %% @private
 rpc_call(Node, M, F, A, T) ->
@@ -110,7 +111,7 @@ rpc_call(Node, M, F, A, T) ->
 %% Cluster Query
 %%--------------------------------------------------------------------
 
-cluster_query(Params, {Tab, QsSchema}, QueryFun) ->
+cluster_query(Params, Tab, QsSchema, QueryFun) ->
     {CodCnt, Qs} = params2qs(Params, QsSchema),
     Limit = b2i(limit(Params)),
     Page  = b2i(page(Params)),
@@ -118,7 +119,7 @@ cluster_query(Params, {Tab, QsSchema}, QueryFun) ->
                true -> 0
             end,
     Nodes = ekka_mnesia:running_nodes(),
-    Rows = do_cluster_query(Nodes, Qs, QueryFun, Start, Limit+1, []),
+    Rows = do_cluster_query(Nodes, Tab, Qs, QueryFun, Start, Limit+1, []),
     Meta = #{page => Page, limit => Limit},
     NMeta = case CodCnt =:= 0 of
                 true -> Meta#{count => count(Tab, Nodes)};
@@ -127,13 +128,13 @@ cluster_query(Params, {Tab, QsSchema}, QueryFun) ->
     #{meta => NMeta, data => lists:sublist(Rows, Limit)}.
 
 %% @private
-do_cluster_query([], _, _, _, _, Acc) ->
+do_cluster_query([], _, _, _, _, _, Acc) ->
     lists:append(lists:reverse(Acc));
-do_cluster_query([Node|Nodes], Qs, QueryFun, Start, Limit, Acc) ->
-    {NStart, Rows} = do_query(Node, Qs, QueryFun, Start, Limit),
+do_cluster_query([Node|Nodes], Tab, Qs, QueryFun, Start, Limit, Acc) ->
+    {NStart, Rows} = do_query(Node, Tab, Qs, QueryFun, Start, Limit),
     case Limit - length(Rows) of
         Rest when Rest > 0 ->
-            do_cluster_query(Nodes, Qs, QueryFun, NStart, Limit, [Rows|Acc]);
+            do_cluster_query(Nodes, Tab, Qs, QueryFun, NStart, Limit, [Rows|Acc]);
         0 ->
             lists:append(lists:reverse([Rows|Acc]))
     end.

+ 9 - 14
apps/emqx_management/src/emqx_mgmt_api_alarms.erl

@@ -22,8 +22,10 @@
 
 -export([alarms/2]).
 
--export([ query_activated/3
-        , query_deactivated/3]).
+%% internal export (for query)
+-export([ query/4
+        ]).
+
 %% notice: from emqx_alarms
 -define(ACTIVATED_ALARM, emqx_activated_alarm).
 -define(DEACTIVATED_ALARM, emqx_deactivated_alarm).
@@ -71,14 +73,12 @@ alarms_api() ->
 %%%==============================================================================================
 %% parameters trans
 alarms(get, #{query_string := Qs}) ->
-    {Table, Function} =
+    Table =
         case maps:get(<<"activated">>, Qs, <<"true">>) of
-            <<"true">> ->
-                {?ACTIVATED_ALARM, query_activated};
-            <<"false">> ->
-                {?DEACTIVATED_ALARM, query_deactivated}
+            <<"true">> -> ?ACTIVATED_ALARM;
+            <<"false">> -> ?DEACTIVATED_ALARM
         end,
-    Response = emqx_mgmt_api:cluster_query(Qs, {Table, []}, {?MODULE, Function}),
+    Response = emqx_mgmt_api:cluster_query(Qs, Table, [], {?MODULE, query}),
     {200, Response};
 
 alarms(delete, _Params) ->
@@ -87,13 +87,8 @@ alarms(delete, _Params) ->
 
 %%%==============================================================================================
 %% internal
-query_activated(_, Start, Limit) ->
-    query(?ACTIVATED_ALARM, Start, Limit).
-
-query_deactivated(_, Start, Limit) ->
-    query(?DEACTIVATED_ALARM, Start, Limit).
 
-query(Table, Start, Limit) ->
+query(Table, _QsSpec, Start, Limit) ->
     Ms = [{'$1',[],['$1']}],
     emqx_mgmt_api:select_table(Table, Ms, Start, Limit, fun format_alarm/1).
 

+ 79 - 69
apps/emqx_management/src/emqx_mgmt_api_clients.erl

@@ -35,7 +35,7 @@
         , unsubscribe/2
         , subscribe_batch/2]).
 
--export([ query/3
+-export([ query/4
         , format_channel_info/1]).
 
 %% for batch operation
@@ -420,14 +420,17 @@ subscriptions(get, #{bindings := #{clientid := ClientID}}) ->
 %% api apply
 
 list(Params) ->
+    {Tab, QuerySchema} = ?CLIENT_QS_SCHEMA,
     case maps:get(<<"node">>, Params, undefined) of
         undefined ->
-            Response = emqx_mgmt_api:cluster_query(Params, ?CLIENT_QS_SCHEMA, ?query_fun),
+            Response = emqx_mgmt_api:cluster_query(Params, Tab,
+                                                   QuerySchema, ?query_fun),
             {200, Response};
         Node1 ->
             Node = binary_to_atom(Node1, utf8),
             ParamsWithoutNode = maps:without([<<"node">>], Params),
-            Response = emqx_mgmt_api:node_query(Node, ParamsWithoutNode, ?CLIENT_QS_SCHEMA, ?query_fun),
+            Response = emqx_mgmt_api:node_query(Node, ParamsWithoutNode,
+                                                Tab, QuerySchema, ?query_fun),
             {200, Response}
     end.
 
@@ -492,66 +495,8 @@ subscribe_batch(#{clientid := ClientID, topics := Topics}) ->
     ArgList = [[ClientID, Topic, Qos]|| #{topic := Topic, qos := Qos} <- Topics],
     emqx_mgmt_util:batch_operation(?MODULE, do_subscribe, ArgList).
 
-%%%==============================================================================================
+%%--------------------------------------------------------------------
 %% internal function
-format_channel_info({_, ClientInfo, ClientStats}) ->
-    Fun =
-        fun
-            (_Key, Value, Current) when is_map(Value) ->
-                maps:merge(Current, Value);
-            (Key, Value, Current) ->
-                maps:put(Key, Value, Current)
-        end,
-    StatsMap = maps:without([memory, next_pkt_id, total_heap_size],
-        maps:from_list(ClientStats)),
-    ClientInfoMap0 = maps:fold(Fun, #{}, ClientInfo),
-    IpAddress      = peer_to_binary(maps:get(peername, ClientInfoMap0)),
-    Connected      = maps:get(conn_state, ClientInfoMap0) =:= connected,
-    ClientInfoMap1 = maps:merge(StatsMap, ClientInfoMap0),
-    ClientInfoMap2 = maps:put(node, node(), ClientInfoMap1),
-    ClientInfoMap3 = maps:put(ip_address, IpAddress, ClientInfoMap2),
-    ClientInfoMap  = maps:put(connected, Connected, ClientInfoMap3),
-    RemoveList = [
-          auth_result
-        , peername
-        , sockname
-        , peerhost
-        , conn_state
-        , send_pend
-        , conn_props
-        , peercert
-        , sockstate
-        , subscriptions
-        , receive_maximum
-        , protocol
-        , is_superuser
-        , sockport
-        , anonymous
-        , mountpoint
-        , socktype
-        , active_n
-        , await_rel_timeout
-        , conn_mod
-        , sockname
-        , retry_interval
-        , upgrade_qos
-    ],
-    maps:without(RemoveList, ClientInfoMap).
-
-peer_to_binary({Addr, Port}) ->
-    AddrBinary = list_to_binary(inet:ntoa(Addr)),
-    PortBinary = integer_to_binary(Port),
-    <<AddrBinary/binary, ":", PortBinary/binary>>;
-peer_to_binary(Addr) ->
-    list_to_binary(inet:ntoa(Addr)).
-
-format_authz_cache({{PubSub, Topic}, {AuthzResult, Timestamp}}) ->
-    #{
-        access => PubSub,
-        topic => Topic,
-        result => AuthzResult,
-        updated_time => Timestamp
-    }.
 
 do_subscribe(ClientID, Topic0, Qos) ->
     {Topic, Opts} = emqx_topic:parse(Topic0),
@@ -575,20 +520,23 @@ do_unsubscribe(ClientID, Topic) ->
         Res ->
             Res
     end.
-%%%==============================================================================================
+%%--------------------------------------------------------------------
 %% Query Functions
 
-query({Qs, []}, Start, Limit) ->
+query(Tab, {Qs, []}, Start, Limit) ->
     Ms = qs2ms(Qs),
-    emqx_mgmt_api:select_table(emqx_channel_info, Ms, Start, Limit, fun format_channel_info/1);
+    emqx_mgmt_api:select_table(Tab, Ms, Start, Limit,
+                               fun format_channel_info/1);
 
-query({Qs, Fuzzy}, Start, Limit) ->
+query(Tab, {Qs, Fuzzy}, Start, Limit) ->
     Ms = qs2ms(Qs),
     MatchFun = match_fun(Ms, Fuzzy),
-    emqx_mgmt_api:traverse_table(emqx_channel_info, MatchFun, Start, Limit, fun format_channel_info/1).
+    emqx_mgmt_api:traverse_table(Tab, MatchFun, Start, Limit,
+                                 fun format_channel_info/1).
 
-%%%==============================================================================================
+%%--------------------------------------------------------------------
 %% QueryString to Match Spec
+
 -spec qs2ms(list()) -> ets:match_spec().
 qs2ms(Qs) ->
     {MtchHead, Conds} = qs2ms(Qs, 2, {#{}, []}),
@@ -633,8 +581,9 @@ ms(connected_at, X) ->
 ms(created_at, X) ->
     #{session => #{created_at => X}}.
 
-%%%==============================================================================================
+%%--------------------------------------------------------------------
 %% Match funcs
+
 match_fun(Ms, Fuzzy) ->
     MsC = ets:match_spec_compile(Ms),
     REFuzzy = lists:map(fun({K, like, S}) ->
@@ -659,3 +608,64 @@ run_fuzzy_match(E = {_, #{clientinfo := ClientInfo}, _}, [{Key, _, RE}|Fuzzy]) -
               V -> V
           end,
     re:run(Val, RE, [{capture, none}]) == match andalso run_fuzzy_match(E, Fuzzy).
+
+%%--------------------------------------------------------------------
+%% format funcs
+
+format_channel_info({_, ClientInfo, ClientStats}) ->
+    Fun =
+        fun
+            (_Key, Value, Current) when is_map(Value) ->
+                maps:merge(Current, Value);
+            (Key, Value, Current) ->
+                maps:put(Key, Value, Current)
+        end,
+    StatsMap = maps:without([memory, next_pkt_id, total_heap_size],
+        maps:from_list(ClientStats)),
+    ClientInfoMap0 = maps:fold(Fun, #{}, ClientInfo),
+    IpAddress      = peer_to_binary(maps:get(peername, ClientInfoMap0)),
+    Connected      = maps:get(conn_state, ClientInfoMap0) =:= connected,
+    ClientInfoMap1 = maps:merge(StatsMap, ClientInfoMap0),
+    ClientInfoMap2 = maps:put(node, node(), ClientInfoMap1),
+    ClientInfoMap3 = maps:put(ip_address, IpAddress, ClientInfoMap2),
+    ClientInfoMap  = maps:put(connected, Connected, ClientInfoMap3),
+    RemoveList = [
+          auth_result
+        , peername
+        , sockname
+        , peerhost
+        , conn_state
+        , send_pend
+        , conn_props
+        , peercert
+        , sockstate
+        , subscriptions
+        , receive_maximum
+        , protocol
+        , is_superuser
+        , sockport
+        , anonymous
+        , mountpoint
+        , socktype
+        , active_n
+        , await_rel_timeout
+        , conn_mod
+        , sockname
+        , retry_interval
+        , upgrade_qos
+    ],
+    maps:without(RemoveList, ClientInfoMap).
+
+peer_to_binary({Addr, Port}) ->
+    AddrBinary = list_to_binary(inet:ntoa(Addr)),
+    PortBinary = integer_to_binary(Port),
+    <<AddrBinary/binary, ":", PortBinary/binary>>;
+peer_to_binary(Addr) ->
+    list_to_binary(inet:ntoa(Addr)).
+
+format_authz_cache({{PubSub, Topic}, {AuthzResult, Timestamp}}) ->
+    #{ access => PubSub,
+       topic => Topic,
+       result => AuthzResult,
+       updated_time => Timestamp
+     }.

+ 10 - 7
apps/emqx_management/src/emqx_mgmt_api_subscriptions.erl

@@ -29,7 +29,7 @@
 
 -export([subscriptions/2]).
 
--export([ query/3
+-export([ query/4
         , format/1
         ]).
 
@@ -111,11 +111,14 @@ subscriptions(get, #{query_string := Params}) ->
     list(Params).
 
 list(Params) ->
+    {Tab, QuerySchema} = ?SUBS_QS_SCHEMA,
     case maps:get(<<"node">>, Params, undefined) of
         undefined ->
-            {200, emqx_mgmt_api:cluster_query(Params, ?SUBS_QS_SCHEMA, ?query_fun)};
+            {200, emqx_mgmt_api:cluster_query(Params, Tab,
+                                              QuerySchema, ?query_fun)};
         Node ->
-            {200, emqx_mgmt_api:node_query(binary_to_atom(Node, utf8), Params, ?SUBS_QS_SCHEMA, ?query_fun)}
+            {200, emqx_mgmt_api:node_query(binary_to_atom(Node, utf8), Params,
+                                           Tab, QuerySchema, ?query_fun)}
     end.
 
 format(Items) when is_list(Items) ->
@@ -145,14 +148,14 @@ format({_Subscriber, Topic, Options}) ->
 %% Query Function
 %%--------------------------------------------------------------------
 
-query({Qs, []}, Start, Limit) ->
+query(Tab, {Qs, []}, Start, Limit) ->
     Ms = qs2ms(Qs),
-    emqx_mgmt_api:select_table(emqx_suboption, Ms, Start, Limit, fun format/1);
+    emqx_mgmt_api:select_table(Tab, Ms, Start, Limit, fun format/1);
 
-query({Qs, Fuzzy}, Start, Limit) ->
+query(Tab, {Qs, Fuzzy}, Start, Limit) ->
     Ms = qs2ms(Qs),
     MatchFun = match_fun(Ms, Fuzzy),
-    emqx_mgmt_api:traverse_table(emqx_suboption, MatchFun, Start, Limit, fun format/1).
+    emqx_mgmt_api:traverse_table(Tab, MatchFun, Start, Limit, fun format/1).
 
 match_fun(Ms, Fuzzy) ->
     MsC = ets:match_spec_compile(Ms),