diff --git a/apps/emqx_auto_subscribe/.gitignore b/apps/emqx_auto_subscribe/.gitignore new file mode 100644 index 000000000..f1c455451 --- /dev/null +++ b/apps/emqx_auto_subscribe/.gitignore @@ -0,0 +1,19 @@ +.rebar3 +_* +.eunit +*.o +*.beam +*.plt +*.swp +*.swo +.erlang.cookie +ebin +log +erl_crash.dump +.rebar +logs +_build +.idea +*.iml +rebar3.crashdump +*~ diff --git a/apps/emqx_auto_subscribe/LICENSE b/apps/emqx_auto_subscribe/LICENSE new file mode 100644 index 000000000..e16434416 --- /dev/null +++ b/apps/emqx_auto_subscribe/LICENSE @@ -0,0 +1,191 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + Copyright 2021, DDDHuang <904897578@qq.com>. + + 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. + diff --git a/apps/emqx_auto_subscribe/README.md b/apps/emqx_auto_subscribe/README.md new file mode 100644 index 000000000..96d368715 --- /dev/null +++ b/apps/emqx_auto_subscribe/README.md @@ -0,0 +1,9 @@ +emqx_auto_subscribe +===== + +An OTP application + +Build +----- + + $ rebar3 compile diff --git a/apps/emqx_auto_subscribe/etc/emqx_auto_subscribe.conf b/apps/emqx_auto_subscribe/etc/emqx_auto_subscribe.conf new file mode 100644 index 000000000..c91b77aa1 --- /dev/null +++ b/apps/emqx_auto_subscribe/etc/emqx_auto_subscribe.conf @@ -0,0 +1,29 @@ + +auto_subscribe { + topics = [ + # { + # topic = "/c/${clientid}", + # qos = 0 + # }, + # { + # topic = "/u/${username}", + # qos = 1 + # }, + # { + # topic = "/h/${host}", + # qos = 2 + # }, + # { + # topic = "/p/${port}", + # qos = 0 + # }, + # { + # topic = "/topic/abc", + # qos = 0 + # }, + # { + # topic = "/client/${clientid}/username/${username}/host/${host}/port/${port}", + # qos = 0 + # } + ] +} diff --git a/apps/emqx_auto_subscribe/include/emqx_auto_subscribe.hrl b/apps/emqx_auto_subscribe/include/emqx_auto_subscribe.hrl new file mode 100644 index 000000000..e69de29bb diff --git a/apps/emqx_auto_subscribe/rebar.config b/apps/emqx_auto_subscribe/rebar.config new file mode 100644 index 000000000..88793f7ba --- /dev/null +++ b/apps/emqx_auto_subscribe/rebar.config @@ -0,0 +1,6 @@ +{erl_opts, [debug_info]}. +{deps, []}. + +{shell, [ + {apps, [emqx_auto_subscribe]} +]}. diff --git a/apps/emqx_auto_subscribe/src/emqx_auto_subscribe.app.src b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe.app.src new file mode 100644 index 000000000..0d87af87a --- /dev/null +++ b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe.app.src @@ -0,0 +1,15 @@ +{application, emqx_auto_subscribe, + [{description, "An OTP application"}, + {vsn, "0.1.0"}, + {registered, []}, + {mod, {emqx_auto_subscribe_app, []}}, + {applications, + [kernel, + stdlib + ]}, + {env,[]}, + {modules, []}, + + {licenses, ["Apache 2.0"]}, + {links, []} + ]}. diff --git a/apps/emqx_auto_subscribe/src/emqx_auto_subscribe.erl b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe.erl new file mode 100644 index 000000000..b13b3760a --- /dev/null +++ b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe.erl @@ -0,0 +1,80 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2020-2021 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_auto_subscribe). + +-define(HOOK_POINT, 'client.connected'). + +-define(MAX_AUTO_SUBSCRIBE, 20). + +-export([load/0]). + +-export([ max_limit/0 + , list/0 + , update/1 + , test/1 + ]). + +%% hook callback +-export([on_client_connected/3]). + +load() -> + update_hook(). + +max_limit() -> + ?MAX_AUTO_SUBSCRIBE. + +list() -> + emqx:get_config([auto_subscribe, topics], []). + +update(Topics) -> + update_(Topics). + +test(_) -> +%% TODO: test rule with info map + ok. + +% test(Topic) when is_map(Topic) -> +% test([Topic]); + +% test(Topics) when is_list(Topics) -> +% PlaceHolders = emqx_auto_subscribe_placeholder:generate(Topics), +% ClientInfo = #{}, +% ConnInfo = #{}, +% emqx_auto_subscribe_placeholder:to_topic_table([PlaceHolders], ClientInfo, ConnInfo). + +%%-------------------------------------------------------------------- +%% hook + +on_client_connected(ClientInfo, ConnInfo, {TopicHandler, Options}) -> + TopicTables = erlang:apply(TopicHandler, handle, [ClientInfo, ConnInfo, Options]), + self() ! {subscribe, TopicTables}; +on_client_connected(_, _, _) -> + ok. + +%%-------------------------------------------------------------------- +%% internal + +update_(Topics) when length(Topics) =< ?MAX_AUTO_SUBSCRIBE -> + {ok, _} = emqx:update_config([auto_subscribe, topics], Topics), + update_hook(); +update_(_Topics) -> + {error, quota_exceeded}. + +update_hook() -> + {TopicHandler, Options} = emqx_auto_subscribe_handler:init(), + emqx_hooks:put(?HOOK_POINT, {?MODULE, on_client_connected, [{TopicHandler, Options}]}), + ok. diff --git a/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_api.erl b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_api.erl new file mode 100644 index 000000000..d55444dba --- /dev/null +++ b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_api.erl @@ -0,0 +1,64 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2020-2021 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_auto_subscribe_api). + +-behaviour(minirest_api). + +-export([api_spec/0]). + +-export([auto_subscribe/2]). + +-define(EXCEED_LIMIT, 'EXCEED_LIMIT'). + +api_spec() -> + {[auto_subscribe_api()], []}. + +schema() -> + emqx_mgmt_util:schema( + emqx_mgmt_api_configs:gen_schema( + emqx:get_raw_config([auto_subscribe, topics]))). + +auto_subscribe_api() -> + Metadata = #{ + get => #{ + description => <<"Auto subscribe list">>, + responses => #{ + <<"200">> => schema()}}, + put => #{ + description => <<"Update auto subscribe topic list">>, + 'requestBody' => schema(), + responses => #{ + <<"200">> => schema(), + <<"409">> => emqx_mgmt_util:error_schema( + <<"Auto Subscribe topics max limit">>, [?EXCEED_LIMIT])}} + }, + {"/mqtt/auto_subscribe", Metadata, auto_subscribe}. + +%%%============================================================================================== +%% api apply +auto_subscribe(get, _) -> + {200, emqx_auto_subscribe:list()}; + +auto_subscribe(put, #{body := Params}) -> + case emqx_auto_subscribe:update(Params) of + {error, quota_exceeded} -> + Message = list_to_binary(io_lib:format("Max auto subscribe topic count is ~p", + [emqx_auto_subscribe:max_limit()])), + {409, #{code => ?EXCEED_LIMIT, message => Message}}; + ok -> + {200, emqx_auto_subscribe:list()} + end. diff --git a/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_app.erl b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_app.erl new file mode 100644 index 000000000..116e35b1c --- /dev/null +++ b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_app.erl @@ -0,0 +1,30 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2020-2021 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_auto_subscribe_app). + +-behaviour(application). + +-export([start/2, stop/1]). + +start(_StartType, _StartArgs) -> + ok = emqx_auto_subscribe:load(), + emqx_auto_subscribe_sup:start_link(). + +stop(_State) -> + ok. + +%% internal functions diff --git a/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_placeholder.erl b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_placeholder.erl new file mode 100644 index 000000000..72b2509cc --- /dev/null +++ b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_placeholder.erl @@ -0,0 +1,72 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2020-2021 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_auto_subscribe_placeholder). + +-export([generate/1]). + +-export([to_topic_table/3]). + +-spec(generate(list() | map()) -> list() | map()). +generate(Topics) when is_list(Topics) -> + [generate(Topic) || Topic <- Topics]; + +generate(#{qos := Qos, topic := Topic}) when is_binary(Topic) -> + #{qos => Qos, placeholder => generate(Topic, [])}. + +-spec(to_topic_table(list(), map(), map()) -> list()). +to_topic_table(PlaceHolders, ClientInfo, ConnInfo) -> + [begin + Topic0 = to_topic(PlaceHolder, ClientInfo, ConnInfo, []), + {Topic, Opts} = emqx_topic:parse(Topic0), + {Topic, Opts#{qos => Qos}} + end || #{qos := Qos, placeholder := PlaceHolder} <- PlaceHolders]. + +%%-------------------------------------------------------------------- +%% internal + +generate(<<"">>, Result) -> + lists:reverse(Result); +generate(<<"${clientid}", Tail/binary>>, Result) -> + generate(Tail, [clientid | Result]); +generate(<<"${username}", Tail/binary>>, Result) -> + generate(Tail, [username | Result]); +generate(<<"${host}", Tail/binary>>, Result) -> + generate(Tail, [host | Result]); +generate(<<"${port}", Tail/binary>>, Result) -> + generate(Tail, [port | Result]); +generate(<>, []) -> + generate(Tail, [<>]); +generate(<>, [R | Result]) when is_binary(R) -> + generate(Tail, [<> | Result]); +generate(<>, [R | Result]) when is_atom(R) -> + generate(Tail, [<> | [R | Result]]). + +to_topic([], _, _, Res) -> + list_to_binary(lists:reverse(Res)); +to_topic([Binary | PTs], C, Co, Res) when is_binary(Binary) -> + to_topic(PTs, C, Co, [Binary | Res]); +to_topic([clientid | PTs], C = #{clientid := ClientID}, Co, Res) -> + to_topic(PTs, C, Co, [ClientID | Res]); +to_topic([username | PTs], C = #{username := undefined}, Co, Res) -> + to_topic(PTs, C, Co, [<<"undefined">> | Res]); +to_topic([username | PTs], C = #{username := Username}, Co, Res) -> + to_topic(PTs, C, Co, [Username | Res]); +to_topic([host | PTs], C, Co = #{peername := {Host, _}}, Res) -> + HostBinary = list_to_binary(inet:ntoa(Host)), + to_topic(PTs, C, Co, [HostBinary | Res]); +to_topic([port | PTs], C, Co = #{peername := {_, Port}}, Res) -> + PortBinary = integer_to_binary(Port), + to_topic(PTs, C, Co, [PortBinary | Res]). diff --git a/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_schema.erl b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_schema.erl new file mode 100644 index 000000000..3a68b59ab --- /dev/null +++ b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_schema.erl @@ -0,0 +1,34 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2020-2021 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_auto_subscribe_schema). + +-behaviour(hocon_schema). + +-include_lib("typerefl/include/types.hrl"). + +-export([ structs/0 + , fields/1]). + +structs() -> + ["auto_subscribe"]. + +fields("auto_subscribe") -> + [ {topics, hoconsc:array(hoconsc:ref(?MODULE, "topic"))}]; + +fields("topic") -> + [ {topic, emqx_schema:t(binary(), undefined, <<"">>)} + , {qos, emqx_schema:t(integer(), undefined, 0)} + ]. diff --git a/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_sup.erl b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_sup.erl new file mode 100644 index 000000000..9e35f825f --- /dev/null +++ b/apps/emqx_auto_subscribe/src/emqx_auto_subscribe_sup.erl @@ -0,0 +1,37 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2020-2021 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_auto_subscribe_sup). + +-behaviour(supervisor). + +-export([start_link/0]). + +-export([init/1]). + +-define(SERVER, ?MODULE). + +start_link() -> + supervisor:start_link({local, ?SERVER}, ?MODULE, []). + +init([]) -> + SupFlags = #{strategy => one_for_all, + intensity => 0, + period => 1}, + ChildSpecs = [], + {ok, {SupFlags, ChildSpecs}}. + +%% internal functions diff --git a/apps/emqx_auto_subscribe/src/topics_handler/emqx_auto_subscribe_handler.erl b/apps/emqx_auto_subscribe/src/topics_handler/emqx_auto_subscribe_handler.erl new file mode 100644 index 000000000..11865153a --- /dev/null +++ b/apps/emqx_auto_subscribe/src/topics_handler/emqx_auto_subscribe_handler.erl @@ -0,0 +1,29 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2020-2021 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_auto_subscribe_handler). + +-export([init/0]). + +-spec(init() -> {Module :: atom(), Config :: term()}). +init() -> + do_init(emqx:get_config([auto_subscribe], #{})). + +do_init(Config = #{topics := _Topics}) -> + Options = emqx_auto_subscribe_internal:init(Config), + {emqx_auto_subscribe_internal, Options}; + +do_init(_) -> + erlang:error("only support in EMQ X Enterprise"). diff --git a/apps/emqx_auto_subscribe/src/topics_handler/emqx_auto_subscribe_internal.erl b/apps/emqx_auto_subscribe/src/topics_handler/emqx_auto_subscribe_internal.erl new file mode 100644 index 000000000..f3cd58980 --- /dev/null +++ b/apps/emqx_auto_subscribe/src/topics_handler/emqx_auto_subscribe_internal.erl @@ -0,0 +1,29 @@ +%%-------------------------------------------------------------------- +%% Copyright (c) 2020-2021 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_auto_subscribe_internal). + +-export([init/1]). + +-export([handle/3]). + +-spec(init(Config :: map()) -> HandlerOptions :: term()). +init(#{topics := Topics}) -> + emqx_auto_subscribe_placeholder:generate(Topics). + +-spec(handle(ClientInfo :: map(), ConnInfo :: map(), HandlerOptions :: term()) -> + TopicTables :: list()). +handle(ClientInfo, ConnInfo, PlaceHolders) -> + emqx_auto_subscribe_placeholder:to_topic_table(PlaceHolders, ClientInfo, ConnInfo). diff --git a/apps/emqx_machine/src/emqx_machine_schema.erl b/apps/emqx_machine/src/emqx_machine_schema.erl index 0d1e9b176..38ed98898 100644 --- a/apps/emqx_machine/src/emqx_machine_schema.erl +++ b/apps/emqx_machine/src/emqx_machine_schema.erl @@ -48,6 +48,7 @@ , emqx_statsd_schema , emqx_authn_schema , emqx_authz_schema + , emqx_auto_subscribe_schema , emqx_bridge_mqtt_schema , emqx_modules_schema , emqx_management_schema diff --git a/rebar.config.erl b/rebar.config.erl index eee5d69b1..3a189dba0 100644 --- a/rebar.config.erl +++ b/rebar.config.erl @@ -267,6 +267,7 @@ relx_apps(ReleaseType) -> , emqx_connector , emqx_authn , emqx_authz + , emqx_auto_subscribe , emqx_gateway , emqx_exhook , emqx_data_bridge