fix(emqx_management): handle multiple routes in topics/{topic} API

The topics/{topic} API endpoint would return 500 - Internal Error if a
topic had multiple routes. This is now fixed by returning a list of
routes.
This commit is contained in:
Erik Timan 2023-01-20 13:48:35 +01:00
parent 1a1c3afa81
commit 33e011aff5
2 changed files with 17 additions and 6 deletions

View File

@ -75,7 +75,7 @@ schema("/topics/:topic") ->
tags => ?TAGS, tags => ?TAGS,
parameters => [topic_param(path)], parameters => [topic_param(path)],
responses => #{ responses => #{
200 => hoconsc:mk(hoconsc:ref(topic), #{}), 200 => hoconsc:mk(hoconsc:array(hoconsc:ref(topic)), #{}),
404 => 404 =>
emqx_dashboard_swagger:error_codes(['TOPIC_NOT_FOUND'], <<"Topic not found">>) emqx_dashboard_swagger:error_codes(['TOPIC_NOT_FOUND'], <<"Topic not found">>)
} }
@ -130,8 +130,9 @@ lookup(#{topic := Topic}) ->
case emqx_router:lookup_routes(Topic) of case emqx_router:lookup_routes(Topic) of
[] -> [] ->
{404, #{code => ?TOPIC_NOT_FOUND, message => <<"Topic not found">>}}; {404, #{code => ?TOPIC_NOT_FOUND, message => <<"Topic not found">>}};
[Route] -> Routes when is_list(Routes) ->
{200, format(Route)} Formatted = [format(Route) || Route <- Routes],
{200, Formatted}
end. end.
%%%============================================================================================== %%%==============================================================================================

View File

@ -72,8 +72,18 @@ t_nodes_api(_) ->
), ),
%% get topics/:topic %% get topics/:topic
%% We add another route here to ensure that the response handles
%% multiple routes for a single topic
DummyNode = 'dummy-node-name',
ok = emqx_router:add_route(Topic, DummyNode),
RoutePath = emqx_mgmt_api_test_util:api_path(["topics", Topic]), RoutePath = emqx_mgmt_api_test_util:api_path(["topics", Topic]),
{ok, RouteResponse} = emqx_mgmt_api_test_util:request_api(get, RoutePath), {ok, RouteResponse} = emqx_mgmt_api_test_util:request_api(get, RoutePath),
RouteData = emqx_json:decode(RouteResponse, [return_maps]), ok = emqx_router:delete_route(Topic, DummyNode),
?assertEqual(Topic, maps:get(<<"topic">>, RouteData)),
?assertEqual(Node, maps:get(<<"node">>, RouteData)). [
#{<<"topic">> := Topic, <<"node">> := Node1},
#{<<"topic">> := Topic, <<"node">> := Node2}
] = emqx_json:decode(RouteResponse, [return_maps]),
DummyNodeBin = atom_to_binary(DummyNode),
?assertEqual(lists:usort([Node, DummyNodeBin]), lists:usort([Node1, Node2])).