From 665a9d1dee5bc7e24784edd18de1a4d7d2355411 Mon Sep 17 00:00:00 2001 From: JianBo He Date: Mon, 31 May 2021 14:33:52 +0800 Subject: [PATCH] fix(mgmt): return type conversion error --- .../src/emqx_management.appup.src | 8 ++++ apps/emqx_management/src/emqx_mgmt_api.erl | 48 ++++++++++++------- .../src/emqx_mgmt_api_clients.erl | 21 +++++++- 3 files changed, 59 insertions(+), 18 deletions(-) diff --git a/apps/emqx_management/src/emqx_management.appup.src b/apps/emqx_management/src/emqx_management.appup.src index 2843937f2..57afdf029 100644 --- a/apps/emqx_management/src/emqx_management.appup.src +++ b/apps/emqx_management/src/emqx_management.appup.src @@ -3,24 +3,32 @@ [ {"4.3.2", [ {load_module, emqx_mgmt, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt_api_data, brutal_purge, soft_purge, []} + , {load_module, emqx_mgmt_api, brutal_purge, soft_purge, []} + , {load_module, emqx_mgmt_api_clients, brutal_purge, soft_purge, []} ]}, {<<"4.3.[0-1]">>, [ {load_module, emqx_mgmt_data_backup, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt_cli, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt_api_data, brutal_purge, soft_purge, []} + , {load_module, emqx_mgmt_api, brutal_purge, soft_purge, []} + , {load_module, emqx_mgmt_api_clients, brutal_purge, soft_purge, []} ]}, {<<".*">>, []} ], [ {"4.3.2", [ {load_module, emqx_mgmt, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt_api_data, brutal_purge, soft_purge, []} + , {load_module, emqx_mgmt_api, brutal_purge, soft_purge, []} + , {load_module, emqx_mgmt_api_clients, brutal_purge, soft_purge, []} ]}, {<<"4.3.[0-1]">>, [ {load_module, emqx_mgmt_data_backup, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt_cli, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt, brutal_purge, soft_purge, []} , {load_module, emqx_mgmt_api_data, brutal_purge, soft_purge, []} + , {load_module, emqx_mgmt_api, brutal_purge, soft_purge, []} + , {load_module, emqx_mgmt_api_clients, brutal_purge, soft_purge, []} ]}, {<<".*">>, []} ] diff --git a/apps/emqx_management/src/emqx_mgmt_api.erl b/apps/emqx_management/src/emqx_mgmt_api.erl index 5dedc91be..e068c5384 100644 --- a/apps/emqx_management/src/emqx_mgmt_api.erl +++ b/apps/emqx_management/src/emqx_mgmt_api.erl @@ -239,22 +239,30 @@ pick_params_to_qs([{Key, Value}|Params], QsKits, Acc1, Acc2) -> end end. -qs(<<"_gte_", Key/binary>>, Value, Type) -> - {binary_to_existing_atom(Key, utf8), '>=', to_type(Value, Type)}; -qs(<<"_lte_", Key/binary>>, Value, Type) -> - {binary_to_existing_atom(Key, utf8), '=<', to_type(Value, Type)}; -qs(<<"_like_", Key/binary>>, Value, Type) -> - {binary_to_existing_atom(Key, utf8), like, to_type(Value, Type)}; -qs(<<"_match_", Key/binary>>, Value, Type) -> - {binary_to_existing_atom(Key, utf8), match, to_type(Value, Type)}; -qs(Key, Value, Type) -> - {binary_to_existing_atom(Key, utf8), '=:=', to_type(Value, Type)}. - qs(K1, V1, K2, V2, Type) -> {Key, Op1, NV1} = qs(K1, V1, Type), {Key, Op2, NV2} = qs(K2, V2, Type), {Key, Op1, NV1, Op2, NV2}. +qs(K, Value0, Type) -> + try + qs(K, to_type(Value0, Type)) + catch + throw : bad_value_type -> + throw({bad_value_type, {K, Type, Value0}}) + end. + +qs(<<"_gte_", Key/binary>>, Value) -> + {binary_to_existing_atom(Key, utf8), '>=', Value}; +qs(<<"_lte_", Key/binary>>, Value) -> + {binary_to_existing_atom(Key, utf8), '=<', Value}; +qs(<<"_like_", Key/binary>>, Value) -> + {binary_to_existing_atom(Key, utf8), like, Value}; +qs(<<"_match_", Key/binary>>, Value) -> + {binary_to_existing_atom(Key, utf8), match, Value}; +qs(Key, Value) -> + {binary_to_existing_atom(Key, utf8), '=:=', Value}. + is_fuzzy_key(<<"_like_", _/binary>>) -> true; is_fuzzy_key(<<"_match_", _/binary>>) -> @@ -265,11 +273,19 @@ is_fuzzy_key(_) -> %%-------------------------------------------------------------------- %% Types -to_type(V, atom) -> to_atom(V); -to_type(V, integer) -> to_integer(V); -to_type(V, timestamp) -> to_timestamp(V); -to_type(V, ip) -> aton(V); -to_type(V, _) -> V. +to_type(V, TargetType) -> + try + to_type_(V, TargetType) + catch + _ : _ -> + throw(bad_value_type) + end. + +to_type_(V, atom) -> to_atom(V); +to_type_(V, integer) -> to_integer(V); +to_type_(V, timestamp) -> to_timestamp(V); +to_type_(V, ip) -> aton(V); +to_type_(V, _) -> V. to_atom(A) when is_atom(A) -> A; diff --git a/apps/emqx_management/src/emqx_mgmt_api_clients.erl b/apps/emqx_management/src/emqx_mgmt_api_clients.erl index 90f0d3466..2fe6a5ccb 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_clients.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_clients.erl @@ -140,10 +140,14 @@ -define(format_fun, {?MODULE, format_channel_info}). list(Bindings, Params) when map_size(Bindings) == 0 -> - minirest:return({ok, emqx_mgmt_api:cluster_query(Params, ?CLIENT_QS_SCHEMA, ?query_fun)}); + fence(fun() -> + emqx_mgmt_api:cluster_query(Params, ?CLIENT_QS_SCHEMA, ?query_fun) + end); list(#{node := Node}, Params) when Node =:= node() -> - minirest:return({ok, emqx_mgmt_api:node_query(Node, Params, ?CLIENT_QS_SCHEMA, ?query_fun)}); + fence(fun() -> + emqx_mgmt_api:node_query(Node, Params, ?CLIENT_QS_SCHEMA, ?query_fun) + end); list(Bindings = #{node := Node}, Params) -> case rpc:call(Node, ?MODULE, list, [Bindings, Params]) of @@ -151,6 +155,19 @@ list(Bindings = #{node := Node}, Params) -> Res -> Res end. +%% @private +fence(Func) -> + try + minirest:return({ok, Func()}) + catch + throw : {bad_value_type, {_Key, Type, Value}} -> + Reason = iolist_to_binary( + io_lib:format("Can't convert ~p to ~p type", + [Value, Type]) + ), + minirest:return({error, ?ERROR8, Reason}) + end. + lookup(#{node := Node, clientid := ClientId}, _Params) -> minirest:return({ok, emqx_mgmt:lookup_client(Node, {clientid, emqx_mgmt_util:urldecode(ClientId)}, ?format_fun)});