Merge pull request #9958 from HJianBo/refine-clients-http-return
fix(api): fix bad return error message if client id is not found
This commit is contained in:
commit
0753146f65
|
@ -2,7 +2,7 @@
|
||||||
{application, emqx_management, [
|
{application, emqx_management, [
|
||||||
{description, "EMQX Management API and CLI"},
|
{description, "EMQX Management API and CLI"},
|
||||||
% strict semver, bump manually!
|
% strict semver, bump manually!
|
||||||
{vsn, "5.0.14"},
|
{vsn, "5.0.15"},
|
||||||
{modules, []},
|
{modules, []},
|
||||||
{registered, [emqx_management_sup]},
|
{registered, [emqx_management_sup]},
|
||||||
{applications, [kernel, stdlib, emqx_plugins, minirest, emqx]},
|
{applications, [kernel, stdlib, emqx_plugins, minirest, emqx]},
|
||||||
|
|
|
@ -76,9 +76,10 @@
|
||||||
|
|
||||||
-define(FORMAT_FUN, {?MODULE, format_channel_info}).
|
-define(FORMAT_FUN, {?MODULE, format_channel_info}).
|
||||||
|
|
||||||
-define(CLIENT_ID_NOT_FOUND,
|
-define(CLIENTID_NOT_FOUND, #{
|
||||||
<<"{\"code\": \"RESOURCE_NOT_FOUND\", \"reason\": \"Client id not found\"}">>
|
code => 'CLIENTID_NOT_FOUND',
|
||||||
).
|
message => <<"Client ID not found">>
|
||||||
|
}).
|
||||||
|
|
||||||
api_spec() ->
|
api_spec() ->
|
||||||
emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true, translate_body => true}).
|
emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true, translate_body => true}).
|
||||||
|
@ -219,7 +220,7 @@ schema("/clients/:clientid") ->
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => hoconsc:mk(hoconsc:ref(?MODULE, client), #{}),
|
200 => hoconsc:mk(hoconsc:ref(?MODULE, client), #{}),
|
||||||
404 => emqx_dashboard_swagger:error_codes(
|
404 => emqx_dashboard_swagger:error_codes(
|
||||||
['CLIENTID_NOT_FOUND'], <<"Client id not found">>
|
['CLIENTID_NOT_FOUND'], <<"Client ID not found">>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -232,7 +233,7 @@ schema("/clients/:clientid") ->
|
||||||
responses => #{
|
responses => #{
|
||||||
204 => <<"Kick out client successfully">>,
|
204 => <<"Kick out client successfully">>,
|
||||||
404 => emqx_dashboard_swagger:error_codes(
|
404 => emqx_dashboard_swagger:error_codes(
|
||||||
['CLIENTID_NOT_FOUND'], <<"Client id not found">>
|
['CLIENTID_NOT_FOUND'], <<"Client ID not found">>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,7 +248,7 @@ schema("/clients/:clientid/authorization/cache") ->
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => hoconsc:mk(hoconsc:ref(?MODULE, authz_cache), #{}),
|
200 => hoconsc:mk(hoconsc:ref(?MODULE, authz_cache), #{}),
|
||||||
404 => emqx_dashboard_swagger:error_codes(
|
404 => emqx_dashboard_swagger:error_codes(
|
||||||
['CLIENTID_NOT_FOUND'], <<"Client id not found">>
|
['CLIENTID_NOT_FOUND'], <<"Client ID not found">>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -256,9 +257,9 @@ schema("/clients/:clientid/authorization/cache") ->
|
||||||
tags => ?TAGS,
|
tags => ?TAGS,
|
||||||
parameters => [{clientid, hoconsc:mk(binary(), #{in => path})}],
|
parameters => [{clientid, hoconsc:mk(binary(), #{in => path})}],
|
||||||
responses => #{
|
responses => #{
|
||||||
204 => <<"Kick out client successfully">>,
|
204 => <<"Clean client authz cache successfully">>,
|
||||||
404 => emqx_dashboard_swagger:error_codes(
|
404 => emqx_dashboard_swagger:error_codes(
|
||||||
['CLIENTID_NOT_FOUND'], <<"Client id not found">>
|
['CLIENTID_NOT_FOUND'], <<"Client ID not found">>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,10 +274,11 @@ schema("/clients/:clientid/subscriptions") ->
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => hoconsc:mk(
|
200 => hoconsc:mk(
|
||||||
hoconsc:array(hoconsc:ref(emqx_mgmt_api_subscriptions, subscription)), #{}
|
hoconsc:array(hoconsc:ref(emqx_mgmt_api_subscriptions, subscription)), #{}
|
||||||
),
|
|
||||||
404 => emqx_dashboard_swagger:error_codes(
|
|
||||||
['CLIENTID_NOT_FOUND'], <<"Client id not found">>
|
|
||||||
)
|
)
|
||||||
|
%% returns [] if client not existed in cluster
|
||||||
|
%404 => emqx_dashboard_swagger:error_codes(
|
||||||
|
% ['CLIENTID_NOT_FOUND'], <<"Client ID not found">>
|
||||||
|
%)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -291,7 +293,7 @@ schema("/clients/:clientid/subscribe") ->
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => hoconsc:ref(emqx_mgmt_api_subscriptions, subscription),
|
200 => hoconsc:ref(emqx_mgmt_api_subscriptions, subscription),
|
||||||
404 => emqx_dashboard_swagger:error_codes(
|
404 => emqx_dashboard_swagger:error_codes(
|
||||||
['CLIENTID_NOT_FOUND'], <<"Client id not found">>
|
['CLIENTID_NOT_FOUND'], <<"Client ID not found">>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -307,7 +309,7 @@ schema("/clients/:clientid/subscribe/bulk") ->
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => hoconsc:array(hoconsc:ref(emqx_mgmt_api_subscriptions, subscription)),
|
200 => hoconsc:array(hoconsc:ref(emqx_mgmt_api_subscriptions, subscription)),
|
||||||
404 => emqx_dashboard_swagger:error_codes(
|
404 => emqx_dashboard_swagger:error_codes(
|
||||||
['CLIENTID_NOT_FOUND'], <<"Client id not found">>
|
['CLIENTID_NOT_FOUND'], <<"Client ID not found">>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -323,7 +325,7 @@ schema("/clients/:clientid/unsubscribe") ->
|
||||||
responses => #{
|
responses => #{
|
||||||
204 => <<"Unsubscribe OK">>,
|
204 => <<"Unsubscribe OK">>,
|
||||||
404 => emqx_dashboard_swagger:error_codes(
|
404 => emqx_dashboard_swagger:error_codes(
|
||||||
['CLIENTID_NOT_FOUND'], <<"Client id not found">>
|
['CLIENTID_NOT_FOUND'], <<"Client ID not found">>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,7 +341,7 @@ schema("/clients/:clientid/unsubscribe/bulk") ->
|
||||||
responses => #{
|
responses => #{
|
||||||
204 => <<"Unsubscribe OK">>,
|
204 => <<"Unsubscribe OK">>,
|
||||||
404 => emqx_dashboard_swagger:error_codes(
|
404 => emqx_dashboard_swagger:error_codes(
|
||||||
['CLIENTID_NOT_FOUND'], <<"Client id not found">>
|
['CLIENTID_NOT_FOUND'], <<"Client ID not found">>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,7 +357,7 @@ schema("/clients/:clientid/keepalive") ->
|
||||||
responses => #{
|
responses => #{
|
||||||
200 => hoconsc:mk(hoconsc:ref(?MODULE, client), #{}),
|
200 => hoconsc:mk(hoconsc:ref(?MODULE, client), #{}),
|
||||||
404 => emqx_dashboard_swagger:error_codes(
|
404 => emqx_dashboard_swagger:error_codes(
|
||||||
['CLIENTID_NOT_FOUND'], <<"Client id not found">>
|
['CLIENTID_NOT_FOUND'], <<"Client ID not found">>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -621,7 +623,7 @@ set_keepalive(put, #{bindings := #{clientid := ClientID}, body := Body}) ->
|
||||||
{ok, Interval} ->
|
{ok, Interval} ->
|
||||||
case emqx_mgmt:set_keepalive(emqx_mgmt_util:urldecode(ClientID), Interval) of
|
case emqx_mgmt:set_keepalive(emqx_mgmt_util:urldecode(ClientID), Interval) of
|
||||||
ok -> lookup(#{clientid => ClientID});
|
ok -> lookup(#{clientid => ClientID});
|
||||||
{error, not_found} -> {404, ?CLIENT_ID_NOT_FOUND};
|
{error, not_found} -> {404, ?CLIENTID_NOT_FOUND};
|
||||||
{error, Reason} -> {400, #{code => 'PARAMS_ERROR', message => Reason}}
|
{error, Reason} -> {400, #{code => 'PARAMS_ERROR', message => Reason}}
|
||||||
end
|
end
|
||||||
end.
|
end.
|
||||||
|
@ -669,7 +671,7 @@ list_clients(QString) ->
|
||||||
lookup(#{clientid := ClientID}) ->
|
lookup(#{clientid := ClientID}) ->
|
||||||
case emqx_mgmt:lookup_client({clientid, ClientID}, ?FORMAT_FUN) of
|
case emqx_mgmt:lookup_client({clientid, ClientID}, ?FORMAT_FUN) of
|
||||||
[] ->
|
[] ->
|
||||||
{404, ?CLIENT_ID_NOT_FOUND};
|
{404, ?CLIENTID_NOT_FOUND};
|
||||||
ClientInfo ->
|
ClientInfo ->
|
||||||
{200, hd(ClientInfo)}
|
{200, hd(ClientInfo)}
|
||||||
end.
|
end.
|
||||||
|
@ -677,7 +679,7 @@ lookup(#{clientid := ClientID}) ->
|
||||||
kickout(#{clientid := ClientID}) ->
|
kickout(#{clientid := ClientID}) ->
|
||||||
case emqx_mgmt:kickout_client({ClientID, ?FORMAT_FUN}) of
|
case emqx_mgmt:kickout_client({ClientID, ?FORMAT_FUN}) of
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
{404, ?CLIENT_ID_NOT_FOUND};
|
{404, ?CLIENTID_NOT_FOUND};
|
||||||
_ ->
|
_ ->
|
||||||
{204}
|
{204}
|
||||||
end.
|
end.
|
||||||
|
@ -685,7 +687,7 @@ kickout(#{clientid := ClientID}) ->
|
||||||
get_authz_cache(#{clientid := ClientID}) ->
|
get_authz_cache(#{clientid := ClientID}) ->
|
||||||
case emqx_mgmt:list_authz_cache(ClientID) of
|
case emqx_mgmt:list_authz_cache(ClientID) of
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
{404, ?CLIENT_ID_NOT_FOUND};
|
{404, ?CLIENTID_NOT_FOUND};
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
Message = list_to_binary(io_lib:format("~p", [Reason])),
|
Message = list_to_binary(io_lib:format("~p", [Reason])),
|
||||||
{500, #{code => <<"UNKNOW_ERROR">>, message => Message}};
|
{500, #{code => <<"UNKNOW_ERROR">>, message => Message}};
|
||||||
|
@ -699,7 +701,7 @@ clean_authz_cache(#{clientid := ClientID}) ->
|
||||||
ok ->
|
ok ->
|
||||||
{204};
|
{204};
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
{404, ?CLIENT_ID_NOT_FOUND};
|
{404, ?CLIENTID_NOT_FOUND};
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
Message = list_to_binary(io_lib:format("~p", [Reason])),
|
Message = list_to_binary(io_lib:format("~p", [Reason])),
|
||||||
{500, #{code => <<"UNKNOW_ERROR">>, message => Message}}
|
{500, #{code => <<"UNKNOW_ERROR">>, message => Message}}
|
||||||
|
@ -709,7 +711,7 @@ subscribe(#{clientid := ClientID, topic := Topic} = Sub) ->
|
||||||
Opts = maps:with([qos, nl, rap, rh], Sub),
|
Opts = maps:with([qos, nl, rap, rh], Sub),
|
||||||
case do_subscribe(ClientID, Topic, Opts) of
|
case do_subscribe(ClientID, Topic, Opts) of
|
||||||
{error, channel_not_found} ->
|
{error, channel_not_found} ->
|
||||||
{404, ?CLIENT_ID_NOT_FOUND};
|
{404, ?CLIENTID_NOT_FOUND};
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
Message = list_to_binary(io_lib:format("~p", [Reason])),
|
Message = list_to_binary(io_lib:format("~p", [Reason])),
|
||||||
{500, #{code => <<"UNKNOW_ERROR">>, message => Message}};
|
{500, #{code => <<"UNKNOW_ERROR">>, message => Message}};
|
||||||
|
@ -723,7 +725,7 @@ subscribe_batch(#{clientid := ClientID, topics := Topics}) ->
|
||||||
%% has returned. So if one want to subscribe topics in this hook, it will fail.
|
%% has returned. So if one want to subscribe topics in this hook, it will fail.
|
||||||
case ets:lookup(emqx_channel, ClientID) of
|
case ets:lookup(emqx_channel, ClientID) of
|
||||||
[] ->
|
[] ->
|
||||||
{404, ?CLIENT_ID_NOT_FOUND};
|
{404, ?CLIENTID_NOT_FOUND};
|
||||||
_ ->
|
_ ->
|
||||||
ArgList = [
|
ArgList = [
|
||||||
[ClientID, Topic, maps:with([qos, nl, rap, rh], Sub)]
|
[ClientID, Topic, maps:with([qos, nl, rap, rh], Sub)]
|
||||||
|
@ -735,7 +737,7 @@ subscribe_batch(#{clientid := ClientID, topics := Topics}) ->
|
||||||
unsubscribe(#{clientid := ClientID, topic := Topic}) ->
|
unsubscribe(#{clientid := ClientID, topic := Topic}) ->
|
||||||
case do_unsubscribe(ClientID, Topic) of
|
case do_unsubscribe(ClientID, Topic) of
|
||||||
{error, channel_not_found} ->
|
{error, channel_not_found} ->
|
||||||
{404, ?CLIENT_ID_NOT_FOUND};
|
{404, ?CLIENTID_NOT_FOUND};
|
||||||
{unsubscribe, [{Topic, #{}}]} ->
|
{unsubscribe, [{Topic, #{}}]} ->
|
||||||
{204}
|
{204}
|
||||||
end.
|
end.
|
||||||
|
@ -745,8 +747,8 @@ unsubscribe_batch(#{clientid := ClientID, topics := Topics}) ->
|
||||||
{200, _} ->
|
{200, _} ->
|
||||||
_ = emqx_mgmt:unsubscribe_batch(ClientID, Topics),
|
_ = emqx_mgmt:unsubscribe_batch(ClientID, Topics),
|
||||||
{204};
|
{204};
|
||||||
{404, ?CLIENT_ID_NOT_FOUND} ->
|
{404, NotFound} ->
|
||||||
{404, ?CLIENT_ID_NOT_FOUND}
|
{404, NotFound}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
|
|
|
@ -247,6 +247,49 @@ t_keepalive(_Config) ->
|
||||||
emqtt:disconnect(C1),
|
emqtt:disconnect(C1),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
t_client_id_not_found(_Config) ->
|
||||||
|
AuthHeader = emqx_mgmt_api_test_util:auth_header_(),
|
||||||
|
Http = {"HTTP/1.1", 404, "Not Found"},
|
||||||
|
Body = "{\"code\":\"CLIENTID_NOT_FOUND\",\"message\":\"Client ID not found\"}",
|
||||||
|
|
||||||
|
PathFun = fun(Suffix) ->
|
||||||
|
emqx_mgmt_api_test_util:api_path(["clients", "no_existed_clientid"] ++ Suffix)
|
||||||
|
end,
|
||||||
|
ReqFun = fun(Method, Path) ->
|
||||||
|
emqx_mgmt_api_test_util:request_api(
|
||||||
|
Method, Path, "", AuthHeader, [], #{return_all => true}
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
PostFun = fun(Method, Path, Data) ->
|
||||||
|
emqx_mgmt_api_test_util:request_api(
|
||||||
|
Method, Path, "", AuthHeader, Data, #{return_all => true}
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
|
||||||
|
%% Client lookup
|
||||||
|
?assertMatch({error, {Http, _, Body}}, ReqFun(get, PathFun([]))),
|
||||||
|
%% Client kickout
|
||||||
|
?assertMatch({error, {Http, _, Body}}, ReqFun(delete, PathFun([]))),
|
||||||
|
%% Client Subscription list
|
||||||
|
?assertMatch({ok, {{"HTTP/1.1", 200, "OK"}, _, "[]"}}, ReqFun(get, PathFun(["subscriptions"]))),
|
||||||
|
%% AuthZ Cache lookup
|
||||||
|
?assertMatch({error, {Http, _, Body}}, ReqFun(get, PathFun(["authorization", "cache"]))),
|
||||||
|
%% AuthZ Cache clean
|
||||||
|
?assertMatch({error, {Http, _, Body}}, ReqFun(delete, PathFun(["authorization", "cache"]))),
|
||||||
|
%% Client Subscribe
|
||||||
|
SubBody = #{topic => <<"testtopic">>, qos => 1, nl => 1, rh => 1},
|
||||||
|
?assertMatch({error, {Http, _, Body}}, PostFun(post, PathFun(["subscribe"]), SubBody)),
|
||||||
|
?assertMatch(
|
||||||
|
{error, {Http, _, Body}}, PostFun(post, PathFun(["subscribe", "bulk"]), [SubBody])
|
||||||
|
),
|
||||||
|
%% Client Unsubscribe
|
||||||
|
UnsubBody = #{topic => <<"testtopic">>},
|
||||||
|
?assertMatch({error, {Http, _, Body}}, PostFun(post, PathFun(["unsubscribe"]), UnsubBody)),
|
||||||
|
?assertMatch(
|
||||||
|
{error, {Http, _, Body}}, PostFun(post, PathFun(["unsubscribe", "bulk"]), [UnsubBody])
|
||||||
|
).
|
||||||
|
|
||||||
time_string_to_epoch_millisecond(DateTime) ->
|
time_string_to_epoch_millisecond(DateTime) ->
|
||||||
time_string_to_epoch(DateTime, millisecond).
|
time_string_to_epoch(DateTime, millisecond).
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix bad http response format when client ID is not found in `clients` APIs
|
|
@ -0,0 +1 @@
|
||||||
|
修复 `clients` API 在 Client ID 不存在时返回的错误的 HTTP 应答格式。
|
Loading…
Reference in New Issue