Просмотр исходного кода

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.
Erik Timan 3 лет назад
Родитель
Сommit
33e011aff5

+ 4 - 3
apps/emqx_management/src/emqx_mgmt_api_topics.erl

@@ -75,7 +75,7 @@ schema("/topics/:topic") ->
             tags => ?TAGS,
             parameters => [topic_param(path)],
             responses => #{
-                200 => hoconsc:mk(hoconsc:ref(topic), #{}),
+                200 => hoconsc:mk(hoconsc:array(hoconsc:ref(topic)), #{}),
                 404 =>
                     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
         [] ->
             {404, #{code => ?TOPIC_NOT_FOUND, message => <<"Topic not found">>}};
-        [Route] ->
-            {200, format(Route)}
+        Routes when is_list(Routes) ->
+            Formatted = [format(Route) || Route <- Routes],
+            {200, Formatted}
     end.
 
 %%%==============================================================================================

+ 13 - 3
apps/emqx_management/test/emqx_mgmt_api_topics_SUITE.erl

@@ -72,8 +72,18 @@ t_nodes_api(_) ->
     ),
 
     %% 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]),
     {ok, RouteResponse} = emqx_mgmt_api_test_util:request_api(get, RoutePath),
-    RouteData = emqx_json:decode(RouteResponse, [return_maps]),
-    ?assertEqual(Topic, maps:get(<<"topic">>, RouteData)),
-    ?assertEqual(Node, maps:get(<<"node">>, RouteData)).
+    ok = emqx_router:delete_route(Topic, DummyNode),
+
+    [
+        #{<<"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])).