chore(topic_index): add topic validation
This commit is contained in:
parent
33ed53bb6a
commit
558402a68e
|
@ -113,7 +113,7 @@
|
||||||
%% @doc Make a search-key for the given topic.
|
%% @doc Make a search-key for the given topic.
|
||||||
-spec make_key(emqx_types:topic(), ID) -> key(ID).
|
-spec make_key(emqx_types:topic(), ID) -> key(ID).
|
||||||
make_key(Topic, ID) when is_binary(Topic) ->
|
make_key(Topic, ID) when is_binary(Topic) ->
|
||||||
Words = words(Topic),
|
Words = filter_words(Topic),
|
||||||
case emqx_topic:wildcard(Words) of
|
case emqx_topic:wildcard(Words) of
|
||||||
true ->
|
true ->
|
||||||
%% it's a wildcard
|
%% it's a wildcard
|
||||||
|
@ -171,7 +171,7 @@ matches(Topic, NextF, Opts) ->
|
||||||
|
|
||||||
%% @doc Entrypoint of the search for a given topic.
|
%% @doc Entrypoint of the search for a given topic.
|
||||||
search(Topic, NextF, Opts) ->
|
search(Topic, NextF, Opts) ->
|
||||||
Words = words(Topic),
|
Words = topic_words(Topic),
|
||||||
Base = base_init(Words),
|
Base = base_init(Words),
|
||||||
ORetFirst = proplists:get_bool(return_first, Opts),
|
ORetFirst = proplists:get_bool(return_first, Opts),
|
||||||
OUnique = proplists:get_bool(unique, Opts),
|
OUnique = proplists:get_bool(unique, Opts),
|
||||||
|
@ -320,18 +320,22 @@ match_add(K, Acc) when is_list(Acc) ->
|
||||||
match_add(K, first) ->
|
match_add(K, first) ->
|
||||||
throw({first, K}).
|
throw({first, K}).
|
||||||
|
|
||||||
-spec words(emqx_types:topic()) -> [word()].
|
-spec filter_words(emqx_types:topic()) -> [word()].
|
||||||
words(Topic) when is_binary(Topic) ->
|
filter_words(Topic) when is_binary(Topic) ->
|
||||||
% NOTE
|
% NOTE
|
||||||
% This is almost identical to `emqx_topic:words/1`, but it doesn't convert empty
|
% This is almost identical to `emqx_topic:words/1`, but it doesn't convert empty
|
||||||
% tokens to ''. This is needed to keep ordering of words consistent with what
|
% tokens to ''. This is needed to keep ordering of words consistent with what
|
||||||
% `match_filter/3` expects.
|
% `match_filter/3` expects.
|
||||||
[word(W) || W <- emqx_topic:tokens(Topic)].
|
[word(W, filter) || W <- emqx_topic:tokens(Topic)].
|
||||||
|
|
||||||
-spec word(binary()) -> word().
|
topic_words(Topic) when is_binary(Topic) ->
|
||||||
word(<<"+">>) -> '+';
|
[word(W, topic) || W <- emqx_topic:tokens(Topic)].
|
||||||
word(<<"#">>) -> '#';
|
|
||||||
word(Bin) -> Bin.
|
word(<<"+">>, topic) -> error(badarg);
|
||||||
|
word(<<"#">>, topic) -> error(badarg);
|
||||||
|
word(<<"+">>, filter) -> '+';
|
||||||
|
word(<<"#">>, filter) -> '#';
|
||||||
|
word(Bin, _) -> Bin.
|
||||||
|
|
||||||
%% match non-wildcard topics
|
%% match non-wildcard topics
|
||||||
match_topics(Topic, {Topic, _} = Key, NextF, Acc) ->
|
match_topics(Topic, {Topic, _} = Key, NextF, Acc) ->
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% Copyright (c) 2023 EMQ Technologies Co., Ltd. All Rights Reserved.
|
||||||
|
%%
|
||||||
|
%% Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
%% you may not use this file except in compliance with the License.
|
||||||
|
%% You may obtain a copy of the License at
|
||||||
|
%%
|
||||||
|
%% http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
%%
|
||||||
|
%% Unless required by applicable law or agreed to in writing, software
|
||||||
|
%% distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
%% See the License for the specific language governing permissions and
|
||||||
|
%% limitations under the License.
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
-module(emqx_trie_search_tests).
|
||||||
|
|
||||||
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
|
||||||
|
topic_validation_test() ->
|
||||||
|
NextF = fun(_) -> '$end_of_table' end,
|
||||||
|
Call = fun(Topic) ->
|
||||||
|
emqx_trie_search:match(Topic, NextF)
|
||||||
|
end,
|
||||||
|
?assertError(badarg, Call(<<"+">>)),
|
||||||
|
?assertError(badarg, Call(<<"#">>)),
|
||||||
|
?assertError(badarg, Call(<<"a/+/b">>)),
|
||||||
|
?assertError(badarg, Call(<<"a/b/#">>)),
|
||||||
|
?assertEqual(false, Call(<<"a/b/b+">>)),
|
||||||
|
?assertEqual(false, Call(<<"a/b/c#">>)),
|
||||||
|
ok.
|
Loading…
Reference in New Issue