Merge pull request #12096 from thalesmg/fix-delete-deps-rules-m-20231204
fix(api): return list of dependent rule ids when trying to delete bridge/action
This commit is contained in:
commit
2579f8ea92
|
@ -87,12 +87,15 @@ paths() ->
|
||||||
"/bridges_probe"
|
"/bridges_probe"
|
||||||
].
|
].
|
||||||
|
|
||||||
error_schema(Code, Message) when is_atom(Code) ->
|
error_schema(Code, Message) ->
|
||||||
error_schema([Code], Message);
|
error_schema(Code, Message, _ExtraFields = []).
|
||||||
error_schema(Codes, Message) when is_list(Message) ->
|
|
||||||
error_schema(Codes, list_to_binary(Message));
|
error_schema(Code, Message, ExtraFields) when is_atom(Code) ->
|
||||||
error_schema(Codes, Message) when is_list(Codes) andalso is_binary(Message) ->
|
error_schema([Code], Message, ExtraFields);
|
||||||
emqx_dashboard_swagger:error_codes(Codes, Message).
|
error_schema(Codes, Message, ExtraFields) when is_list(Message) ->
|
||||||
|
error_schema(Codes, list_to_binary(Message), ExtraFields);
|
||||||
|
error_schema(Codes, Message, ExtraFields) when is_list(Codes) andalso is_binary(Message) ->
|
||||||
|
ExtraFields ++ emqx_dashboard_swagger:error_codes(Codes, Message).
|
||||||
|
|
||||||
get_response_body_schema() ->
|
get_response_body_schema() ->
|
||||||
emqx_dashboard_swagger:schema_with_examples(
|
emqx_dashboard_swagger:schema_with_examples(
|
||||||
|
@ -340,7 +343,8 @@ schema("/bridges/:id") ->
|
||||||
204 => <<"Bridge deleted">>,
|
204 => <<"Bridge deleted">>,
|
||||||
400 => error_schema(
|
400 => error_schema(
|
||||||
'BAD_REQUEST',
|
'BAD_REQUEST',
|
||||||
"Cannot delete bridge while active rules are defined for this bridge"
|
"Cannot delete bridge while active rules are defined for this bridge",
|
||||||
|
[{rules, mk(array(string()), #{desc => "Dependent Rule IDs"})}]
|
||||||
),
|
),
|
||||||
404 => error_schema('NOT_FOUND', "Bridge not found"),
|
404 => error_schema('NOT_FOUND', "Bridge not found"),
|
||||||
503 => error_schema('SERVICE_UNAVAILABLE', "Service unavailable")
|
503 => error_schema('SERVICE_UNAVAILABLE', "Service unavailable")
|
||||||
|
@ -517,11 +521,12 @@ schema("/bridges_probe") ->
|
||||||
reason := rules_depending_on_this_bridge,
|
reason := rules_depending_on_this_bridge,
|
||||||
rule_ids := RuleIds
|
rule_ids := RuleIds
|
||||||
}} ->
|
}} ->
|
||||||
RulesStr = [[" ", I] || I <- RuleIds],
|
Msg0 = ?ERROR_MSG(
|
||||||
Msg = bin([
|
'BAD_REQUEST',
|
||||||
"Cannot delete bridge while active rules are depending on it:", RulesStr
|
bin("Cannot delete bridge while active rules are depending on it")
|
||||||
]),
|
),
|
||||||
?BAD_REQUEST(Msg);
|
Msg = Msg0#{rules => RuleIds},
|
||||||
|
{400, Msg};
|
||||||
{error, timeout} ->
|
{error, timeout} ->
|
||||||
?SERVICE_UNAVAILABLE(<<"request timeout">>);
|
?SERVICE_UNAVAILABLE(<<"request timeout">>);
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
|
|
|
@ -91,12 +91,15 @@ paths() ->
|
||||||
"/action_types"
|
"/action_types"
|
||||||
].
|
].
|
||||||
|
|
||||||
error_schema(Code, Message) when is_atom(Code) ->
|
error_schema(Code, Message) ->
|
||||||
error_schema([Code], Message);
|
error_schema(Code, Message, _ExtraFields = []).
|
||||||
error_schema(Codes, Message) when is_list(Message) ->
|
|
||||||
error_schema(Codes, list_to_binary(Message));
|
error_schema(Code, Message, ExtraFields) when is_atom(Code) ->
|
||||||
error_schema(Codes, Message) when is_list(Codes) andalso is_binary(Message) ->
|
error_schema([Code], Message, ExtraFields);
|
||||||
emqx_dashboard_swagger:error_codes(Codes, Message).
|
error_schema(Codes, Message, ExtraFields) when is_list(Message) ->
|
||||||
|
error_schema(Codes, list_to_binary(Message), ExtraFields);
|
||||||
|
error_schema(Codes, Message, ExtraFields) when is_list(Codes) andalso is_binary(Message) ->
|
||||||
|
ExtraFields ++ emqx_dashboard_swagger:error_codes(Codes, Message).
|
||||||
|
|
||||||
get_response_body_schema() ->
|
get_response_body_schema() ->
|
||||||
emqx_dashboard_swagger:schema_with_examples(
|
emqx_dashboard_swagger:schema_with_examples(
|
||||||
|
@ -247,7 +250,8 @@ schema("/actions/:id") ->
|
||||||
204 => <<"Bridge deleted">>,
|
204 => <<"Bridge deleted">>,
|
||||||
400 => error_schema(
|
400 => error_schema(
|
||||||
'BAD_REQUEST',
|
'BAD_REQUEST',
|
||||||
"Cannot delete bridge while active rules are defined for this bridge"
|
"Cannot delete bridge while active rules are defined for this bridge",
|
||||||
|
[{rules, mk(array(string()), #{desc => "Dependent Rule IDs"})}]
|
||||||
),
|
),
|
||||||
404 => error_schema('NOT_FOUND', "Bridge not found"),
|
404 => error_schema('NOT_FOUND', "Bridge not found"),
|
||||||
503 => error_schema('SERVICE_UNAVAILABLE', "Service unavailable")
|
503 => error_schema('SERVICE_UNAVAILABLE', "Service unavailable")
|
||||||
|
@ -445,15 +449,12 @@ schema("/action_types") ->
|
||||||
reason := rules_depending_on_this_bridge,
|
reason := rules_depending_on_this_bridge,
|
||||||
rule_ids := RuleIds
|
rule_ids := RuleIds
|
||||||
}} ->
|
}} ->
|
||||||
RuleIdLists = [binary_to_list(iolist_to_binary(X)) || X <- RuleIds],
|
Msg0 = ?ERROR_MSG(
|
||||||
RulesStr = string:join(RuleIdLists, ", "),
|
'BAD_REQUEST',
|
||||||
Msg = io_lib:format(
|
bin("Cannot delete action while active rules are depending on it")
|
||||||
"Cannot delete bridge while active rules are depending on it: ~s\n"
|
|
||||||
"Append ?also_delete_dep_actions=true to the request URL to delete "
|
|
||||||
"rule actions that depend on this bridge as well.",
|
|
||||||
[RulesStr]
|
|
||||||
),
|
),
|
||||||
?BAD_REQUEST(iolist_to_binary(Msg));
|
Msg = Msg0#{rules => RuleIds},
|
||||||
|
{400, Msg};
|
||||||
{error, timeout} ->
|
{error, timeout} ->
|
||||||
?SERVICE_UNAVAILABLE(<<"request timeout">>);
|
?SERVICE_UNAVAILABLE(<<"request timeout">>);
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
|
|
|
@ -621,9 +621,10 @@ t_check_dependent_actions_on_delete(Config) ->
|
||||||
Config
|
Config
|
||||||
),
|
),
|
||||||
%% deleting the bridge should fail because there is a rule that depends on it
|
%% deleting the bridge should fail because there is a rule that depends on it
|
||||||
{ok, 400, _} = request(
|
{ok, 400, Body} = request(
|
||||||
delete, uri(["bridges", BridgeID]) ++ "?also_delete_dep_actions=false", Config
|
delete, uri(["bridges", BridgeID]) ++ "?also_delete_dep_actions=false", Config
|
||||||
),
|
),
|
||||||
|
?assertMatch(#{<<"rules">> := [_ | _]}, emqx_utils_json:decode(Body, [return_maps])),
|
||||||
%% delete the rule first
|
%% delete the rule first
|
||||||
{ok, 204, <<>>} = request(delete, uri(["rules", RuleId]), Config),
|
{ok, 204, <<>>} = request(delete, uri(["rules", RuleId]), Config),
|
||||||
%% then delete the bridge is OK
|
%% then delete the bridge is OK
|
||||||
|
|
|
@ -958,11 +958,12 @@ t_cascade_delete_actions(Config) ->
|
||||||
},
|
},
|
||||||
Config
|
Config
|
||||||
),
|
),
|
||||||
{ok, 400, _} = request(
|
{ok, 400, Body} = request(
|
||||||
delete,
|
delete,
|
||||||
uri([?ROOT, BridgeID]),
|
uri([?ROOT, BridgeID]),
|
||||||
Config
|
Config
|
||||||
),
|
),
|
||||||
|
?assertMatch(#{<<"rules">> := [_ | _]}, emqx_utils_json:decode(Body, [return_maps])),
|
||||||
{ok, 200, [_]} = request_json(get, uri([?ROOT]), Config),
|
{ok, 200, [_]} = request_json(get, uri([?ROOT]), Config),
|
||||||
%% Cleanup
|
%% Cleanup
|
||||||
{ok, 204, _} = request(
|
{ok, 204, _} = request(
|
||||||
|
|
2
mix.exs
2
mix.exs
|
@ -58,7 +58,7 @@ defmodule EMQXUmbrella.MixProject do
|
||||||
{:ekka, github: "emqx/ekka", tag: "0.15.16", override: true},
|
{:ekka, github: "emqx/ekka", tag: "0.15.16", override: true},
|
||||||
{:gen_rpc, github: "emqx/gen_rpc", tag: "3.3.0", override: true},
|
{:gen_rpc, github: "emqx/gen_rpc", tag: "3.3.0", override: true},
|
||||||
{:grpc, github: "emqx/grpc-erl", tag: "0.6.12", override: true},
|
{:grpc, github: "emqx/grpc-erl", tag: "0.6.12", override: true},
|
||||||
{:minirest, github: "emqx/minirest", tag: "1.3.14", override: true},
|
{:minirest, github: "emqx/minirest", tag: "1.3.15", override: true},
|
||||||
{:ecpool, github: "emqx/ecpool", tag: "0.5.4", override: true},
|
{:ecpool, github: "emqx/ecpool", tag: "0.5.4", override: true},
|
||||||
{:replayq, github: "emqx/replayq", tag: "0.3.7", override: true},
|
{:replayq, github: "emqx/replayq", tag: "0.3.7", override: true},
|
||||||
{:pbkdf2, github: "emqx/erlang-pbkdf2", tag: "2.0.4", override: true},
|
{:pbkdf2, github: "emqx/erlang-pbkdf2", tag: "2.0.4", override: true},
|
||||||
|
|
|
@ -65,7 +65,7 @@
|
||||||
, {ekka, {git, "https://github.com/emqx/ekka", {tag, "0.15.16"}}}
|
, {ekka, {git, "https://github.com/emqx/ekka", {tag, "0.15.16"}}}
|
||||||
, {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "3.3.0"}}}
|
, {gen_rpc, {git, "https://github.com/emqx/gen_rpc", {tag, "3.3.0"}}}
|
||||||
, {grpc, {git, "https://github.com/emqx/grpc-erl", {tag, "0.6.12"}}}
|
, {grpc, {git, "https://github.com/emqx/grpc-erl", {tag, "0.6.12"}}}
|
||||||
, {minirest, {git, "https://github.com/emqx/minirest", {tag, "1.3.14"}}}
|
, {minirest, {git, "https://github.com/emqx/minirest", {tag, "1.3.15"}}}
|
||||||
, {ecpool, {git, "https://github.com/emqx/ecpool", {tag, "0.5.4"}}}
|
, {ecpool, {git, "https://github.com/emqx/ecpool", {tag, "0.5.4"}}}
|
||||||
, {replayq, {git, "https://github.com/emqx/replayq.git", {tag, "0.3.7"}}}
|
, {replayq, {git, "https://github.com/emqx/replayq.git", {tag, "0.3.7"}}}
|
||||||
, {pbkdf2, {git, "https://github.com/emqx/erlang-pbkdf2.git", {tag, "2.0.4"}}}
|
, {pbkdf2, {git, "https://github.com/emqx/erlang-pbkdf2.git", {tag, "2.0.4"}}}
|
||||||
|
|
Loading…
Reference in New Issue