From 106aa559e051b807f25a59c44a6263855aa136fd Mon Sep 17 00:00:00 2001 From: JimMoen Date: Wed, 10 Nov 2021 14:37:45 +0800 Subject: [PATCH 1/5] fix(api): DELETE success wrongly returned code 200 --- apps/emqx_authn/src/emqx_authn_api.erl | 2 +- apps/emqx_authz/src/emqx_authz_api_mnesia.erl | 6 +++--- apps/emqx_authz/src/emqx_authz_api_sources.erl | 2 +- apps/emqx_bridge/src/emqx_bridge_api.erl | 2 +- apps/emqx_dashboard/src/emqx_dashboard_api.erl | 4 ++-- apps/emqx_management/src/emqx_mgmt_api_alarms.erl | 4 ++-- apps/emqx_management/src/emqx_mgmt_api_banned.erl | 4 ++-- apps/emqx_management/src/emqx_mgmt_api_clients.erl | 6 +++--- apps/emqx_management/src/emqx_mgmt_api_listeners.erl | 8 ++++---- apps/emqx_modules/src/emqx_delayed_api.erl | 4 ++-- apps/emqx_modules/src/emqx_topic_metrics_api.erl | 2 +- apps/emqx_retainer/src/emqx_retainer_api.erl | 4 ++-- apps/emqx_rule_engine/src/emqx_rule_engine_api.erl | 4 ++-- 13 files changed, 26 insertions(+), 26 deletions(-) diff --git a/apps/emqx_authn/src/emqx_authn_api.erl b/apps/emqx_authn/src/emqx_authn_api.erl index 68d9c0d1f..98159f5b7 100644 --- a/apps/emqx_authn/src/emqx_authn_api.erl +++ b/apps/emqx_authn/src/emqx_authn_api.erl @@ -186,7 +186,7 @@ schema("/authentication/:id") -> description => <<"Delete authenticator from global authentication chain">>, parameters => [{id, mk(binary(), #{in => path, desc => <<"Authenticator ID">>})}], responses => #{ - 200 => <<"Authenticator deleted">>, + 204 => <<"Authenticator deleted">>, 404 => error_codes([?NOT_FOUND], <<"Not Found">>) } } diff --git a/apps/emqx_authz/src/emqx_authz_api_mnesia.erl b/apps/emqx_authz/src/emqx_authz_api_mnesia.erl index cafc8a27d..5448cbfd8 100644 --- a/apps/emqx_authz/src/emqx_authz_api_mnesia.erl +++ b/apps/emqx_authz/src/emqx_authz_api_mnesia.erl @@ -148,7 +148,7 @@ schema("/authorization/sources/built-in-database/username/:username") -> description => <<"Delete one record for username">>, parameters => [hoconsc:ref(username)], responses => #{ - 204 => <<"No Content">>, + 204 => <<"Deleted">>, 400 => emqx_dashboard_swagger:error_codes([?BAD_REQUEST], <<"Bad username">>) } } @@ -183,7 +183,7 @@ schema("/authorization/sources/built-in-database/clientid/:clientid") -> description => <<"Delete one record for clientid">>, parameters => [hoconsc:ref(clientid)], responses => #{ - 204 => <<"No Content">>, + 204 => <<"Deleted">>, 400 => emqx_dashboard_swagger:error_codes([?BAD_REQUEST], <<"Bad clientid">>) } } @@ -216,7 +216,7 @@ schema("/authorization/sources/built-in-database/purge-all") -> tags => [<<"authorization">>], description => <<"Purge all records">>, responses => #{ - 204 => <<"No Content">>, + 204 => <<"Deleted">>, 400 => emqx_dashboard_swagger:error_codes([?BAD_REQUEST], <<"Bad Request">>) } } diff --git a/apps/emqx_authz/src/emqx_authz_api_sources.erl b/apps/emqx_authz/src/emqx_authz_api_sources.erl index 25135fa34..04c8079cb 100644 --- a/apps/emqx_authz/src/emqx_authz_api_sources.erl +++ b/apps/emqx_authz/src/emqx_authz_api_sources.erl @@ -250,7 +250,7 @@ source_api() -> } ], responses => #{ - <<"204">> => #{description => <<"No Content">>}, + <<"204">> => #{description => <<"Deleted">>}, <<"400">> => emqx_mgmt_util:bad_request() } } diff --git a/apps/emqx_bridge/src/emqx_bridge_api.erl b/apps/emqx_bridge/src/emqx_bridge_api.erl index 40a101640..ecff87774 100644 --- a/apps/emqx_bridge/src/emqx_bridge_api.erl +++ b/apps/emqx_bridge/src/emqx_bridge_api.erl @@ -104,7 +104,7 @@ crud_bridges_apis() -> description => <<"Delete a bridge">>, parameters => [param_path_id()], responses => #{ - <<"200">> => emqx_mgmt_util:schema(<<"Bridge deleted">>), + <<"204">> => emqx_mgmt_util:schema(<<"Bridge deleted">>), <<"404">> => emqx_mgmt_util:error_schema(<<"Bridge not found">>, ['NOT_FOUND']) } } diff --git a/apps/emqx_dashboard/src/emqx_dashboard_api.erl b/apps/emqx_dashboard/src/emqx_dashboard_api.erl index 2396af9eb..1cf59d509 100644 --- a/apps/emqx_dashboard/src/emqx_dashboard_api.erl +++ b/apps/emqx_dashboard/src/emqx_dashboard_api.erl @@ -131,7 +131,7 @@ schema("/users/:username") -> parameters => [{username, mk(binary(), #{in => path, example => <<"admin">>})}], responses => #{ - 200 => <<"Delete User successfully">>, + 204 => <<"Delete User successfully">>, 400 => [ {code, mk(string(), #{example => 'CANNOT_DELETE_ADMIN'})}, {message, mk(string(), #{example => "CANNOT DELETE ADMIN"})}]}} @@ -220,7 +220,7 @@ user(delete, #{bindings := #{username := Username}}) -> message => <<"Cannot delete admin">>}}; false -> _ = emqx_dashboard_admin:remove_user(Username), - {200} + {204} end. change_pwd(put, #{bindings := #{username := Username}, body := Params}) -> diff --git a/apps/emqx_management/src/emqx_mgmt_api_alarms.erl b/apps/emqx_management/src/emqx_mgmt_api_alarms.erl index 38d923742..95a100972 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_alarms.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_alarms.erl @@ -56,7 +56,7 @@ schema("/alarms") -> delete => #{ description => <<"Remove all deactivated alarms">>, responses => #{ - 200 => <<"Remove all deactivated alarms ok">> + 204 => <<"Remove all deactivated alarms ok">> } } }. @@ -94,7 +94,7 @@ alarms(get, #{query_string := Qs}) -> alarms(delete, _Params) -> _ = emqx_mgmt:delete_all_deactivated_alarms(), - {200}. + {204}. %%%============================================================================================== %% internal diff --git a/apps/emqx_management/src/emqx_mgmt_api_banned.erl b/apps/emqx_management/src/emqx_mgmt_api_banned.erl index 3452395a4..9c9fbbb31 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_banned.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_banned.erl @@ -82,7 +82,7 @@ schema("/banned/:as/:who") -> example => <<"Badass">>})} ], responses => #{ - 200 => <<"Delete banned success">>, + 204 => <<"Delete banned success">>, 404 => emqx_dashboard_swagger:error_codes(['RESOURCE_NOT_FOUND'], <<"Banned not found">>) } @@ -146,7 +146,7 @@ delete_banned(delete, #{bindings := Params}) -> {404, #{code => 'RESOURCE_NOT_FOUND', message => Message}}; _ -> ok = emqx_banned:delete(Params), - {200} + {204} end. format(Banned) -> diff --git a/apps/emqx_management/src/emqx_mgmt_api_clients.erl b/apps/emqx_management/src/emqx_mgmt_api_clients.erl index 2314c0b47..db7704a4c 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_clients.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_clients.erl @@ -342,7 +342,7 @@ client_api() -> }], responses => #{ <<"404">> => emqx_mgmt_util:error_schema(<<"Client id not found">>), - <<"200">> => emqx_mgmt_util:schema(client, <<"List clients 200 OK">>)}}}, + <<"204">> => emqx_mgmt_util:schema(<<"Kick out client successfully">>)}}}, {"/clients/:clientid", Metadata, client}. clients_authz_cache_api() -> @@ -368,7 +368,7 @@ clients_authz_cache_api() -> }], responses => #{ <<"404">> => emqx_mgmt_util:error_schema(<<"Client id not found">>), - <<"200">> => emqx_mgmt_util:schema(<<"Delete clients 200 OK">>)}}}, + <<"204">> => emqx_mgmt_util:schema(<<"Clean client authz cache successfully">>)}}}, {"/clients/:clientid/authz_cache", Metadata, authz_cache}. clients_subscriptions_api() -> @@ -506,7 +506,7 @@ lookup(#{clientid := ClientID}) -> kickout(#{clientid := ClientID}) -> emqx_mgmt:kickout_client(ClientID), - {200}. + {204}. get_authz_cache(#{clientid := ClientID})-> case emqx_mgmt:list_authz_cache(ClientID) of diff --git a/apps/emqx_management/src/emqx_mgmt_api_listeners.erl b/apps/emqx_management/src/emqx_mgmt_api_listeners.erl index 4568bcd9a..eebdc4aae 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_listeners.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_listeners.erl @@ -110,7 +110,7 @@ api_list_update_listeners_by_id() -> responses => #{ <<"404">> => emqx_mgmt_util:error_schema(?LISTENER_NOT_FOUND, ['BAD_LISTENER_ID']), - <<"200">> => + <<"204">> => emqx_mgmt_util:schema(<<"Delete listener successfully">>)}} }, {"/listeners/:id", Metadata, crud_listeners_by_id}. @@ -160,7 +160,7 @@ api_get_update_listener_by_id_on_node() -> responses => #{ <<"404">> => emqx_mgmt_util:error_schema(?LISTENER_NOT_FOUND, ['BAD_LISTENER_ID']), - <<"200">> => + <<"204">> => emqx_mgmt_util:schema(<<"Delete listener successfully">>)}} }, {"/nodes/:node/listeners/:id", Metadata, crud_listener_by_id_on_node}. @@ -251,7 +251,7 @@ crud_listeners_by_id(put, #{bindings := #{id := Id}, body := Conf}) -> crud_listeners_by_id(delete, #{bindings := #{id := Id}}) -> Results = emqx_mgmt:remove_listener(Id), case lists:filter(fun filter_errors/1, Results) of - [] -> {200}; + [] -> {204}; Errors -> {500, #{code => 'UNKNOW_ERROR', message => err_msg(Errors)}} end. @@ -291,7 +291,7 @@ crud_listener_by_id_on_node(put, #{bindings := #{id := Id, node := Node}, body : end; crud_listener_by_id_on_node(delete, #{bindings := #{id := Id, node := Node}}) -> case emqx_mgmt:remove_listener(atom(Node), Id) of - ok -> {200}; + ok -> {204}; {error, Reason} -> {500, #{code => 'UNKNOW_ERROR', message => err_msg(Reason)}} end. diff --git a/apps/emqx_modules/src/emqx_delayed_api.erl b/apps/emqx_modules/src/emqx_delayed_api.erl index 95b586fef..f0b72f502 100644 --- a/apps/emqx_modules/src/emqx_delayed_api.erl +++ b/apps/emqx_modules/src/emqx_delayed_api.erl @@ -90,7 +90,7 @@ schema("/mqtt/delayed/messages/:msgid") -> description => <<"Delete delayed message">>, parameters => [{msgid, mk(binary(), #{in => path, desc => <<"delay message ID">>})}], responses => #{ - 200 => <<"Delete delayed message success">>, + 204 => <<"Delete delayed message success">>, 400 => emqx_dashboard_swagger:error_codes([?MESSAGE_ID_SCHEMA_ERROR], <<"Bad MsgId format">>), 404 => emqx_dashboard_swagger:error_codes([?MESSAGE_ID_NOT_FOUND], <<"MsgId not found">>) } @@ -166,7 +166,7 @@ delayed_message(delete, #{bindings := #{msgid := Id}}) -> case emqx_delayed:get_delayed_message(Id) of {ok, _Message} -> _ = emqx_delayed:delete_delayed_message(Id), - {200}; + {204}; {error, id_schema_error} -> {400, generate_http_code_map(id_schema_error, Id)}; {error, not_found} -> diff --git a/apps/emqx_modules/src/emqx_topic_metrics_api.erl b/apps/emqx_modules/src/emqx_topic_metrics_api.erl index 00740584e..e62d5537f 100644 --- a/apps/emqx_modules/src/emqx_topic_metrics_api.erl +++ b/apps/emqx_modules/src/emqx_topic_metrics_api.erl @@ -115,7 +115,7 @@ operation_topic_metrics_api() -> description => <<"Deregister topic metrics">>, parameters => [topic_param()], responses => #{ - <<"200">> => schema(<<"Deregister topic metrics">>), + <<"204">> => schema(<<"Deregister topic metrics">>), <<"404">> => error_schema(<<"Topic not found">>, [?ERROR_TOPIC]) } } diff --git a/apps/emqx_retainer/src/emqx_retainer_api.erl b/apps/emqx_retainer/src/emqx_retainer_api.erl index 7315d5a63..afcd2e3f6 100644 --- a/apps/emqx_retainer/src/emqx_retainer_api.erl +++ b/apps/emqx_retainer/src/emqx_retainer_api.erl @@ -88,7 +88,7 @@ with_topic_api() -> description => <<"delete matching messages">>, parameters => parameters(), responses => #{ - <<"200">> => schema(<<"Successed">>), + <<"204">> => schema(<<"Successed">>), <<"405">> => schema(<<"NotAllowed">>) } } @@ -147,7 +147,7 @@ with_topic(get, #{bindings := Bindings} = Params) -> with_topic(delete, #{bindings := Bindings}) -> Topic = maps:get(topic, Bindings), emqx_retainer_mnesia:delete_message(undefined, Topic), - {200}. + {204}. -spec lookup(undefined | binary(), map(), diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl b/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl index b9a3b16f7..a70c7894c 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl @@ -104,7 +104,7 @@ api_rules_crud() -> description => <<"Delete a rule by given Id from all nodes in the cluster">>, parameters => [param_path_id()], responses => #{ - <<"200">> => + <<"204">> => emqx_mgmt_util:schema(<<"Delete rule successfully">>)}} }, {"/rules/:id", Metadata, crud_rules_by_id}. @@ -291,7 +291,7 @@ crud_rules_by_id(put, #{bindings := #{id := Id}, body := Params}) -> crud_rules_by_id(delete, #{bindings := #{id := Id}}) -> ConfPath = emqx_rule_engine:config_key_path() ++ [Id], case emqx:remove_config(ConfPath, #{}) of - {ok, _} -> {200}; + {ok, _} -> {204}; {error, Reason} -> ?SLOG(error, #{msg => "delete_rule_failed", id => Id, reason => Reason}), From c5f9f397f07a00841ba5b7a9012a343ed808ab71 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Thu, 11 Nov 2021 18:49:02 +0800 Subject: [PATCH 2/5] chore(ignore): add direnv dotfile --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b7a358b31..6da25e641 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,5 @@ erlang_ls.config # Emacs temporary files .#* *# +# For direnv +.envrc From b3f9220d0227dc6344c2d295df328916c8d56531 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Fri, 12 Nov 2021 10:18:54 +0800 Subject: [PATCH 3/5] style: make elvis happy --- .../emqx_authz/src/emqx_authz_api_sources.erl | 30 ++++++++++------- apps/emqx_bridge/src/emqx_bridge_api.erl | 9 +++--- .../emqx_dashboard/src/emqx_dashboard_api.erl | 24 +++++++------- .../src/emqx_mgmt_api_alarms.erl | 14 +++++--- .../src/emqx_mgmt_api_listeners.erl | 25 +++++++++------ apps/emqx_modules/src/emqx_delayed_api.erl | 32 ++++++++++++------- .../src/emqx_topic_metrics_api.erl | 9 ++++-- apps/emqx_retainer/src/emqx_retainer_api.erl | 8 +++-- .../src/emqx_rule_engine_api.erl | 18 +++++++---- 9 files changed, 102 insertions(+), 67 deletions(-) diff --git a/apps/emqx_authz/src/emqx_authz_api_sources.erl b/apps/emqx_authz/src/emqx_authz_api_sources.erl index 04c8079cb..81e0fc2b6 100644 --- a/apps/emqx_authz/src/emqx_authz_api_sources.erl +++ b/apps/emqx_authz/src/emqx_authz_api_sources.erl @@ -32,7 +32,8 @@ -define(EXAMPLE_FILE, #{type=> file, enable => true, - rules => <<"{allow,{username,\"^dashboard?\"},subscribe,[\"$SYS/#\"]}.\n{allow,{ipaddr,\"127.0.0.1\"},all,[\"$SYS/#\",\"#\"]}.">> + rules => <<"{allow,{username,\"^dashboard?\"},subscribe,[\"$SYS/#\"]}.\n", + "{allow,{ipaddr,\"127.0.0.1\"},all,[\"$SYS/#\",\"#\"]}.">> }). -define(EXAMPLE_RETURNED, @@ -90,7 +91,7 @@ sources_api() -> }, post => #{ description => "Add new source", - requestBody => #{ + 'requestBody' => #{ content => #{ 'application/json' => #{ schema => minirest:ref(<<"sources">>), @@ -114,7 +115,7 @@ sources_api() -> }, put => #{ description => "Update all sources", - requestBody => #{ + 'requestBody' => #{ content => #{ 'application/json' => #{ schema => #{ @@ -206,7 +207,7 @@ source_api() -> required => true } ], - requestBody => #{ + 'requestBody' => #{ content => #{ 'application/json' => #{ schema => minirest:ref(<<"sources">>), @@ -279,7 +280,7 @@ move_source_api() -> required => true } ], - requestBody => #{ + 'requestBody' => #{ content => #{ 'application/json' => #{ schema => #{ @@ -287,7 +288,7 @@ move_source_api() -> required => [position], properties => #{ position => #{ - oneOf => [ + 'oneOf' => [ #{type => string, enum => [<<"top">>, <<"bottom">>] }, @@ -326,7 +327,8 @@ move_source_api() -> {"/authorization/sources/:type/move", Metadata, move_source}. sources(get, _) -> - Sources = lists:foldl(fun (#{<<"type">> := <<"file">>, <<"enable">> := Enable, <<"path">> := Path}, AccIn) -> + Sources = lists:foldl(fun (#{<<"type">> := <<"file">>, + <<"enable">> := Enable, <<"path">> := Path}, AccIn) -> case file:read_file(Path) of {ok, Rules} -> lists:append(AccIn, [#{type => file, @@ -345,7 +347,8 @@ sources(get, _) -> {200, #{sources => Sources}}; sources(post, #{body := #{<<"type">> := <<"file">>, <<"rules">> := Rules}}) -> {ok, Filename} = write_file(acl_conf_file(), Rules), - update_config(?CMD_PREPEND, [#{<<"type">> => <<"file">>, <<"enable">> => true, <<"path">> => Filename}]); + update_config(?CMD_PREPEND, [#{<<"type">> => <<"file">>, + <<"enable">> => true, <<"path">> => Filename}]); sources(post, #{body := Body}) when is_map(Body) -> update_config(?CMD_PREPEND, [maybe_write_certs(Body)]); sources(put, #{body := Body}) when is_list(Body) -> @@ -377,9 +380,13 @@ source(get, #{bindings := #{type := Type}}) -> [Source] -> {200, read_certs(Source)} end; -source(put, #{bindings := #{type := <<"file">>}, body := #{<<"type">> := <<"file">>, <<"rules">> := Rules, <<"enable">> := Enable}}) -> +source(put, #{bindings := #{type := <<"file">>}, body := #{<<"type">> := <<"file">>, + <<"rules">> := Rules, + <<"enable">> := Enable}}) -> {ok, Filename} = write_file(maps:get(path, emqx_authz:lookup(file), ""), Rules), - case emqx_authz:update({?CMD_REPLACE, <<"file">>}, #{<<"type">> => <<"file">>, <<"enable">> => Enable, <<"path">> => Filename}) of + case emqx_authz:update({?CMD_REPLACE, <<"file">>}, #{<<"type">> => <<"file">>, + <<"enable">> => Enable, + <<"path">> => Filename}) of {ok, _} -> {204}; {error, Reason} -> {400, #{code => <<"BAD_REQUEST">>, @@ -405,7 +412,8 @@ get_raw_sources() -> RawSources = emqx:get_raw_config([authorization, sources], []), Schema = #{roots => emqx_authz_schema:fields("authorization"), fields => #{}}, Conf = #{<<"sources">> => RawSources}, - #{<<"sources">> := Sources} = hocon_schema:check_plain(Schema, Conf, #{only_fill_defaults => true}), + #{<<"sources">> := Sources} = hocon_schema:check_plain(Schema, Conf, + #{only_fill_defaults => true}), Sources. get_raw_source(Type) -> diff --git a/apps/emqx_bridge/src/emqx_bridge_api.erl b/apps/emqx_bridge/src/emqx_bridge_api.erl index ecff87774..29d55f749 100644 --- a/apps/emqx_bridge/src/emqx_bridge_api.erl +++ b/apps/emqx_bridge/src/emqx_bridge_api.erl @@ -45,10 +45,10 @@ req_schema() -> emqx_mgmt_api_configs:gen_schema(Conf) end || T <- ?TYPES], - #{oneOf => Schema}. + #{'oneOf' => Schema}. resp_schema() -> - #{oneOf := Schema} = req_schema(), + #{'oneOf' := Schema} = req_schema(), AddMetadata = fun(Prop) -> Prop#{is_connected => #{type => boolean}, id => #{type => string}, @@ -57,7 +57,7 @@ resp_schema() -> end, Schema1 = [S#{properties => AddMetadata(Prop)} || S = #{properties := Prop} <- Schema], - #{oneOf => Schema1}. + #{'oneOf' => Schema1}. api_spec() -> {bridge_apis(), []}. @@ -120,7 +120,8 @@ operation_apis() -> param_path_id(), param_path_operation()], responses => #{ - <<"500">> => emqx_mgmt_util:error_schema(<<"Operation Failed">>, ['INTERNAL_ERROR']), + <<"500">> => emqx_mgmt_util:error_schema(<<"Operation Failed">>, + ['INTERNAL_ERROR']), <<"200">> => emqx_mgmt_util:schema(<<"Operation success">>)}}}, {"/nodes/:node/bridges/:id/operation/:operation", Metadata, manage_bridges}. diff --git a/apps/emqx_dashboard/src/emqx_dashboard_api.erl b/apps/emqx_dashboard/src/emqx_dashboard_api.erl index 1cf59d509..a3f58f4e4 100644 --- a/apps/emqx_dashboard/src/emqx_dashboard_api.erl +++ b/apps/emqx_dashboard/src/emqx_dashboard_api.erl @@ -48,16 +48,16 @@ paths() -> ["/login", "/logout", "/users", schema("/login") -> #{ - operationId => login, + 'operationId' => login, post => #{ tags => [<<"dashboard">>], description => <<"Dashboard Auth">>, summary => <<"Dashboard Auth">>, - requestBody => + 'requestBody' => [ {username, mk(binary(), #{desc => <<"The User for which to create the token.">>, - maxLength => 100, example => <<"admin">>})}, + 'maxLength' => 100, example => <<"admin">>})}, {password, mk(binary(), #{desc => "password", example => "public"})} ], @@ -76,14 +76,14 @@ schema("/login") -> }}; schema("/logout") -> #{ - operationId => logout, + 'operationId' => logout, post => #{ tags => [<<"dashboard">>], description => <<"Dashboard User logout">>, - requestBody => [ + 'requestBody' => [ {username, mk(binary(), #{desc => <<"The User for which to create the token.">>, - maxLength => 100, example => <<"admin">>})} + 'maxLength' => 100, example => <<"admin">>})} ], responses => #{ 200 => <<"Dashboard logout successfully">> @@ -92,7 +92,7 @@ schema("/logout") -> }; schema("/users") -> #{ - operationId => users, + 'operationId' => users, get => #{ tags => [<<"dashboard">>], description => <<"Get dashboard users">>, @@ -104,7 +104,7 @@ schema("/users") -> post => #{ tags => [<<"dashboard">>], description => <<"Create dashboard users">>, - requestBody => fields(user_password), + 'requestBody' => fields(user_password), responses => #{ 200 => <<"Create user successfully">>, 400 => [{code, mk(string(), #{example => 'CREATE_FAIL'})}, @@ -114,13 +114,13 @@ schema("/users") -> schema("/users/:username") -> #{ - operationId => user, + 'operationId' => user, put => #{ tags => [<<"dashboard">>], description => <<"Update dashboard users">>, parameters => [{username, mk(binary(), #{in => path, example => <<"admin">>})}], - requestBody => [{tag, mk(binary(), #{desc => <<"Tag">>})}], + 'requestBody' => [{tag, mk(binary(), #{desc => <<"Tag">>})}], responses => #{ 200 => <<"Update User successfully">>, 400 => [{code, mk(string(), #{example => 'UPDATE_FAIL'})}, @@ -138,13 +138,13 @@ schema("/users/:username") -> }; schema("/users/:username/change_pwd") -> #{ - operationId => change_pwd, + 'operationId' => change_pwd, put => #{ tags => [<<"dashboard">>], description => <<"Update dashboard users password">>, parameters => [{username, mk(binary(), #{in => path, required => true, example => <<"admin">>})}], - requestBody => [ + 'requestBody' => [ {old_pwd, mk(binary(), #{required => true})}, {new_pwd, mk(binary(), #{required => true})} ], diff --git a/apps/emqx_management/src/emqx_mgmt_api_alarms.erl b/apps/emqx_management/src/emqx_mgmt_api_alarms.erl index 95a100972..1204ee22f 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_alarms.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_alarms.erl @@ -36,7 +36,7 @@ paths() -> schema("/alarms") -> #{ - operationId => alarms, + 'operationId' => alarms, get => #{ description => <<"EMQ X alarms">>, parameters => [ @@ -63,17 +63,21 @@ schema("/alarms") -> fields(alarm) -> [ - {node, hoconsc:mk(binary(), #{desc => <<"Alarm in node">>, example => atom_to_list(node())})}, - {name, hoconsc:mk(binary(), #{desc => <<"Alarm name">>, example => <<"high_system_memory_usage">>})}, + {node, hoconsc:mk(binary(), + #{desc => <<"Alarm in node">>, example => atom_to_list(node())})}, + {name, hoconsc:mk(binary(), + #{desc => <<"Alarm name">>, example => <<"high_system_memory_usage">>})}, {message, hoconsc:mk(binary(), #{desc => <<"Alarm readable information">>, example => <<"System memory usage is higher than 70%">>})}, {details, hoconsc:mk(map(), #{desc => <<"Alarm details information">>, example => #{<<"high_watermark">> => 70}})}, - {duration, hoconsc:mk(integer(), #{desc => <<"Alarms duration time; UNIX time stamp, millisecond">>, + {duration, hoconsc:mk(integer(), + #{desc => <<"Alarms duration time; UNIX time stamp, millisecond">>, example => 297056})}, {activate_at, hoconsc:mk(binary(), #{desc => <<"Alarms activate time, RFC 3339">>, example => <<"2021-10-25T11:52:52.548+08:00">>})}, - {deactivate_at, hoconsc:mk(binary(), #{desc => <<"Nullable, alarms deactivate time, RFC 3339">>, + {deactivate_at, hoconsc:mk(binary(), + #{desc => <<"Nullable, alarms deactivate time, RFC 3339">>, example => <<"2021-10-31T10:52:52.548+08:00">>})} ]; diff --git a/apps/emqx_management/src/emqx_mgmt_api_listeners.erl b/apps/emqx_management/src/emqx_mgmt_api_listeners.erl index eebdc4aae..2a871d166 100644 --- a/apps/emqx_management/src/emqx_mgmt_api_listeners.erl +++ b/apps/emqx_management/src/emqx_mgmt_api_listeners.erl @@ -59,10 +59,10 @@ req_schema() -> Schema = [emqx_mgmt_api_configs:gen_schema( emqx:get_raw_config([listeners, T, default], #{})) || T <- ?TYPES_ATOM], - #{oneOf => Schema}. + #{'oneOf' => Schema}. resp_schema() -> - #{oneOf := Schema} = req_schema(), + #{'oneOf' := Schema} = req_schema(), AddMetadata = fun(Prop) -> Prop#{running => #{type => boolean}, id => #{type => string}, @@ -70,7 +70,7 @@ resp_schema() -> end, Schema1 = [S#{properties => AddMetadata(Prop)} || S = #{properties := Prop} <- Schema], - #{oneOf => Schema1}. + #{'oneOf' => Schema1}. api_list_listeners() -> Metadata = #{ @@ -78,7 +78,8 @@ api_list_listeners() -> description => <<"List listeners from all nodes in the cluster">>, responses => #{ <<"200">> => - emqx_mgmt_util:array_schema(resp_schema(), <<"List listeners successfully">>)}}}, + emqx_mgmt_util:array_schema(resp_schema(), + <<"List listeners successfully">>)}}}, {"/listeners", Metadata, list_listeners}. api_list_update_listeners_by_id() -> @@ -92,18 +93,21 @@ api_list_update_listeners_by_id() -> <<"200">> => emqx_mgmt_util:array_schema(resp_schema(), <<"List listeners successfully">>)}}, put => #{ - description => <<"Create or update a listener by a given Id to all nodes in the cluster">>, + description => + <<"Create or update a listener by a given Id to all nodes in the cluster">>, parameters => [param_path_id()], - requestBody => emqx_mgmt_util:schema(req_schema(), <<"Listener Config">>), + 'requestBody' => emqx_mgmt_util:schema(req_schema(), <<"Listener Config">>), responses => #{ <<"400">> => - emqx_mgmt_util:error_schema(?UPDATE_CONFIG_FAILED, ['BAD_LISTENER_ID', 'BAD_CONFIG_SCHEMA']), + emqx_mgmt_util:error_schema(?UPDATE_CONFIG_FAILED, + ['BAD_LISTENER_ID', 'BAD_CONFIG_SCHEMA']), <<"404">> => emqx_mgmt_util:error_schema(?LISTENER_NOT_FOUND, ['BAD_LISTENER_ID']), <<"500">> => emqx_mgmt_util:error_schema(?OPERATION_FAILED, ['INTERNAL_ERROR']), <<"200">> => - emqx_mgmt_util:array_schema(resp_schema(), <<"Create or update listener successfully">>)}}, + emqx_mgmt_util:array_schema(resp_schema(), + <<"Create or update listener successfully">>)}}, delete => #{ description => <<"Delete a listener by a given Id to all nodes in the cluster">>, parameters => [param_path_id()], @@ -143,10 +147,11 @@ api_get_update_listener_by_id_on_node() -> put => #{ description => <<"Create or update a listener by a given Id on a specific node">>, parameters => [param_path_node(), param_path_id()], - requestBody => emqx_mgmt_util:schema(req_schema(), <<"Listener Config">>), + 'requestBody' => emqx_mgmt_util:schema(req_schema(), <<"Listener Config">>), responses => #{ <<"400">> => - emqx_mgmt_util:error_schema(?UPDATE_CONFIG_FAILED, ['BAD_LISTENER_ID', 'BAD_CONFIG_SCHEMA']), + emqx_mgmt_util:error_schema(?UPDATE_CONFIG_FAILED, + ['BAD_LISTENER_ID', 'BAD_CONFIG_SCHEMA']), <<"404">> => emqx_mgmt_util:error_schema(?NODE_LISTENER_NOT_FOUND, ['BAD_NODE_NAME', 'BAD_LISTENER_ID']), diff --git a/apps/emqx_modules/src/emqx_delayed_api.erl b/apps/emqx_modules/src/emqx_delayed_api.erl index f0b72f502..8137d9e63 100644 --- a/apps/emqx_modules/src/emqx_delayed_api.erl +++ b/apps/emqx_modules/src/emqx_delayed_api.erl @@ -52,7 +52,7 @@ paths() -> ["/mqtt/delayed", "/mqtt/delayed/messages", "/mqtt/delayed/messages/: schema("/mqtt/delayed") -> #{ - operationId => status, + 'operationId' => status, get => #{ tags => [<<"mqtt">>], description => <<"Get delayed status">>, @@ -64,25 +64,28 @@ schema("/mqtt/delayed") -> put => #{ tags => [<<"mqtt">>], description => <<"Enable or disable delayed, set max delayed messages">>, - requestBody => ref(emqx_modules_schema, "delayed"), + 'requestBody' => ref(emqx_modules_schema, "delayed"), responses => #{ 200 => mk(ref(emqx_modules_schema, "delayed"), #{desc => <<"Enable or disable delayed successfully">>}), - 400 => emqx_dashboard_swagger:error_codes([?BAD_REQUEST], <<"Max limit illegality">>) + 400 => emqx_dashboard_swagger:error_codes( [?BAD_REQUEST] + , <<"Max limit illegality">>) } } }; schema("/mqtt/delayed/messages/:msgid") -> - #{operationId => delayed_message, + #{'operationId' => delayed_message, get => #{ tags => [<<"mqtt">>], description => <<"Get delayed message">>, parameters => [{msgid, mk(binary(), #{in => path, desc => <<"delay message ID">>})}], responses => #{ 200 => ref("message_without_payload"), - 400 => emqx_dashboard_swagger:error_codes([?MESSAGE_ID_SCHEMA_ERROR], <<"Bad MsgId format">>), - 404 => emqx_dashboard_swagger:error_codes([?MESSAGE_ID_NOT_FOUND], <<"MsgId not found">>) + 400 => emqx_dashboard_swagger:error_codes( [?MESSAGE_ID_SCHEMA_ERROR] + , <<"Bad MsgId format">>), + 404 => emqx_dashboard_swagger:error_codes( [?MESSAGE_ID_NOT_FOUND] + , <<"MsgId not found">>) } }, delete => #{ @@ -91,14 +94,16 @@ schema("/mqtt/delayed/messages/:msgid") -> parameters => [{msgid, mk(binary(), #{in => path, desc => <<"delay message ID">>})}], responses => #{ 204 => <<"Delete delayed message success">>, - 400 => emqx_dashboard_swagger:error_codes([?MESSAGE_ID_SCHEMA_ERROR], <<"Bad MsgId format">>), - 404 => emqx_dashboard_swagger:error_codes([?MESSAGE_ID_NOT_FOUND], <<"MsgId not found">>) + 400 => emqx_dashboard_swagger:error_codes( [?MESSAGE_ID_SCHEMA_ERROR] + , <<"Bad MsgId format">>), + 404 => emqx_dashboard_swagger:error_codes( [?MESSAGE_ID_NOT_FOUND] + , <<"MsgId not found">>) } } }; schema("/mqtt/delayed/messages") -> #{ - operationId => delayed_messages, + 'operationId' => delayed_messages, get => #{ tags => [<<"mqtt">>], description => <<"List delayed messages">>, @@ -130,7 +135,8 @@ fields("message_without_payload") -> {from_username, mk(binary(), #{desc => <<"From Username">>})} ]; fields("message") -> - PayloadDesc = io_lib:format("Payload, base64 encode. Payload will be ~p if length large than ~p", + PayloadDesc = io_lib:format( + "Payload, base64 encode. Payload will be ~p if length large than ~p", [?PAYLOAD_TOO_LARGE, ?MAX_PAYLOAD_LENGTH]), fields("message_without_payload") ++ [{payload, mk(binary(), #{desc => iolist_to_binary(PayloadDesc)})}]. @@ -233,9 +239,11 @@ update_config_(Node, Config) -> rpc_call(Node, ?MODULE, ?FUNCTION_NAME, [Node, Config]). generate_http_code_map(id_schema_error, Id) -> - #{code => ?MESSAGE_ID_SCHEMA_ERROR, message => iolist_to_binary(io_lib:format("Message ID ~p schema error", [Id]))}; + #{code => ?MESSAGE_ID_SCHEMA_ERROR, message => + iolist_to_binary(io_lib:format("Message ID ~p schema error", [Id]))}; generate_http_code_map(not_found, Id) -> - #{code => ?MESSAGE_ID_NOT_FOUND, message => iolist_to_binary(io_lib:format("Message ID ~p not found", [Id]))}. + #{code => ?MESSAGE_ID_NOT_FOUND, message => + iolist_to_binary(io_lib:format("Message ID ~p not found", [Id]))}. rpc_call(Node, Module, Fun, Args) -> case rpc:call(Node, Module, Fun, Args) of diff --git a/apps/emqx_modules/src/emqx_topic_metrics_api.erl b/apps/emqx_modules/src/emqx_topic_metrics_api.erl index e62d5537f..e8be39c47 100644 --- a/apps/emqx_modules/src/emqx_topic_metrics_api.erl +++ b/apps/emqx_modules/src/emqx_topic_metrics_api.erl @@ -96,7 +96,8 @@ topic_metrics_api() -> responses => #{ <<"200">> => schema(<<"Create topic metrics success">>), <<"409">> => error_schema(<<"Topic metrics max limit">>, [?EXCEED_LIMIT]), - <<"400">> => error_schema(<<"Topic metrics already exist or bad topic">>, [?BAD_REQUEST, ?BAD_TOPIC]) + <<"400">> => error_schema( <<"Topic metrics already exist or bad topic">> + , [?BAD_REQUEST, ?BAD_TOPIC]) } } }, @@ -174,8 +175,10 @@ register(Topic) -> [Topic])), {400, #{code => ?BAD_TOPIC, message => Message}}; {error, {quota_exceeded, bad_topic}} -> - Message = list_to_binary(io_lib:format("Max topic metrics count is ~p, and topic cannot have wildcard ~p", - [emqx_topic_metrics:max_limit(), Topic])), + Message = list_to_binary( + io_lib:format( + "Max topic metrics count is ~p, and topic cannot have wildcard ~p", + [emqx_topic_metrics:max_limit(), Topic])), {400, #{code => ?BAD_REQUEST, message => Message}}; {error, already_existed} -> Message = list_to_binary(io_lib:format("Topic ~p already registered", [Topic])), diff --git a/apps/emqx_retainer/src/emqx_retainer_api.erl b/apps/emqx_retainer/src/emqx_retainer_api.erl index afcd2e3f6..61085d9a9 100644 --- a/apps/emqx_retainer/src/emqx_retainer_api.erl +++ b/apps/emqx_retainer/src/emqx_retainer_api.erl @@ -151,7 +151,7 @@ with_topic(delete, #{bindings := Bindings}) -> -spec lookup(undefined | binary(), map(), - fun((#message{}) -> map())) -> + fun((emqx_types:message()) -> map())) -> {200, map()}. lookup(Topic, #{query_string := Qs}, Formatter) -> Page = maps:get(page, Qs, 1), @@ -166,11 +166,13 @@ format_message(Messages, Formatter) when is_list(Messages)-> format_message(Message, Formatter) -> Formatter(Message). -format_message(#message{id = ID, qos = Qos, topic = Topic, from = From, timestamp = Timestamp, headers = Headers}) -> +format_message(#message{ id = ID, qos = Qos, topic = Topic, from = From + , timestamp = Timestamp, headers = Headers}) -> #{msgid => emqx_guid:to_hexstr(ID), qos => Qos, topic => Topic, - publish_at => list_to_binary(calendar:system_time_to_rfc3339(Timestamp, [{unit, millisecond}])), + publish_at => list_to_binary(calendar:system_time_to_rfc3339( + Timestamp, [{unit, millisecond}])), from_clientid => to_bin_string(From), from_username => maps:get(username, Headers, <<>>) }. diff --git a/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl b/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl index a70c7894c..2250d0f93 100644 --- a/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl +++ b/apps/emqx_rule_engine/src/emqx_rule_engine_api.erl @@ -62,7 +62,7 @@ api_rules_list_create() -> emqx_mgmt_util:array_schema(resp_schema(), <<"List rules successfully">>)}}, post => #{ description => <<"Create a new rule using given Id to all nodes in the cluster">>, - requestBody => emqx_mgmt_util:schema(post_req_schema(), <<"Rule parameters">>), + 'requestBody' => emqx_mgmt_util:schema(post_req_schema(), <<"Rule parameters">>), responses => #{ <<"400">> => emqx_mgmt_util:error_schema(<<"Invalid Parameters">>, ['BAD_ARGS']), @@ -94,12 +94,13 @@ api_rules_crud() -> put => #{ description => <<"Create or update a rule by given Id to all nodes in the cluster">>, parameters => [param_path_id()], - requestBody => emqx_mgmt_util:schema(put_req_schema(), <<"Rule parameters">>), + 'requestBody' => emqx_mgmt_util:schema(put_req_schema(), <<"Rule parameters">>), responses => #{ <<"400">> => emqx_mgmt_util:error_schema(<<"Invalid Parameters">>, ['BAD_ARGS']), <<"200">> => - emqx_mgmt_util:schema(resp_schema(), <<"Create or update rule successfully">>)}}, + emqx_mgmt_util:schema(resp_schema(), + <<"Create or update rule successfully">>)}}, delete => #{ description => <<"Delete a rule by given Id from all nodes in the cluster">>, parameters => [param_path_id()], @@ -113,7 +114,7 @@ api_rule_test() -> Metadata = #{ post => #{ description => <<"Test a rule">>, - requestBody => emqx_mgmt_util:schema(rule_test_req_schema(), <<"Rule parameters">>), + 'requestBody' => emqx_mgmt_util:schema(rule_test_req_schema(), <<"Rule parameters">>), responses => #{ <<"400">> => emqx_mgmt_util:error_schema(<<"Invalid Parameters">>, ['BAD_ARGS']), @@ -141,7 +142,7 @@ put_req_schema() -> description => <<"The outputs of the rule">>, type => array, items => #{ - oneOf => [ + 'oneOf' => [ #{ type => string, example => <<"channel_id_of_my_bridge">>, @@ -253,7 +254,7 @@ crud_rules(post, #{body := #{<<"id">> := Id} = Params}) -> not_found -> case emqx:update_config(ConfPath, maps:remove(<<"id">>, Params), #{}) of {ok, #{post_config_update := #{emqx_rule_engine := AllRules}}} -> - [Rule] = [R || R = #{id := Id0} <- AllRules, Id0 == Id], + [Rule] = get_one_rule(AllRules, Id), {201, format_rule_resp(Rule)}; {error, Reason} -> ?SLOG(error, #{msg => "create_rule_failed", @@ -280,7 +281,7 @@ crud_rules_by_id(put, #{bindings := #{id := Id}, body := Params}) -> ConfPath = emqx_rule_engine:config_key_path() ++ [Id], case emqx:update_config(ConfPath, maps:remove(<<"id">>, Params), #{}) of {ok, #{post_config_update := #{emqx_rule_engine := AllRules}}} -> - [Rule] = [R || R = #{id := Id0} <- AllRules, Id0 == Id], + [Rule] = get_one_rule(AllRules, Id), {200, format_rule_resp(Rule)}; {error, Reason} -> ?SLOG(error, #{msg => "update_rule_failed", @@ -339,3 +340,6 @@ do_format_output(BridgeChannelId) when is_binary(BridgeChannelId) -> get_rule_metrics(Id) -> [maps:put(node, Node, rpc:call(Node, emqx_rule_metrics, get_rule_metrics, [Id])) || Node <- mria_mnesia:running_nodes()]. + +get_one_rule(AllRules, Id) -> + [R || R = #{id := Id0} <- AllRules, Id0 == Id]. From dcc5ae064228d90f6ad13bec3a3d59f20bcf1de0 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Fri, 12 Nov 2021 10:32:31 +0800 Subject: [PATCH 4/5] test: API return code section --- apps/emqx_management/test/emqx_mgmt_api_test_util.erl | 2 +- apps/emqx_rule_engine/test/emqx_rule_engine_api_SUITE.erl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/emqx_management/test/emqx_mgmt_api_test_util.erl b/apps/emqx_management/test/emqx_mgmt_api_test_util.erl index cdad91b0c..dd14d0a81 100644 --- a/apps/emqx_management/test/emqx_mgmt_api_test_util.erl +++ b/apps/emqx_management/test/emqx_mgmt_api_test_util.erl @@ -88,7 +88,7 @@ do_request_api(Method, Request)-> {error, socket_closed_remotely} -> {error, socket_closed_remotely}; {ok, {{"HTTP/1.1", Code, _}, _, Return} } - when Code =:= 200 orelse Code =:= 201 -> + when Code >= 200 andalso Code =< 299 -> {ok, Return}; {ok, {Reason, _, _}} -> {error, Reason} diff --git a/apps/emqx_rule_engine/test/emqx_rule_engine_api_SUITE.erl b/apps/emqx_rule_engine/test/emqx_rule_engine_api_SUITE.erl index 10ea55a69..712d113f9 100644 --- a/apps/emqx_rule_engine/test/emqx_rule_engine_api_SUITE.erl +++ b/apps/emqx_rule_engine/test/emqx_rule_engine_api_SUITE.erl @@ -60,7 +60,7 @@ t_crud_rule_api(_Config) -> ?assertEqual(Rule3, Rule2), ?assertEqual(<<"select * from \"t/b\"">>, maps:get(sql, Rule3)), - ?assertMatch({200}, emqx_rule_engine_api:crud_rules_by_id(delete, + ?assertMatch({204}, emqx_rule_engine_api:crud_rules_by_id(delete, #{bindings => #{id => RuleID}})), %ct:pal("Show After Deleted: ~p", [NotFound]), From e07e3c703957862979e6d98e21bd68f3b2783a65 Mon Sep 17 00:00:00 2001 From: JimMoen Date: Mon, 15 Nov 2021 16:10:16 +0800 Subject: [PATCH 5/5] ci: update emqx-fvt version --- .github/workflows/run_api_tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/run_api_tests.yaml b/.github/workflows/run_api_tests.yaml index fc8630b95..c315ec23b 100644 --- a/.github/workflows/run_api_tests.yaml +++ b/.github/workflows/run_api_tests.yaml @@ -61,7 +61,7 @@ jobs: - uses: actions/checkout@v2 with: repository: emqx/emqx-fvt - ref: v1.3.0 + ref: v1.5.0 path: . - uses: actions/setup-java@v1 with: