|
|
@@ -24,8 +24,7 @@
|
|
|
%% API functions
|
|
|
-export([ start_link/0
|
|
|
, add_handler/2
|
|
|
- , update_config/2
|
|
|
- , get_raw_config/0
|
|
|
+ , update_config/3
|
|
|
, merge_to_old_config/2
|
|
|
]).
|
|
|
|
|
|
@@ -43,60 +42,49 @@
|
|
|
|
|
|
-define(MOD, {mod}).
|
|
|
|
|
|
--type update_request() :: term().
|
|
|
--type raw_config() :: hocon:config() | undefined.
|
|
|
--type config_key() :: atom().
|
|
|
-type handler_name() :: module().
|
|
|
--type config_key_path() :: [atom()].
|
|
|
--type handlers() :: #{config_key() => handlers(), ?MOD => handler_name()}.
|
|
|
+-type handlers() :: #{emqx_config:config_key() => handlers(), ?MOD => handler_name()}.
|
|
|
|
|
|
-optional_callbacks([handle_update_config/2]).
|
|
|
|
|
|
--callback handle_update_config(update_request(), raw_config()) -> update_request().
|
|
|
+-callback handle_update_config(emqx_config:update_request(), emqx_config:raw_config()) ->
|
|
|
+ emqx_config:update_request().
|
|
|
|
|
|
-type state() :: #{
|
|
|
handlers := handlers(),
|
|
|
- raw_config := raw_config(),
|
|
|
atom() => term()
|
|
|
}.
|
|
|
|
|
|
start_link() ->
|
|
|
gen_server:start_link({local, ?MODULE}, ?MODULE, {}, []).
|
|
|
|
|
|
--spec update_config(config_key_path(), update_request()) -> ok | {error, term()}.
|
|
|
-update_config(ConfKeyPath, UpdateReq) ->
|
|
|
- gen_server:call(?MODULE, {update_config, ConfKeyPath, UpdateReq}).
|
|
|
+-spec update_config(emqx_config:config_key_path(), emqx_config:update_request(),
|
|
|
+ emqx_config:raw_config()) ->
|
|
|
+ ok | {error, term()}.
|
|
|
+update_config(ConfKeyPath, UpdateReq, RawConfig) ->
|
|
|
+ gen_server:call(?MODULE, {update_config, ConfKeyPath, UpdateReq, RawConfig}).
|
|
|
|
|
|
--spec add_handler(config_key_path(), handler_name()) -> ok.
|
|
|
+-spec add_handler(emqx_config:config_key_path(), handler_name()) -> ok.
|
|
|
add_handler(ConfKeyPath, HandlerName) ->
|
|
|
gen_server:call(?MODULE, {add_child, ConfKeyPath, HandlerName}).
|
|
|
|
|
|
--spec get_raw_config() -> raw_config().
|
|
|
-get_raw_config() ->
|
|
|
- gen_server:call(?MODULE, get_raw_config).
|
|
|
-
|
|
|
%%============================================================================
|
|
|
|
|
|
-spec init(term()) -> {ok, state()}.
|
|
|
init(_) ->
|
|
|
{ok, RawConf} = hocon:load(emqx_conf_name(), #{format => richmap}),
|
|
|
{_MappedEnvs, Conf} = hocon_schema:map_translate(emqx_schema, RawConf, #{}),
|
|
|
- ok = save_config_to_emqx_config(hocon_schema:richmap_to_map(Conf)),
|
|
|
- {ok, #{raw_config => hocon_schema:richmap_to_map(RawConf),
|
|
|
- handlers => #{?MOD => ?MODULE}}}.
|
|
|
-
|
|
|
-handle_call(get_raw_config, _From, State = #{raw_config := RawConf}) ->
|
|
|
- {reply, RawConf, State};
|
|
|
-
|
|
|
+ ok = save_config_to_emqx(to_plainmap(Conf), to_plainmap(RawConf)),
|
|
|
+ {ok, #{handlers => #{?MOD => ?MODULE}}}.
|
|
|
handle_call({add_child, ConfKeyPath, HandlerName}, _From,
|
|
|
State = #{handlers := Handlers}) ->
|
|
|
{reply, ok, State#{handlers =>
|
|
|
emqx_config:deep_put(ConfKeyPath, Handlers, #{?MOD => HandlerName})}};
|
|
|
|
|
|
-handle_call({update_config, ConfKeyPath, UpdateReq}, _From,
|
|
|
- #{raw_config := RawConf, handlers := Handlers} = State) ->
|
|
|
+handle_call({update_config, ConfKeyPath, UpdateReq, RawConf}, _From,
|
|
|
+ #{handlers := Handlers} = State) ->
|
|
|
try {RootKeys, Conf} = do_update_config(ConfKeyPath, Handlers, RawConf, UpdateReq),
|
|
|
- {reply, save_configs(RootKeys, Conf), State#{raw_config => Conf}}
|
|
|
+ {reply, save_configs(RootKeys, Conf), State}
|
|
|
catch
|
|
|
throw: Reason ->
|
|
|
{reply, {error, Reason}, State};
|
|
|
@@ -158,21 +146,22 @@ merge_to_old_config(UpdateReq, RawConf) ->
|
|
|
maps:merge(RawConf, UpdateReq).
|
|
|
|
|
|
%%============================================================================
|
|
|
-save_configs(RootKeys, Conf0) ->
|
|
|
- {_MappedEnvs, Conf1} = hocon_schema:map_translate(emqx_schema, to_richmap(Conf0), #{}),
|
|
|
- %save_config_to_app_env(MappedEnvs),
|
|
|
- save_config_to_emqx_config(hocon_schema:richmap_to_map(Conf1)),
|
|
|
- save_config_to_disk(RootKeys, Conf0).
|
|
|
-
|
|
|
-%% We may need also support hot config update for the apps that use application envs.
|
|
|
-%% If so uncomment the following lines to update the configs to application env
|
|
|
+save_configs(RootKeys, RawConf) ->
|
|
|
+ {_MappedEnvs, Conf} = hocon_schema:map_translate(emqx_schema, to_richmap(RawConf), #{}),
|
|
|
+ %% We may need also support hot config update for the apps that use application envs.
|
|
|
+ %% If so uncomment the following line to update the configs to application env
|
|
|
+ %save_config_to_app_env(_MappedEnvs),
|
|
|
+ save_config_to_emqx(to_plainmap(Conf), RawConf),
|
|
|
+ save_config_to_disk(RootKeys, RawConf).
|
|
|
+
|
|
|
% save_config_to_app_env(MappedEnvs) ->
|
|
|
% lists:foreach(fun({AppName, Envs}) ->
|
|
|
% [application:set_env(AppName, Par, Val) || {Par, Val} <- Envs]
|
|
|
% end, MappedEnvs).
|
|
|
|
|
|
-save_config_to_emqx_config(Conf) ->
|
|
|
- emqx_config:put(emqx_config:unsafe_atom_key_map(Conf)).
|
|
|
+save_config_to_emqx(Conf, RawConf) ->
|
|
|
+ emqx_config:put(emqx_config:unsafe_atom_key_map(Conf)),
|
|
|
+ emqx_config:put_raw(RawConf).
|
|
|
|
|
|
save_config_to_disk(RootKeys, Conf) ->
|
|
|
FileName = emqx_override_conf_name(),
|
|
|
@@ -215,6 +204,9 @@ to_richmap(Map) ->
|
|
|
{ok, RichMap} = hocon:binary(jsx:encode(Map), #{format => richmap}),
|
|
|
RichMap.
|
|
|
|
|
|
+to_plainmap(RichMap) ->
|
|
|
+ hocon_schema:richmap_to_map(RichMap).
|
|
|
+
|
|
|
bin(A) when is_atom(A) -> list_to_binary(atom_to_list(A));
|
|
|
bin(B) when is_binary(B) -> B;
|
|
|
bin(S) when is_list(S) -> list_to_binary(S).
|