diff --git a/apps/emqx_gateway/src/coap/emqx_coap_api.erl b/apps/emqx_gateway/src/coap/emqx_coap_api.erl index beb32b2cf..5e94934da 100644 --- a/apps/emqx_gateway/src/coap/emqx_coap_api.erl +++ b/apps/emqx_gateway/src/coap/emqx_coap_api.erl @@ -42,7 +42,7 @@ api_spec() -> emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true, translate_body => true}). paths() -> - [?PREFIX ++ "/request"]. + emqx_gateway_utils:make_deprecated_paths([?PREFIX ++ "/request"]). schema(?PREFIX ++ "/request") -> #{ @@ -60,7 +60,9 @@ schema(?PREFIX ++ "/request") -> ) } } - }. + }; +schema(Path) -> + emqx_gateway_utils:make_compatible_schema(Path, fun schema/1). request(post, #{body := Body, bindings := Bindings}) -> ClientId = maps:get(clientid, Bindings, undefined), diff --git a/apps/emqx_gateway/src/emqx_gateway_api.erl b/apps/emqx_gateway/src/emqx_gateway_api.erl index 6a2f2313c..5ae8fe1e7 100644 --- a/apps/emqx_gateway/src/emqx_gateway_api.erl +++ b/apps/emqx_gateway/src/emqx_gateway_api.erl @@ -61,10 +61,10 @@ api_spec() -> emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true}). paths() -> - [ + emqx_gateway_utils:make_deprecated_paths([ "/gateways", "/gateways/:name" - ]. + ]). %%-------------------------------------------------------------------- %% http handlers @@ -210,7 +210,9 @@ schema("/gateways/:name") -> responses => ?STANDARD_RESP(#{200 => schema_gateways_conf()}) } - }. + }; +schema(Path) -> + emqx_gateway_utils:make_compatible_schema(Path, fun schema/1). %%-------------------------------------------------------------------- %% params defines diff --git a/apps/emqx_gateway/src/emqx_gateway_api_authn.erl b/apps/emqx_gateway/src/emqx_gateway_api_authn.erl index e1cd39c7c..6fd073a3b 100644 --- a/apps/emqx_gateway/src/emqx_gateway_api_authn.erl +++ b/apps/emqx_gateway/src/emqx_gateway_api_authn.erl @@ -60,11 +60,11 @@ api_spec() -> emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true}). paths() -> - [ + emqx_gateway_utils:make_deprecated_paths([ "/gateways/:name/authentication", "/gateways/:name/authentication/users", "/gateways/:name/authentication/users/:uid" - ]. + ]). %%-------------------------------------------------------------------- %% http handlers @@ -298,8 +298,9 @@ schema("/gateways/:name/authentication/users/:uid") -> responses => ?STANDARD_RESP(#{204 => <<"User Deleted">>}) } - }. - + }; +schema(Path) -> + emqx_gateway_utils:make_compatible_schema(Path, fun schema/1). %%-------------------------------------------------------------------- %% params defines diff --git a/apps/emqx_gateway/src/emqx_gateway_api_authn_user_import.erl b/apps/emqx_gateway/src/emqx_gateway_api_authn_user_import.erl index 09482c593..38036f7c7 100644 --- a/apps/emqx_gateway/src/emqx_gateway_api_authn_user_import.erl +++ b/apps/emqx_gateway/src/emqx_gateway_api_authn_user_import.erl @@ -53,10 +53,10 @@ api_spec() -> emqx_dashboard_swagger:spec(?MODULE, #{check_schema => false}). paths() -> - [ + emqx_gateway_utils:make_deprecated_paths([ "/gateways/:name/authentication/import_users", "/gateways/:name/listeners/:id/authentication/import_users" - ]. + ]). %%-------------------------------------------------------------------- %% http handlers @@ -141,8 +141,9 @@ schema("/gateways/:name/listeners/:id/authentication/import_users") -> responses => ?STANDARD_RESP(#{204 => <<"Imported">>}) } - }. - + }; +schema(Path) -> + emqx_gateway_utils:make_compatible_schema(Path, fun schema/1). %%-------------------------------------------------------------------- %% params defines %%-------------------------------------------------------------------- diff --git a/apps/emqx_gateway/src/emqx_gateway_api_clients.erl b/apps/emqx_gateway/src/emqx_gateway_api_clients.erl index cb6618fd1..b7cf9fc64 100644 --- a/apps/emqx_gateway/src/emqx_gateway_api_clients.erl +++ b/apps/emqx_gateway/src/emqx_gateway_api_clients.erl @@ -67,12 +67,12 @@ api_spec() -> emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true, translate_body => true}). paths() -> - [ + emqx_gateway_utils:make_deprecated_paths([ "/gateways/:name/clients", "/gateways/:name/clients/:clientid", "/gateways/:name/clients/:clientid/subscriptions", "/gateways/:name/clients/:clientid/subscriptions/:topic" - ]. + ]). -define(CLIENT_QSCHEMA, [ {<<"node">>, atom}, @@ -537,7 +537,9 @@ schema("/gateways/:name/clients/:clientid/subscriptions/:topic") -> responses => ?STANDARD_RESP(#{204 => <<"Unsubscribed">>}) } - }. + }; +schema(Path) -> + emqx_gateway_utils:make_compatible_schema(Path, fun schema/1). params_client_query() -> params_gateway_name_in_path() ++ diff --git a/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl b/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl index bdf0c4c02..92903ec35 100644 --- a/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl +++ b/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl @@ -68,13 +68,13 @@ api_spec() -> emqx_dashboard_swagger:spec(?MODULE, #{check_schema => true}). paths() -> - [ + emqx_gateway_utils:make_deprecated_paths([ "/gateways/:name/listeners", "/gateways/:name/listeners/:id", "/gateways/:name/listeners/:id/authentication", "/gateways/:name/listeners/:id/authentication/users", "/gateways/:name/listeners/:id/authentication/users/:uid" - ]. + ]). %%-------------------------------------------------------------------- %% http handlers @@ -567,8 +567,9 @@ schema("/gateways/:name/listeners/:id/authentication/users/:uid") -> responses => ?STANDARD_RESP(#{204 => <<"Deleted">>}) } - }. - + }; +schema(Path) -> + emqx_gateway_utils:make_compatible_schema(Path, fun schema/1). %%-------------------------------------------------------------------- %% params defines diff --git a/apps/emqx_gateway/src/emqx_gateway_utils.erl b/apps/emqx_gateway/src/emqx_gateway_utils.erl index 3a6de2031..8df7d84c0 100644 --- a/apps/emqx_gateway/src/emqx_gateway_utils.erl +++ b/apps/emqx_gateway/src/emqx_gateway_utils.erl @@ -44,7 +44,9 @@ parse_listener_id/1, is_running/2, global_chain/1, - listener_chain/3 + listener_chain/3, + make_deprecated_paths/1, + make_compatible_schema/2 ]). -export([stringfy/1]). @@ -538,3 +540,36 @@ default_subopts() -> qos => 0, is_new => true }. + +%% Since 5.0.8, the API path of the gateway has been changed from "gateway" to "gateways" +%% and we need to be compatible with the old path +get_compatible_path("/gateway") -> + "/gateways"; +get_compatible_path("/gateway/" ++ Rest) -> + "/gateways/" ++ Rest. + +get_deprecated_path("/gateways") -> + "/gateway"; +get_deprecated_path("/gateways/" ++ Rest) -> + "/gateway/" ++ Rest. + +make_deprecated_paths(Paths) -> + Paths ++ [get_deprecated_path(Path) || Path <- Paths]. + +make_compatible_schema(Path, SchemaFun) -> + OldPath = get_compatible_path(Path), + make_compatible_schema2(OldPath, SchemaFun). + +make_compatible_schema2(Path, SchemaFun) -> + Schema = SchemaFun(Path), + maps:map( + fun(Key, Value) -> + case lists:member(Key, [get, delete, put, post]) of + true -> + Value#{deprecated => true}; + _ -> + Value + end + end, + Schema + ). diff --git a/apps/emqx_gateway/src/lwm2m/emqx_lwm2m_api.erl b/apps/emqx_gateway/src/lwm2m/emqx_lwm2m_api.erl index 3e0a9f9b7..1aa0bac93 100644 --- a/apps/emqx_gateway/src/lwm2m/emqx_lwm2m_api.erl +++ b/apps/emqx_gateway/src/lwm2m/emqx_lwm2m_api.erl @@ -37,7 +37,9 @@ api_spec() -> emqx_dashboard_swagger:spec(?MODULE). paths() -> - [?PATH("/lookup"), ?PATH("/observe"), ?PATH("/read"), ?PATH("/write")]. + emqx_gateway_utils:make_deprecated_paths([ + ?PATH("/lookup"), ?PATH("/observe"), ?PATH("/read"), ?PATH("/write") + ]). schema(?PATH("/lookup")) -> #{ @@ -118,7 +120,9 @@ schema(?PATH("/write")) -> 404 => error_codes(['CLIENT_NOT_FOUND'], <<"Clientid not found">>) } } - }. + }; +schema(Path) -> + emqx_gateway_utils:make_compatible_schema(Path, fun schema/1). fields(resource) -> [ diff --git a/apps/emqx_gateway/test/emqx_coap_api_SUITE.erl b/apps/emqx_gateway/test/emqx_coap_api_SUITE.erl index 577da1a26..0f0f3787f 100644 --- a/apps/emqx_gateway/test/emqx_coap_api_SUITE.erl +++ b/apps/emqx_gateway/test/emqx_coap_api_SUITE.erl @@ -71,28 +71,33 @@ end_per_suite(Config) -> t_send_request_api(_) -> ClientId = start_client(), timer:sleep(200), - Path = emqx_mgmt_api_test_util:api_path(["gateways/coap/clients/client1/request"]), - Token = <<"atoken">>, - Payload = <<"simple echo this">>, - Req = #{ - token => Token, - payload => Payload, - timeout => <<"10s">>, - content_type => <<"text/plain">>, - method => <<"get">> - }, - Auth = emqx_mgmt_api_test_util:auth_header_(), - {ok, Response} = emqx_mgmt_api_test_util:request_api( - post, - Path, - "method=get", - Auth, - Req - ), - #{<<"token">> := RToken, <<"payload">> := RPayload} = - emqx_json:decode(Response, [return_maps]), - ?assertEqual(Token, RToken), - ?assertEqual(Payload, RPayload), + Test = fun(API) -> + Path = emqx_mgmt_api_test_util:api_path([API]), + Token = <<"atoken">>, + Payload = <<"simple echo this">>, + Req = #{ + token => Token, + payload => Payload, + timeout => <<"10s">>, + content_type => <<"text/plain">>, + method => <<"get">> + }, + Auth = emqx_mgmt_api_test_util:auth_header_(), + {ok, Response} = emqx_mgmt_api_test_util:request_api( + post, + Path, + "method=get", + Auth, + Req + ), + #{<<"token">> := RToken, <<"payload">> := RPayload} = + emqx_json:decode(Response, [return_maps]), + ?assertEqual(Token, RToken), + ?assertEqual(Payload, RPayload) + end, + Test("gateways/coap/clients/client1/request"), + timer:sleep(100), + Test("gateway/coap/clients/client1/request"), erlang:exit(ClientId, kill), ok. diff --git a/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl b/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl index d873ad1a4..8532a3a74 100644 --- a/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl +++ b/apps/emqx_gateway/test/emqx_gateway_api_SUITE.erl @@ -75,6 +75,22 @@ t_gateway(_) -> assert_gw_unloaded(StompGw2), ok. +t_deprecated_gateway(_) -> + {200, Gateways} = request(get, "/gateway"), + lists:foreach(fun assert_gw_unloaded/1, Gateways), + {400, BadReq} = request(get, "/gateway/uname_gateway"), + assert_bad_request(BadReq), + {201, _} = request(post, "/gateway", #{name => <<"stomp">>}), + {200, StompGw1} = request(get, "/gateway/stomp"), + assert_feilds_apperence( + [name, status, enable, created_at, started_at], + StompGw1 + ), + {204, _} = request(delete, "/gateway/stomp"), + {200, StompGw2} = request(get, "/gateway/stomp"), + assert_gw_unloaded(StompGw2), + ok. + t_gateway_stomp(_) -> {200, Gw} = request(get, "/gateways/stomp"), assert_gw_unloaded(Gw), diff --git a/apps/emqx_gateway/test/emqx_lwm2m_api_SUITE.erl b/apps/emqx_gateway/test/emqx_lwm2m_api_SUITE.erl index 8c011c54a..6128b9b62 100644 --- a/apps/emqx_gateway/test/emqx_lwm2m_api_SUITE.erl +++ b/apps/emqx_gateway/test/emqx_lwm2m_api_SUITE.erl @@ -326,7 +326,7 @@ t_observe(Config) -> test_recv_mqtt_response(RespTopic), %% step2, call observe API - call_send_api(Epn, "observe", "path=/3/0/1&enable=false"), + call_deprecated_send_api(Epn, "observe", "path=/3/0/1&enable=false"), timer:sleep(100), #coap_message{type = Type, method = Method, options = Opts} = test_recv_coap_request(UdpSock), ?assertEqual(con, Type), @@ -346,7 +346,13 @@ call_lookup_api(ClientId, Path, Action) -> Response. call_send_api(ClientId, Cmd, Query) -> - ApiPath = emqx_mgmt_api_test_util:api_path(["gateways/lwm2m/clients", ClientId, Cmd]), + call_send_api(ClientId, Cmd, Query, "gateways/lwm2m/clients"). + +call_deprecated_send_api(ClientId, Cmd, Query) -> + call_send_api(ClientId, Cmd, Query, "gateway/lwm2m/clients"). + +call_send_api(ClientId, Cmd, Query, API) -> + ApiPath = emqx_mgmt_api_test_util:api_path([API, ClientId, Cmd]), Auth = emqx_mgmt_api_test_util:auth_header_(), {ok, Response} = emqx_mgmt_api_test_util:request_api(post, ApiPath, Query, Auth), ?LOGT("rest api response:~ts~n", [Response]),