Skip to content

Commit f03f5aa

Browse files
Normalize policy definitions before merging them
Closes rabbitmq/rabbitmq-management#751. (cherry picked from commit 751ece5) Conflicts: src/rabbit_policy.erl
1 parent 184e2e9 commit f03f5aa

File tree

2 files changed

+88
-17
lines changed

2 files changed

+88
-17
lines changed

src/rabbit_policy.erl

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242

4343
-export([register/0]).
4444
-export([invalidate/0, recover/0]).
45-
-export([name/1, name_op/1, effective_definition/1, get/2, get_arg/3, set/1]).
45+
-export([name/1, name_op/1, effective_definition/1, merge_operator_definitions/2, get/2, get_arg/3, set/1]).
4646
-export([validate/5, notify/5, notify_clear/4]).
4747
-export([parse_set/7, set/7, delete/3, lookup/2, list/0, list/1,
4848
list_formatted/1, list_formatted/3, info_keys/0]).
@@ -69,23 +69,23 @@ name0(undefined) -> none;
6969
name0(Policy) -> pget(name, Policy).
7070

7171
effective_definition(#amqqueue{policy = Policy, operator_policy = OpPolicy}) ->
72-
effective_definition0(Policy, OpPolicy);
72+
merge_operator_definitions(Policy, OpPolicy);
7373
effective_definition(#exchange{policy = Policy, operator_policy = OpPolicy}) ->
74-
effective_definition0(Policy, OpPolicy).
75-
76-
effective_definition0(undefined, undefined) -> undefined;
77-
effective_definition0(Policy, undefined) -> pget(definition, Policy);
78-
effective_definition0(undefined, OpPolicy) -> pget(definition, OpPolicy);
79-
effective_definition0(Policy, OpPolicy) ->
80-
OpDefinition = pget(definition, OpPolicy, []),
81-
Definition = pget(definition, Policy, []),
82-
{Keys, _} = lists:unzip(Definition),
83-
{OpKeys, _} = lists:unzip(OpDefinition),
74+
merge_operator_definitions(Policy, OpPolicy).
75+
76+
merge_operator_definitions(undefined, undefined) -> undefined;
77+
merge_operator_definitions(Policy, undefined) -> pget(definition, Policy);
78+
merge_operator_definitions(undefined, OpPolicy) -> pget(definition, OpPolicy);
79+
merge_operator_definitions(Policy, OpPolicy) ->
80+
OpDefinition = rabbit_data_coercion:to_map(pget(definition, OpPolicy, [])),
81+
Definition = rabbit_data_coercion:to_map(pget(definition, Policy, [])),
82+
Keys = maps:keys(Definition),
83+
OpKeys = maps:keys(OpDefinition),
8484
lists:map(fun(Key) ->
85-
case {pget(Key, Definition), pget(Key, OpDefinition)} of
86-
{Val, undefined} -> {Key, Val};
87-
{undefined, Val} -> {Key, Val};
88-
{Val, OpVal} -> {Key, merge_policy_value(Key, Val, OpVal)}
85+
case {maps:get(Key, Definition, undefined), maps:get(Key, OpDefinition, undefined)} of
86+
{Val, undefined} -> {Key, Val};
87+
{undefined, OpVal} -> {Key, OpVal};
88+
{Val, OpVal} -> {Key, merge_policy_value(Key, Val, OpVal)}
8989
end
9090
end,
9191
lists:umerge(Keys, OpKeys)).
@@ -128,7 +128,7 @@ get0(Name, Policy, OpPolicy) ->
128128
merge_policy_value(Name, PolicyVal, OpVal) ->
129129
case policy_merge_strategy(Name) of
130130
{ok, Module} -> Module:merge_policy_value(Name, PolicyVal, OpVal);
131-
{error, not_found} -> PolicyVal
131+
{error, not_found} -> rabbit_policies:merge_policy_value(Name, PolicyVal, OpVal)
132132
end.
133133

134134
policy_merge_strategy(Name) ->

test/unit_SUITE.erl

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ groups() ->
4747
rabbitmqctl_encode,
4848
pmerge,
4949
plmerge,
50+
merge_operator_policy_definitions,
5051
priority_queue,
5152
rabbit_direct_extract_extra_auth_props,
5253
{resource_monitor, [parallel], [
@@ -807,6 +808,76 @@ plmerge(_Config) ->
807808
[{a, 1}, {b, 2}, {c, 3}, {d, 4}] = rabbit_misc:plmerge(P1, P2),
808809
passed.
809810

811+
merge_operator_policy_definitions(_Config) ->
812+
P1 = undefined,
813+
P2 = [{definition, [{<<"message-ttl">>, 3000}]}],
814+
?assertEqual([{<<"message-ttl">>, 3000}], rabbit_policy:merge_operator_definitions(P1, P2)),
815+
?assertEqual([{<<"message-ttl">>, 3000}], rabbit_policy:merge_operator_definitions(P2, P1)),
816+
817+
?assertEqual([{<<"message-ttl">>, 3000}], rabbit_policy:merge_operator_definitions(P1, rabbit_data_coercion:to_map(P2))),
818+
?assertEqual([{<<"message-ttl">>, 3000}], rabbit_policy:merge_operator_definitions(rabbit_data_coercion:to_map(P2), P1)),
819+
820+
?assertEqual(undefined, rabbit_policy:merge_operator_definitions(undefined, undefined)),
821+
822+
?assertEqual([], rabbit_policy:merge_operator_definitions([], [])),
823+
?assertEqual([], rabbit_policy:merge_operator_definitions(#{}, [])),
824+
?assertEqual([], rabbit_policy:merge_operator_definitions(#{}, #{})),
825+
?assertEqual([], rabbit_policy:merge_operator_definitions([], #{})),
826+
827+
%% operator policy takes precedence
828+
?assertEqual([{<<"message-ttl">>, 3000}], rabbit_policy:merge_operator_definitions(
829+
[{definition, [
830+
{<<"message-ttl">>, 5000}
831+
]}],
832+
[{definition, [
833+
{<<"message-ttl">>, 3000}
834+
]}]
835+
)),
836+
837+
?assertEqual([{<<"delivery-limit">>, 20},
838+
{<<"message-ttl">>, 3000}],
839+
rabbit_policy:merge_operator_definitions(
840+
[{definition, [
841+
{<<"message-ttl">>, 5000},
842+
{<<"delivery-limit">>, 20}
843+
]}],
844+
[{definition, [
845+
{<<"message-ttl">>, 3000}
846+
]}])
847+
),
848+
849+
?assertEqual(
850+
[{<<"delivery-limit">>, 20},
851+
{<<"message-ttl">>, 3000},
852+
{<<"unknown">>, <<"value">>}],
853+
854+
rabbit_policy:merge_operator_definitions(
855+
#{definition => #{
856+
<<"message-ttl">> => 5000,
857+
<<"delivery-limit">> => 20
858+
}},
859+
#{definition => #{
860+
<<"message-ttl">> => 3000,
861+
<<"unknown">> => <<"value">>
862+
}})
863+
),
864+
865+
?assertEqual(
866+
[{<<"delivery-limit">>, 20},
867+
{<<"message-ttl">>, 3000}],
868+
869+
rabbit_policy:merge_operator_definitions(
870+
#{definition => #{
871+
<<"message-ttl">> => 5000,
872+
<<"delivery-limit">> => 20
873+
}},
874+
[{definition, [
875+
{<<"message-ttl">>, 3000}
876+
]}])
877+
),
878+
879+
passed.
880+
810881
table_codec(_Config) ->
811882
%% FIXME this does not test inexact numbers (double and float) yet,
812883
%% because they won't pass the equality assertions

0 commit comments

Comments
 (0)