fix(mgmt): avoid to HTTP dispatch failure due to an URI defination conflict

Since we bave defined
- `listeners/{listener_id}/authentication` in emqx_authn_api.erl
- and `listeners/{id}/{action}` in emqx_mgmt_api_listeners.erl

The HTTP Router always dispatch the `.../authentication` request to `listeners/{id}/{action}`,
which cause a no_union_member checking error.

In this PR, we make a workaround to avoid this dispatch error
This commit is contained in:
JianBo He 2022-06-17 14:52:23 +08:00
parent ca10340eed
commit 03d3fc42c7
1 changed files with 57 additions and 16 deletions

View File

@ -25,6 +25,9 @@
listener_type_status/2, listener_type_status/2,
list_listeners/2, list_listeners/2,
crud_listeners_by_id/2, crud_listeners_by_id/2,
stop_listeners_by_id/2,
start_listeners_by_id/2,
restart_listeners_by_id/2,
action_listeners_by_id/2 action_listeners_by_id/2
]). ]).
@ -53,7 +56,9 @@ paths() ->
"/listeners_status", "/listeners_status",
"/listeners", "/listeners",
"/listeners/:id", "/listeners/:id",
"/listeners/:id/:action" "/listeners/:id/stop",
"/listeners/:id/start",
"/listeners/:id/restart"
]. ].
schema("/listeners_status") -> schema("/listeners_status") ->
@ -136,15 +141,44 @@ schema("/listeners/:id") ->
} }
} }
}; };
schema("/listeners/:id/:action") -> schema("/listeners/:id/start") ->
#{ #{
'operationId' => action_listeners_by_id, 'operationId' => start_listeners_by_id,
post => #{ post => #{
tags => [<<"listeners">>], tags => [<<"listeners">>],
desc => <<"Start/stop/restart listeners on all nodes.">>, desc => <<"Start the listener on all nodes.">>,
parameters => [ parameters => [
?R_REF(listener_id), ?R_REF(listener_id)
?R_REF(action) ],
responses => #{
200 => <<"Updated">>,
400 => error_codes(['BAD_REQUEST', 'BAD_LISTENER_ID'])
}
}
};
schema("/listeners/:id/stop") ->
#{
'operationId' => stop_listeners_by_id,
post => #{
tags => [<<"listeners">>],
desc => <<"Stop the listener on all nodes.">>,
parameters => [
?R_REF(listener_id)
],
responses => #{
200 => <<"Updated">>,
400 => error_codes(['BAD_REQUEST', 'BAD_LISTENER_ID'])
}
}
};
schema("/listeners/:id/restart") ->
#{
'operationId' => restart_listeners_by_id,
post => #{
tags => [<<"listeners">>],
desc => <<"Restart listeners on all nodes.">>,
parameters => [
?R_REF(listener_id)
], ],
responses => #{ responses => #{
200 => <<"Updated">>, 200 => <<"Updated">>,
@ -158,21 +192,12 @@ fields(listener_id) ->
{id, {id,
?HOCON(atom(), #{ ?HOCON(atom(), #{
desc => "Listener id", desc => "Listener id",
example => 'tcp:demo', example => 'tcp:default',
validator => fun validate_id/1, validator => fun validate_id/1,
required => true, required => true,
in => path in => path
})} })}
]; ];
fields(action) ->
[
{action,
?HOCON(?ENUM([start, stop, restart]), #{
desc => "listener action",
example => start,
in => path
})}
];
fields(node) -> fields(node) ->
[ [
{"node", {"node",
@ -371,6 +396,22 @@ parse_listener_conf(Conf0) ->
false -> {error, listener_type_inconsistent} false -> {error, listener_type_inconsistent}
end. end.
stop_listeners_by_id(Method, Body = #{bindings := Bindings}) ->
action_listeners_by_id(
Method,
Body#{bindings := maps:put(action, stop, Bindings)}
).
start_listeners_by_id(Method, Body = #{bindings := Bindings}) ->
action_listeners_by_id(
Method,
Body#{bindings := maps:put(action, start, Bindings)}
).
restart_listeners_by_id(Method, Body = #{bindings := Bindings}) ->
action_listeners_by_id(
Method,
Body#{bindings := maps:put(action, restart, Bindings)}
).
action_listeners_by_id(post, #{bindings := #{id := Id, action := Action}}) -> action_listeners_by_id(post, #{bindings := #{id := Id, action := Action}}) ->
{ok, #{type := Type, name := Name}} = emqx_listeners:parse_listener_id(Id), {ok, #{type := Type, name := Name}} = emqx_listeners:parse_listener_id(Id),
Path = [listeners, Type, Name], Path = [listeners, Type, Name],