|
@@ -24,14 +24,11 @@
|
|
|
%% API functions
|
|
%% API functions
|
|
|
-export([ start_link/0
|
|
-export([ start_link/0
|
|
|
, add_handler/2
|
|
, add_handler/2
|
|
|
- , update_config/3
|
|
|
|
|
|
|
+ , update_config/2
|
|
|
|
|
+ , remove_config/1
|
|
|
, merge_to_old_config/2
|
|
, merge_to_old_config/2
|
|
|
]).
|
|
]).
|
|
|
|
|
|
|
|
-%% emqx_config_handler callbacks
|
|
|
|
|
--export([ pre_config_update/2
|
|
|
|
|
- ]).
|
|
|
|
|
-
|
|
|
|
|
%% gen_server callbacks
|
|
%% gen_server callbacks
|
|
|
-export([init/1,
|
|
-export([init/1,
|
|
|
handle_call/3,
|
|
handle_call/3,
|
|
@@ -62,11 +59,15 @@
|
|
|
start_link() ->
|
|
start_link() ->
|
|
|
gen_server:start_link({local, ?MODULE}, ?MODULE, {}, []).
|
|
gen_server:start_link({local, ?MODULE}, ?MODULE, {}, []).
|
|
|
|
|
|
|
|
--spec update_config(emqx_config:config_key_path(), emqx_config:update_request(),
|
|
|
|
|
- emqx_config:raw_config()) ->
|
|
|
|
|
|
|
+-spec update_config(emqx_config:config_key_path(), emqx_config:update_request()) ->
|
|
|
ok | {error, term()}.
|
|
ok | {error, term()}.
|
|
|
-update_config(ConfKeyPath, UpdateReq, RawConfig) ->
|
|
|
|
|
- gen_server:call(?MODULE, {update_config, ConfKeyPath, UpdateReq, RawConfig}).
|
|
|
|
|
|
|
+update_config(ConfKeyPath, UpdateReq) ->
|
|
|
|
|
+ gen_server:call(?MODULE, {update_config, ConfKeyPath, UpdateReq}).
|
|
|
|
|
+
|
|
|
|
|
+-spec remove_config(emqx_config:config_key_path()) ->
|
|
|
|
|
+ ok | {error, term()}.
|
|
|
|
|
+remove_config(ConfKeyPath) ->
|
|
|
|
|
+ gen_server:call(?MODULE, {remove_config, ConfKeyPath}).
|
|
|
|
|
|
|
|
-spec add_handler(emqx_config:config_key_path(), handler_name()) -> ok.
|
|
-spec add_handler(emqx_config:config_key_path(), handler_name()) -> ok.
|
|
|
add_handler(ConfKeyPath, HandlerName) ->
|
|
add_handler(ConfKeyPath, HandlerName) ->
|
|
@@ -83,11 +84,28 @@ handle_call({add_child, ConfKeyPath, HandlerName}, _From,
|
|
|
{reply, ok, State#{handlers =>
|
|
{reply, ok, State#{handlers =>
|
|
|
emqx_map_lib:deep_put(ConfKeyPath, Handlers, #{?MOD => HandlerName})}};
|
|
emqx_map_lib:deep_put(ConfKeyPath, Handlers, #{?MOD => HandlerName})}};
|
|
|
|
|
|
|
|
-handle_call({update_config, ConfKeyPath, UpdateReq, RawConf}, _From,
|
|
|
|
|
|
|
+handle_call({update_config, ConfKeyPath, UpdateReq}, _From,
|
|
|
#{handlers := Handlers} = State) ->
|
|
#{handlers := Handlers} = State) ->
|
|
|
OldConf = emqx_config:get(),
|
|
OldConf = emqx_config:get(),
|
|
|
- try {RootKeys, Conf} = do_update_config(ConfKeyPath, Handlers, RawConf, UpdateReq),
|
|
|
|
|
- Result = emqx_config:save_configs(Conf, #{overridden_keys => RootKeys}),
|
|
|
|
|
|
|
+ OldRawConf = emqx_config:get_raw(),
|
|
|
|
|
+ try NewRawConf = do_update_config(ConfKeyPath, Handlers, OldRawConf, UpdateReq),
|
|
|
|
|
+ OverrideConf = update_override_config(ConfKeyPath, NewRawConf),
|
|
|
|
|
+ Result = emqx_config:save_configs(NewRawConf, OverrideConf),
|
|
|
|
|
+ do_post_config_update(ConfKeyPath, Handlers, OldConf, emqx_config:get()),
|
|
|
|
|
+ {reply, Result, State}
|
|
|
|
|
+ catch
|
|
|
|
|
+ Error : Reason : ST ->
|
|
|
|
|
+ ?LOG(error, "update config failed: ~p", [{Error, Reason, ST}]),
|
|
|
|
|
+ {reply, {error, Reason}, State}
|
|
|
|
|
+ end;
|
|
|
|
|
+
|
|
|
|
|
+handle_call({remove_config, ConfKeyPath}, _From, #{handlers := Handlers} = State) ->
|
|
|
|
|
+ OldConf = emqx_config:get(),
|
|
|
|
|
+ OldRawConf = emqx_config:get_raw(),
|
|
|
|
|
+ BinKeyPath = bin_path(ConfKeyPath),
|
|
|
|
|
+ try NewRawConf = emqx_map_lib:deep_remove(BinKeyPath, OldRawConf),
|
|
|
|
|
+ OverrideConf = emqx_map_lib:deep_remove(BinKeyPath, emqx_config:read_override_conf()),
|
|
|
|
|
+ Result = emqx_config:save_configs(NewRawConf, OverrideConf),
|
|
|
do_post_config_update(ConfKeyPath, Handlers, OldConf, emqx_config:get()),
|
|
do_post_config_update(ConfKeyPath, Handlers, OldConf, emqx_config:get()),
|
|
|
{reply, Result, State}
|
|
{reply, Result, State}
|
|
|
catch
|
|
catch
|
|
@@ -148,11 +166,6 @@ call_post_config_update(Handlers, OldConf, NewConf) ->
|
|
|
false -> ok
|
|
false -> ok
|
|
|
end.
|
|
end.
|
|
|
|
|
|
|
|
-%% callbacks for the top-level handler
|
|
|
|
|
-pre_config_update(UpdateReq, OldConf) ->
|
|
|
|
|
- FullRawConf = merge_to_old_config(UpdateReq, OldConf),
|
|
|
|
|
- {maps:keys(UpdateReq), FullRawConf}.
|
|
|
|
|
-
|
|
|
|
|
%% The default callback of config handlers
|
|
%% The default callback of config handlers
|
|
|
%% the behaviour is overwriting the old config if:
|
|
%% the behaviour is overwriting the old config if:
|
|
|
%% 1. the old config is undefined
|
|
%% 1. the old config is undefined
|
|
@@ -163,6 +176,18 @@ merge_to_old_config(UpdateReq, RawConf) when is_map(UpdateReq), is_map(RawConf)
|
|
|
merge_to_old_config(UpdateReq, _RawConf) ->
|
|
merge_to_old_config(UpdateReq, _RawConf) ->
|
|
|
UpdateReq.
|
|
UpdateReq.
|
|
|
|
|
|
|
|
|
|
+update_override_config(ConfKeyPath, RawConf) ->
|
|
|
|
|
+ %% We don't save the entire config to emqx_override.conf, but only the part
|
|
|
|
|
+ %% specified by the ConfKeyPath
|
|
|
|
|
+ PartialConf = maps:with(root_keys(ConfKeyPath), RawConf),
|
|
|
|
|
+ OldConf = emqx_config:read_override_conf(),
|
|
|
|
|
+ maps:merge(OldConf, PartialConf).
|
|
|
|
|
+
|
|
|
|
|
+root_keys([]) -> [];
|
|
|
|
|
+root_keys([RootKey | _]) -> [bin(RootKey)].
|
|
|
|
|
+
|
|
|
|
|
+bin_path(ConfKeyPath) -> [bin(Key) || Key <- ConfKeyPath].
|
|
|
|
|
+
|
|
|
bin(A) when is_atom(A) -> list_to_binary(atom_to_list(A));
|
|
bin(A) when is_atom(A) -> list_to_binary(atom_to_list(A));
|
|
|
bin(B) when is_binary(B) -> B;
|
|
bin(B) when is_binary(B) -> B;
|
|
|
bin(S) when is_list(S) -> list_to_binary(S).
|
|
bin(S) when is_list(S) -> list_to_binary(S).
|