fix(message validation): validate duplicated topics

Fixes https://emqx.atlassian.net/browse/EMQX-12254
This commit is contained in:
Thales Macedo Garitezi 2024-04-29 14:50:18 -03:00
parent 1e64e531f0
commit ffedce014f
3 changed files with 81 additions and 0 deletions

View File

@ -65,6 +65,7 @@ fields(validation) ->
#{ #{
desc => ?DESC("topics"), desc => ?DESC("topics"),
converter => fun ensure_array/2, converter => fun ensure_array/2,
validator => fun validate_unique_topics/1,
required => true required => true
} }
)}, )},
@ -269,3 +270,23 @@ do_validate_unique_schema_checks(
end; end;
do_validate_unique_schema_checks([_Check | Rest], Seen, Duplicated) -> do_validate_unique_schema_checks([_Check | Rest], Seen, Duplicated) ->
do_validate_unique_schema_checks(Rest, Seen, Duplicated). do_validate_unique_schema_checks(Rest, Seen, Duplicated).
validate_unique_topics(Topics) ->
Grouped = maps:groups_from_list(
fun(T) -> T end,
Topics
),
DuplicatedMap = maps:filter(
fun(_T, Ts) -> length(Ts) > 1 end,
Grouped
),
case maps:keys(DuplicatedMap) of
[] ->
ok;
Duplicated ->
Msg = iolist_to_binary([
<<"duplicated topics: ">>,
lists:join(", ", Duplicated)
]),
{error, Msg}
end.

View File

@ -232,6 +232,65 @@ check_test_() ->
duplicated_check_test_() -> duplicated_check_test_() ->
[ [
{"duplicated topics 1",
?_assertThrow(
{_Schema, [
#{
reason := <<"duplicated topics: t/1">>,
kind := validation_error,
path := "message_validation.validations.1.topics"
}
]},
parse_and_check([
validation(
<<"foo">>,
[schema_check(json, <<"a">>)],
#{<<"topics">> => [<<"t/1">>, <<"t/1">>]}
)
])
)},
{"duplicated topics 2",
?_assertThrow(
{_Schema, [
#{
reason := <<"duplicated topics: t/1">>,
kind := validation_error,
path := "message_validation.validations.1.topics"
}
]},
parse_and_check([
validation(
<<"foo">>,
[schema_check(json, <<"a">>)],
#{<<"topics">> => [<<"t/1">>, <<"t/#">>, <<"t/1">>]}
)
])
)},
{"duplicated topics 3",
?_assertThrow(
{_Schema, [
#{
reason := <<"duplicated topics: t/1, t/2">>,
kind := validation_error,
path := "message_validation.validations.1.topics"
}
]},
parse_and_check([
validation(
<<"foo">>,
[schema_check(json, <<"a">>)],
#{
<<"topics">> => [
<<"t/1">>,
<<"t/#">>,
<<"t/1">>,
<<"t/2">>,
<<"t/2">>
]
}
)
])
)},
{"duplicated sql checks are not checked", {"duplicated sql checks are not checked",
?_assertMatch( ?_assertMatch(
[#{<<"checks">> := [_, _]}], [#{<<"checks">> := [_, _]}],

View File

@ -0,0 +1 @@
Added a validation to prevent duplicated topics when configuring a message validation.