From c2b1571134f99bd780114d5abcc770a170dfd767 Mon Sep 17 00:00:00 2001 From: firest Date: Mon, 21 Mar 2022 18:32:42 +0800 Subject: [PATCH] fix(auto_subscribe): make log if the topic is empty when auto subscribe --- .../src/emqx_mod_subscription.erl | 57 ++++++++++++++----- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/lib-ce/emqx_modules/src/emqx_mod_subscription.erl b/lib-ce/emqx_modules/src/emqx_mod_subscription.erl index 06178aee7..76b4b1ac9 100644 --- a/lib-ce/emqx_modules/src/emqx_mod_subscription.erl +++ b/lib-ce/emqx_modules/src/emqx_mod_subscription.erl @@ -20,6 +20,7 @@ -include_lib("emqx/include/emqx.hrl"). -include_lib("emqx/include/emqx_mqtt.hrl"). +-include_lib("emqx/include/logger.hrl"). %% emqx_gen_mod callbacks -export([ load/1 @@ -38,14 +39,29 @@ load(Topics) -> emqx_hooks:add('client.connected', {?MODULE, on_client_connected, [Topics]}). on_client_connected(#{clientid := ClientId, username := Username}, _ConnInfo = #{proto_ver := ProtoVer}, Topics) -> - Replace = fun(Topic) -> - rep(<<"%u">>, Username, rep(<<"%c">>, ClientId, Topic)) + + OptFun = case ProtoVer of + ?MQTT_PROTO_V5 -> fun(X) -> X end; + _ -> fun(#{qos := Qos}) -> #{qos => Qos} end end, - TopicFilters = case ProtoVer of - ?MQTT_PROTO_V5 -> [{Replace(Topic), SubOpts} || {Topic, SubOpts} <- Topics]; - _ -> [{Replace(Topic), #{qos => Qos}} || {Topic, #{qos := Qos}} <- Topics] - end, - self() ! {subscribe, TopicFilters}. + + Fold = fun({Topic, SubOpts}, Acc) -> + case rep(Topic, ClientId, Username) of + {error, _} -> + Acc; + <<>> -> + ?LOG(warning, "Topic can't be empty when auto subscribe"), + Acc; + NewTopic -> + [{NewTopic, OptFun(SubOpts)} | Acc] + end + end, + + case lists:foldl(Fold, [], Topics) of + [] -> ok; + TopicFilters -> + self() ! {subscribe, TopicFilters} + end. unload(_) -> emqx_hooks:del('client.connected', {?MODULE, on_client_connected}). @@ -56,10 +72,25 @@ description() -> %% Internal functions %%-------------------------------------------------------------------- -rep(<<"%c">>, ClientId, Topic) -> - emqx_topic:feed_var(<<"%c">>, ClientId, Topic); -rep(<<"%u">>, undefined, Topic) -> - Topic; -rep(<<"%u">>, Username, Topic) -> - emqx_topic:feed_var(<<"%u">>, Username, Topic). +rep(Topic, ClientId, Username) -> + Words = emqx_topic:words(Topic), + rep(Words, ClientId, Username, []). +rep([<<"%c">> | T], ClientId, Username, Acc) -> + rep(T, + ClientId, + Username, + [ClientId | Acc]); +rep([<<"%u">> | _], _, undefined, _) -> + ?LOG(error, "Username undefined when auto subscribe"), + {error, username_undefined}; +rep([<<"%u">> | T], ClientId, Username, Acc) -> + rep(T, + ClientId, + Username, + [Username | Acc]); +rep([H | T], ClientId, UserName, Acc) -> + rep(T, ClientId, UserName, [H | Acc]); + +rep([], _, _, Acc) -> + emqx_topic:join(lists:reverse(Acc)).