From 30c2a76dae6231c0a2728e6ad82fa20d35919d9f Mon Sep 17 00:00:00 2001 From: Shawn <506895667@qq.com> Date: Mon, 5 Jul 2021 15:06:56 +0800 Subject: [PATCH] refactor(emqx_config): move helper funcs to emqx_map_lib --- apps/emqx/src/emqx_config.erl | 84 +++++---------------------- apps/emqx/src/emqx_config_handler.erl | 4 +- apps/emqx/src/emqx_listeners.erl | 4 +- apps/emqx/src/emqx_map_lib.erl | 75 ++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 74 deletions(-) create mode 100644 apps/emqx/src/emqx_map_lib.erl diff --git a/apps/emqx/src/emqx_config.erl b/apps/emqx/src/emqx_config.erl index 3d431f6a8..bc0289baf 100644 --- a/apps/emqx/src/emqx_config.erl +++ b/apps/emqx/src/emqx_config.erl @@ -35,43 +35,34 @@ , put_raw/2 ]). --export([ deep_get/2 - , deep_get/3 - , deep_put/3 - , safe_atom_key_map/1 - , unsafe_atom_key_map/1 - ]). - -define(CONF, ?MODULE). -define(RAW_CONF, {?MODULE, raw}). --export_type([update_request/0, raw_config/0, config_key/0, config_key_path/0]). +-export_type([update_request/0, raw_config/0]). -type update_request() :: term(). -type raw_config() :: hocon:config() | undefined. --type config_key() :: atom() | binary(). --type config_key_path() :: [config_key()]. -spec get() -> map(). get() -> persistent_term:get(?CONF, #{}). --spec get(config_key_path()) -> term(). +-spec get(emqx_map_lib:config_key_path()) -> term(). get(KeyPath) -> - deep_get(KeyPath, get()). + emqx_map_lib:deep_get(KeyPath, get()). --spec get(config_key_path(), term()) -> term(). +-spec get(emqx_map_lib:config_key_path(), term()) -> term(). get(KeyPath, Default) -> - deep_get(KeyPath, get(), Default). + emqx_map_lib:deep_get(KeyPath, get(), Default). -spec put(map()) -> ok. put(Config) -> persistent_term:put(?CONF, Config). --spec put(config_key_path(), term()) -> ok. +-spec put(emqx_map_lib:config_key_path(), term()) -> ok. put(KeyPath, Config) -> - put(deep_put(KeyPath, get(), Config)). + put(emqx_map_lib:deep_put(KeyPath, get(), Config)). --spec update_config(config_key_path(), update_request()) -> +-spec update_config(emqx_map_lib:config_key_path(), update_request()) -> ok | {error, term()}. update_config(ConfKeyPath, UpdateReq) -> emqx_config_handler:update_config(ConfKeyPath, UpdateReq, get_raw()). @@ -80,66 +71,19 @@ update_config(ConfKeyPath, UpdateReq) -> get_raw() -> persistent_term:get(?RAW_CONF, #{}). --spec get_raw(config_key_path()) -> term(). +-spec get_raw(emqx_map_lib:config_key_path()) -> term(). get_raw(KeyPath) -> - deep_get(KeyPath, get_raw()). + emqx_map_lib:deep_get(KeyPath, get_raw()). --spec get_raw(config_key_path(), term()) -> term(). +-spec get_raw(emqx_map_lib:config_key_path(), term()) -> term(). get_raw(KeyPath, Default) -> - deep_get(KeyPath, get_raw(), Default). + emqx_map_lib:deep_get(KeyPath, get_raw(), Default). -spec put_raw(map()) -> ok. put_raw(Config) -> persistent_term:put(?RAW_CONF, Config). --spec put_raw(config_key_path(), term()) -> ok. +-spec put_raw(emqx_map_lib:config_key_path(), term()) -> ok. put_raw(KeyPath, Config) -> - put_raw(deep_put(KeyPath, get_raw(), Config)). + put_raw(emqx_map_lib:deep_put(KeyPath, get_raw(), Config)). -%%----------------------------------------------------------------- --spec deep_get(config_key_path(), map()) -> term(). -deep_get(ConfKeyPath, Map) -> - do_deep_get(ConfKeyPath, Map, fun(KeyPath, Data) -> - error({not_found, KeyPath, Data}) end). - --spec deep_get(config_key_path(), map(), term()) -> term(). -deep_get(ConfKeyPath, Map, Default) -> - do_deep_get(ConfKeyPath, Map, fun(_, _) -> Default end). - --spec deep_put(config_key_path(), map(), term()) -> map(). -deep_put([], Map, Config) when is_map(Map) -> - Config; -deep_put([Key | KeyPath], Map, Config) -> - SubMap = deep_put(KeyPath, maps:get(Key, Map, #{}), Config), - Map#{Key => SubMap}. - -unsafe_atom_key_map(Map) -> - covert_keys_to_atom(Map, fun(K) -> binary_to_atom(K, utf8) end). - -safe_atom_key_map(Map) -> - covert_keys_to_atom(Map, fun(K) -> binary_to_existing_atom(K, utf8) end). - -%%--------------------------------------------------------------------------- - --spec do_deep_get(config_key_path(), map(), fun((config_key(), term()) -> any())) -> term(). -do_deep_get([], Map, _) -> - Map; -do_deep_get([Key | KeyPath], Map, OnNotFound) when is_map(Map) -> - case maps:find(Key, Map) of - {ok, SubMap} -> do_deep_get(KeyPath, SubMap, OnNotFound); - error -> OnNotFound(Key, Map) - end; -do_deep_get([Key | _KeyPath], Data, OnNotFound) -> - OnNotFound(Key, Data). - -covert_keys_to_atom(BinKeyMap, Conv) when is_map(BinKeyMap) -> - maps:fold( - fun(K, V, Acc) when is_binary(K) -> - Acc#{Conv(K) => covert_keys_to_atom(V, Conv)}; - (K, V, Acc) when is_atom(K) -> - %% richmap keys - Acc#{K => covert_keys_to_atom(V, Conv)} - end, #{}, BinKeyMap); -covert_keys_to_atom(ListV, Conv) when is_list(ListV) -> - [covert_keys_to_atom(V, Conv) || V <- ListV]; -covert_keys_to_atom(Val, _) -> Val. diff --git a/apps/emqx/src/emqx_config_handler.erl b/apps/emqx/src/emqx_config_handler.erl index 138521929..eba844829 100644 --- a/apps/emqx/src/emqx_config_handler.erl +++ b/apps/emqx/src/emqx_config_handler.erl @@ -79,7 +79,7 @@ init(_) -> handle_call({add_child, ConfKeyPath, HandlerName}, _From, State = #{handlers := Handlers}) -> {reply, ok, State#{handlers => - emqx_config:deep_put(ConfKeyPath, Handlers, #{?MOD => HandlerName})}}; + emqx_map_lib:deep_put(ConfKeyPath, Handlers, #{?MOD => HandlerName})}}; handle_call({update_config, ConfKeyPath, UpdateReq, RawConf}, _From, #{handlers := Handlers} = State) -> @@ -161,7 +161,7 @@ save_configs(RootKeys, RawConf) -> save_config_to_emqx(Conf, RawConf) -> ?LOG(debug, "set config: ~p", [Conf]), - emqx_config:put(emqx_config:unsafe_atom_key_map(Conf)), + emqx_config:put(emqx_map_lib:unsafe_atom_key_map(Conf)), emqx_config:put_raw(RawConf). save_config_to_disk(RootKeys, Conf) -> diff --git a/apps/emqx/src/emqx_listeners.erl b/apps/emqx/src/emqx_listeners.erl index f3af077e2..aa4fbe7f1 100644 --- a/apps/emqx/src/emqx_listeners.erl +++ b/apps/emqx/src/emqx_listeners.erl @@ -88,7 +88,7 @@ do_start_listener(ZoneName, ListenerName, #{type := ws, bind := ListenOn} = Opts esockd_opts(Opts0) -> Opts1 = maps:with([acceptors, max_connections, proxy_protocol, proxy_protocol_timeout], Opts0), - Opts2 = case emqx_config:deep_get([rate_limit, max_conn_rate], Opts0) of + Opts2 = case emqx_map_lib:deep_get([rate_limit, max_conn_rate], Opts0) of infinity -> Opts1; Rate -> Opts1#{max_conn_rate => Rate} end, @@ -204,4 +204,4 @@ tcp_opts(Opts) -> maps:get(tcp, Opts, #{}))). is_ssl(Opts) -> - emqx_config:deep_get([ssl, enable], Opts, false). + emqx_map_lib:deep_get([ssl, enable], Opts, false). diff --git a/apps/emqx/src/emqx_map_lib.erl b/apps/emqx/src/emqx_map_lib.erl new file mode 100644 index 000000000..b9d6ae03b --- /dev/null +++ b/apps/emqx/src/emqx_map_lib.erl @@ -0,0 +1,75 @@ +%%-------------------------------------------------------------------- +%% 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_map_lib). + +-export([ deep_get/2 + , deep_get/3 + , deep_put/3 + , safe_atom_key_map/1 + , unsafe_atom_key_map/1 + ]). + +-export_type([config_key/0, config_key_path/0]). +-type config_key() :: atom() | binary(). +-type config_key_path() :: [config_key()]. + +%%----------------------------------------------------------------- +-spec deep_get(config_key_path(), map()) -> term(). +deep_get(ConfKeyPath, Map) -> + do_deep_get(ConfKeyPath, Map, fun(KeyPath, Data) -> + error({not_found, KeyPath, Data}) end). + +-spec deep_get(config_key_path(), map(), term()) -> term(). +deep_get(ConfKeyPath, Map, Default) -> + do_deep_get(ConfKeyPath, Map, fun(_, _) -> Default end). + +-spec deep_put(config_key_path(), map(), term()) -> map(). +deep_put([], Map, Config) when is_map(Map) -> + Config; +deep_put([Key | KeyPath], Map, Config) -> + SubMap = deep_put(KeyPath, maps:get(Key, Map, #{}), Config), + Map#{Key => SubMap}. + +unsafe_atom_key_map(Map) -> + covert_keys_to_atom(Map, fun(K) -> binary_to_atom(K, utf8) end). + +safe_atom_key_map(Map) -> + covert_keys_to_atom(Map, fun(K) -> binary_to_existing_atom(K, utf8) end). + +%%--------------------------------------------------------------------------- + +-spec do_deep_get(config_key_path(), map(), fun((config_key(), term()) -> any())) -> term(). +do_deep_get([], Map, _) -> + Map; +do_deep_get([Key | KeyPath], Map, OnNotFound) when is_map(Map) -> + case maps:find(Key, Map) of + {ok, SubMap} -> do_deep_get(KeyPath, SubMap, OnNotFound); + error -> OnNotFound(Key, Map) + end; +do_deep_get([Key | _KeyPath], Data, OnNotFound) -> + OnNotFound(Key, Data). + +covert_keys_to_atom(BinKeyMap, Conv) when is_map(BinKeyMap) -> + maps:fold( + fun(K, V, Acc) when is_binary(K) -> + Acc#{Conv(K) => covert_keys_to_atom(V, Conv)}; + (K, V, Acc) when is_atom(K) -> + %% richmap keys + Acc#{K => covert_keys_to_atom(V, Conv)} + end, #{}, BinKeyMap); +covert_keys_to_atom(ListV, Conv) when is_list(ListV) -> + [covert_keys_to_atom(V, Conv) || V <- ListV]; +covert_keys_to_atom(Val, _) -> Val.