Merge pull request #8655 from zhongwencool/fix-auth-user-count-error
fix: support custom count function
This commit is contained in:
commit
b8a2b8f4f4
|
@ -8,7 +8,12 @@ File format:
|
||||||
|
|
||||||
- Use weight-2 heading for releases
|
- Use weight-2 heading for releases
|
||||||
- One list item per change topic
|
- One list item per change topic
|
||||||
Change log ends with a list of github PRs
|
Change log ends with a list of GitHub PRs
|
||||||
|
|
||||||
|
## v4.3.19
|
||||||
|
|
||||||
|
### Bug fixes
|
||||||
|
- Fix GET `/auth_clientid` and `/auth_username` counts. [#8655](https://github.com/emqx/emqx/pull/8655)
|
||||||
|
|
||||||
## v4.3.18
|
## v4.3.18
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_auth_mnesia,
|
{application, emqx_auth_mnesia,
|
||||||
[{description, "EMQ X Authentication with Mnesia"},
|
[{description, "EMQ X Authentication with Mnesia"},
|
||||||
{vsn, "4.3.7"}, % strict semver, bump manually
|
{vsn, "4.3.8"}, % strict semver, bump manually
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, []},
|
{registered, []},
|
||||||
{applications, [kernel,stdlib,mnesia]},
|
{applications, [kernel,stdlib,mnesia]},
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
%% -*- mode: erlang -*-
|
%% -*- mode: erlang -*-
|
||||||
%% Unless you know what you are doing, DO NOT edit manually!!
|
%% Unless you know what you are doing, DO NOT edit manually!!
|
||||||
{VSN,
|
{VSN,
|
||||||
[{<<"4\\.3\\.[5-6]">>,
|
[{<<"4\\.3\\.7">>,
|
||||||
|
[{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]}]},
|
||||||
|
{<<"4\\.3\\.[5-6]">>,
|
||||||
[{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
||||||
|
@ -28,7 +30,8 @@
|
||||||
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
|
{load_module,emqx_acl_mnesia,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]}]},
|
{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]}]},
|
||||||
{<<".*">>,[]}],
|
{<<".*">>,[]}],
|
||||||
[{<<"4\\.3\\.[5-6]">>,
|
[{"4.3.7",[{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]}]},
|
||||||
|
{<<"4\\.3\\.[5-6]">>,
|
||||||
[{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]},
|
[{load_module,emqx_auth_mnesia_app,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mnesia,brutal_purge,soft_purge,[]},
|
||||||
{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
{load_module,emqx_auth_mnesia_api,brutal_purge,soft_purge,[]},
|
||||||
|
|
|
@ -132,7 +132,11 @@
|
||||||
|
|
||||||
list_clientid(_Bindings, Params) ->
|
list_clientid(_Bindings, Params) ->
|
||||||
SortFun = fun(#{created_at := C1}, #{created_at := C2}) -> C1 > C2 end,
|
SortFun = fun(#{created_at := C1}, #{created_at := C2}) -> C1 > C2 end,
|
||||||
return({ok, emqx_mgmt_api:node_query(node(), Params, ?CLIENTID_SCHEMA, ?query_clientid, SortFun)}).
|
CountFun = fun() ->
|
||||||
|
MatchSpec = [{{?TABLE, {clientid, '_'}, '_', '_'}, [], [true]}],
|
||||||
|
ets:select_count(?TABLE, MatchSpec)
|
||||||
|
end,
|
||||||
|
return({ok, emqx_mgmt_api:node_query(node(), Params, ?CLIENTID_SCHEMA, ?query_clientid, SortFun, CountFun)}).
|
||||||
|
|
||||||
lookup_clientid(#{clientid := Clientid}, _Params) ->
|
lookup_clientid(#{clientid := Clientid}, _Params) ->
|
||||||
return({ok, format(emqx_auth_mnesia_cli:lookup_user({clientid, urldecode(Clientid)}))}).
|
return({ok, format(emqx_auth_mnesia_cli:lookup_user({clientid, urldecode(Clientid)}))}).
|
||||||
|
@ -182,7 +186,11 @@ delete_clientid(#{clientid := Clientid}, _) ->
|
||||||
|
|
||||||
list_username(_Bindings, Params) ->
|
list_username(_Bindings, Params) ->
|
||||||
SortFun = fun(#{created_at := C1}, #{created_at := C2}) -> C1 > C2 end,
|
SortFun = fun(#{created_at := C1}, #{created_at := C2}) -> C1 > C2 end,
|
||||||
return({ok, emqx_mgmt_api:node_query(node(), Params, ?USERNAME_SCHEMA, ?query_username, SortFun)}).
|
CountFun = fun() ->
|
||||||
|
MatchSpec = [{{?TABLE, {username, '_'}, '_', '_'}, [], [true]}],
|
||||||
|
ets:select_count(?TABLE, MatchSpec)
|
||||||
|
end,
|
||||||
|
return({ok, emqx_mgmt_api:node_query(node(), Params, ?USERNAME_SCHEMA, ?query_username, SortFun, CountFun)}).
|
||||||
|
|
||||||
lookup_username(#{username := Username}, _Params) ->
|
lookup_username(#{username := Username}, _Params) ->
|
||||||
return({ok, format(emqx_auth_mnesia_cli:lookup_user({username, urldecode(Username)}))}).
|
return({ok, format(emqx_auth_mnesia_cli:lookup_user({username, urldecode(Username)}))}).
|
||||||
|
|
|
@ -272,7 +272,8 @@ t_clientid_rest_api(_Config) ->
|
||||||
clean_all_users(),
|
clean_all_users(),
|
||||||
|
|
||||||
{ok, Result1} = request_http_rest_list(["auth_clientid"]),
|
{ok, Result1} = request_http_rest_list(["auth_clientid"]),
|
||||||
[] = get_http_data(Result1),
|
?assertMatch(#{<<"data">> := [], <<"meta">> := #{<<"count">> := 0}},
|
||||||
|
emqx_json:decode(Result1, [return_maps])),
|
||||||
|
|
||||||
Params1 = #{<<"clientid">> => ?CLIENTID, <<"password">> => ?PASSWORD},
|
Params1 = #{<<"clientid">> => ?CLIENTID, <<"password">> => ?PASSWORD},
|
||||||
{ok, _} = request_http_rest_add(["auth_clientid"], Params1),
|
{ok, _} = request_http_rest_add(["auth_clientid"], Params1),
|
||||||
|
@ -295,8 +296,28 @@ t_clientid_rest_api(_Config) ->
|
||||||
}, get_http_data(Result3)),
|
}, get_http_data(Result3)),
|
||||||
|
|
||||||
{ok, Result4} = request_http_rest_list(["auth_clientid"]),
|
{ok, Result4} = request_http_rest_list(["auth_clientid"]),
|
||||||
|
#{<<"data">> := Data4, <<"meta">> := #{<<"count">> := Count4}}
|
||||||
|
= emqx_json:decode(Result4, [return_maps]),
|
||||||
|
|
||||||
?assertEqual(3, length(get_http_data(Result4))),
|
?assertEqual(3, Count4),
|
||||||
|
?assertEqual([<<"client2">>, <<"clientid1">>, ?CLIENTID],
|
||||||
|
lists:sort(lists:map(fun(#{<<"clientid">> := C}) -> C end, Data4))),
|
||||||
|
|
||||||
|
UserNameParams = [#{<<"username">> => <<"username1">>, <<"password">> => ?PASSWORD}
|
||||||
|
, #{<<"username">> => <<"username2">>, <<"password">> => ?PASSWORD}
|
||||||
|
],
|
||||||
|
{ok, _} = request_http_rest_add(["auth_username"], UserNameParams),
|
||||||
|
|
||||||
|
{ok, Result41} = request_http_rest_list(["auth_clientid"]),
|
||||||
|
%% the count clientid is not affected by username count.
|
||||||
|
?assertEqual(Result4, Result41),
|
||||||
|
|
||||||
|
{ok, Result42} = request_http_rest_list(["auth_username"]),
|
||||||
|
#{<<"data">> := Data42, <<"meta">> := #{<<"count">> := Count42}}
|
||||||
|
= emqx_json:decode(Result42, [return_maps]),
|
||||||
|
?assertEqual(2, Count42),
|
||||||
|
?assertEqual([<<"username1">>, <<"username2">>],
|
||||||
|
lists:sort(lists:map(fun(#{<<"username">> := U}) -> U end, Data42))),
|
||||||
|
|
||||||
{ok, Result5} = request_http_rest_list(["auth_clientid?_like_clientid=id"]),
|
{ok, Result5} = request_http_rest_list(["auth_clientid?_like_clientid=id"]),
|
||||||
?assertEqual(2, length(get_http_data(Result5))),
|
?assertEqual(2, length(get_http_data(Result5))),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{application, emqx_management,
|
{application, emqx_management,
|
||||||
[{description, "EMQ X Management API and CLI"},
|
[{description, "EMQ X Management API and CLI"},
|
||||||
{vsn, "4.3.15"}, % strict semver, bump manually!
|
{vsn, "4.3.16"}, % strict semver, bump manually!
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_management_sup]},
|
{registered, [emqx_management_sup]},
|
||||||
{applications, [kernel,stdlib,minirest]},
|
{applications, [kernel,stdlib,minirest]},
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
-export([ params2qs/2
|
-export([ params2qs/2
|
||||||
, node_query/4
|
, node_query/4
|
||||||
, node_query/5
|
, node_query/5
|
||||||
|
, node_query/6
|
||||||
, cluster_query/3
|
, cluster_query/3
|
||||||
, traverse_table/5
|
, traverse_table/5
|
||||||
, select_table/5
|
, select_table/5
|
||||||
|
@ -59,6 +60,11 @@ query_handle([Table]) when is_atom(Table) ->
|
||||||
query_handle(Tables) ->
|
query_handle(Tables) ->
|
||||||
qlc:append([qlc:q([E || E <- ets:table(T)]) || T <- Tables]).
|
qlc:append([qlc:q([E || E <- ets:table(T)]) || T <- Tables]).
|
||||||
|
|
||||||
|
count_size(Table, undefined) ->
|
||||||
|
count(Table);
|
||||||
|
count_size(_Table, CountFun) ->
|
||||||
|
CountFun().
|
||||||
|
|
||||||
count(Table) when is_atom(Table) ->
|
count(Table) when is_atom(Table) ->
|
||||||
ets:info(Table, size);
|
ets:info(Table, size);
|
||||||
count([Table]) when is_atom(Table) ->
|
count([Table]) when is_atom(Table) ->
|
||||||
|
@ -83,9 +89,12 @@ limit(Params) ->
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
node_query(Node, Params, {Tab, QsSchema}, QueryFun) ->
|
node_query(Node, Params, {Tab, QsSchema}, QueryFun) ->
|
||||||
node_query(Node, Params, {Tab, QsSchema}, QueryFun, undefined).
|
node_query(Node, Params, {Tab, QsSchema}, QueryFun, undefined, undefined).
|
||||||
|
|
||||||
node_query(Node, Params, {Tab, QsSchema}, QueryFun, SortFun) ->
|
node_query(Node, Params, {Tab, QsSchema}, QueryFun, SortFun) ->
|
||||||
|
node_query(Node, Params, {Tab, QsSchema}, QueryFun, SortFun, undefined).
|
||||||
|
|
||||||
|
node_query(Node, Params, {Tab, QsSchema}, QueryFun, SortFun, CountFun) ->
|
||||||
{CodCnt, Qs} = params2qs(Params, QsSchema),
|
{CodCnt, Qs} = params2qs(Params, QsSchema),
|
||||||
Limit = limit(Params),
|
Limit = limit(Params),
|
||||||
Page = page(Params),
|
Page = page(Params),
|
||||||
|
@ -95,7 +104,7 @@ node_query(Node, Params, {Tab, QsSchema}, QueryFun, SortFun) ->
|
||||||
{_, Rows} = do_query(Node, Qs, QueryFun, Start, Limit+1),
|
{_, Rows} = do_query(Node, Qs, QueryFun, Start, Limit+1),
|
||||||
Meta = #{page => Page, limit => Limit},
|
Meta = #{page => Page, limit => Limit},
|
||||||
NMeta = case CodCnt =:= 0 of
|
NMeta = case CodCnt =:= 0 of
|
||||||
true -> Meta#{count => count(Tab), hasnext => length(Rows) > Limit};
|
true -> Meta#{count => count_size(Tab, CountFun), hasnext => length(Rows) > Limit};
|
||||||
_ -> Meta#{count => -1, hasnext => length(Rows) > Limit}
|
_ -> Meta#{count => -1, hasnext => length(Rows) > Limit}
|
||||||
end,
|
end,
|
||||||
Data0 = lists:sublist(Rows, Limit),
|
Data0 = lists:sublist(Rows, Limit),
|
||||||
|
|
Loading…
Reference in New Issue