Skip to content

Commit

Permalink
Merge pull request #3620 from esl/services-map
Browse files Browse the repository at this point in the history
Service management rework
  • Loading branch information
Premwoik authored Apr 4, 2022
2 parents c9c8717 + 1a7a30d commit 6fcb515
Show file tree
Hide file tree
Showing 16 changed files with 394 additions and 439 deletions.
8 changes: 4 additions & 4 deletions big_tests/tests/service_domain_db_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -1054,11 +1054,11 @@ service_enabled(Node) ->
sync_local(Node).

service_enabled(Node, Opts) ->
rpc(Node, mongoose_service, start_service, [service_domain_db, Opts]),
rpc(Node, mongoose_service, ensure_started, [service_domain_db, Opts]),
true = rpc(Node, service_domain_db, enabled, []).

service_disabled(Node) ->
rpc(Node, mongoose_service, stop_service, [service_domain_db]),
rpc(Node, mongoose_service, ensure_stopped, [service_domain_db]),
false = rpc(Node, service_domain_db, enabled, []).

init_with(Node, Pairs, AllowedHostTypes) ->
Expand Down Expand Up @@ -1159,12 +1159,12 @@ force_check_for_updates(Node) ->
ok = rpc(Node, service_domain_db, force_check_for_updates, []).

restore_conf(Node, #{loaded := Loaded, service_opts := ServiceOpts, core_opts := CoreOpts}) ->
rpc(Node, mongoose_service, stop_service, [service_domain_db]),
rpc(Node, mongoose_service, ensure_stopped, [service_domain_db]),
[Pairs, AllowedHostTypes] = CoreOpts,
init_with(Node, Pairs, AllowedHostTypes),
case Loaded of
true ->
rpc(Node, mongoose_service, start_service, [service_domain_db, ServiceOpts]);
rpc(Node, mongoose_service, ensure_started, [service_domain_db, ServiceOpts]);
_ ->
ok
end.
Expand Down
20 changes: 7 additions & 13 deletions big_tests/tests/service_mongoose_system_metrics_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ init_per_suite(Config) ->
end_per_suite(Config) ->
http_helper:stop(),
Args = [{initial_report, timer:seconds(20)}, {periodic_report, timer:minutes(5)}],
[start_system_metrics_module(Node, Args) || Node <- [mim(), mim2()]],
[start_system_metrics_service(Node, Args) || Node <- [mim(), mim2()]],
escalus:end_per_suite(Config).

%%--------------------------------------------------------------------
Expand Down Expand Up @@ -285,7 +285,6 @@ config_type_is_reported(_Config) ->

just_removed_from_config_logs_question(_Config) ->
disable_system_metrics(mim3()),
remove_service_from_config(service_mongoose_system_metrics),
%% WHEN
Result = distributed_helper:rpc(
mim3(), service_mongoose_system_metrics, verify_if_configured, []),
Expand All @@ -309,7 +308,7 @@ in_config_unmodified_logs_request_for_agreement(_Config) ->
in_config_with_explicit_no_report_goes_off_silently(_Config) ->
%% WHEN
logger_ct_backend:capture(warning),
start_system_metrics_module(mim(), [no_report]),
start_system_metrics_service(mim(), [{no_report, true}]),
logger_ct_backend:stop_capture(),
%% THEN
FilterFun = fun(warning, Msg) ->
Expand All @@ -323,7 +322,7 @@ in_config_with_explicit_no_report_goes_off_silently(_Config) ->
in_config_with_explicit_reporting_goes_on_silently(_Config) ->
%% WHEN
logger_ct_backend:capture(warning),
start_system_metrics_module(mim(), [report]),
start_system_metrics_service(mim(), [{report, true}]),
logger_ct_backend:stop_capture(),
%% THEN
FilterFun = fun(warning, Msg) ->
Expand Down Expand Up @@ -425,17 +424,17 @@ enable_system_metrics(Node) ->
enable_system_metrics(Node, Timers) ->
UrlArgs = [google_analytics_url, ?SERVER_URL],
ok = mongoose_helper:successful_rpc(Node, mongoose_config, set_opt, UrlArgs),
start_system_metrics_module(Node, Timers).
start_system_metrics_service(Node, Timers).

enable_system_metrics_with_configurable_tracking_id(Node) ->
enable_system_metrics(Node, [{initial_report, 100}, {periodic_report, 100}, {tracking_id, ?TRACKING_ID_EXTRA}]).

start_system_metrics_module(Node, Args) ->
start_system_metrics_service(Node, Args) ->
distributed_helper:rpc(
Node, mongoose_service, start_service, [service_mongoose_system_metrics, Args]).
Node, mongoose_service, ensure_started, [service_mongoose_system_metrics, Args]).

disable_system_metrics(Node) ->
distributed_helper:rpc(Node, mongoose_service, stop_service, [service_mongoose_system_metrics]),
distributed_helper:rpc(Node, mongoose_service, ensure_stopped, [service_mongoose_system_metrics]),
mongoose_helper:successful_rpc(Node, mongoose_config, unset_opt, [ google_analytics_url ]).

delete_prev_client_id(Node) ->
Expand All @@ -454,11 +453,6 @@ system_metrics_service_is_enabled(Node) ->
system_metrics_service_is_disabled(Node) ->
not system_metrics_service_is_enabled(Node).

remove_service_from_config(Service) ->
Services = distributed_helper:rpc(mim3(), mongoose_config, get_opt, [services]),
NewServices = proplists:delete(Service, Services),
distributed_helper:rpc(mim3(), mongoose_config, set_opt, [services, NewServices]).

events_are_reported_to_primary_tracking_id() ->
events_are_reported_to_tracking_ids([primary_tracking_id()]).

Expand Down
44 changes: 32 additions & 12 deletions src/config/mongoose_config_parser.erl
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,10 @@
-export([parse_file/1]).

%% state API
-export([new_state/0,
set_opts/2,
set_hosts/2,
set_host_types/2,
get_opts/1]).
-export([build_state/3, get_opts/1]).

%% config post-processing
-export([unfold_globals/1,
post_process_modules/1]).
-export([unfold_opts/1]).

-callback parse_file(FileName :: string()) -> state().

Expand Down Expand Up @@ -48,6 +43,17 @@ parser_module(".toml") -> mongoose_config_parser_toml.

%% State API

-spec build_state([jid:server()], [jid:server()], opts()) -> state().
build_state(Hosts, HostTypes, Opts) ->
lists:foldl(fun(F, StateIn) -> F(StateIn) end,
new_state(),
[fun(S) -> set_hosts(Hosts, S) end,
fun(S) -> set_host_types(HostTypes, S) end,
fun(S) -> set_opts(Opts, S) end,
fun unfold_globals/1,
fun post_process_services/1,
fun post_process_modules/1]).

-spec new_state() -> state().
new_state() ->
#state{}.
Expand Down Expand Up @@ -125,19 +131,33 @@ keep_global_value(acl) -> true;
keep_global_value(access) -> true;
keep_global_value(_) -> false.

-spec post_process_services(state()) -> state().
post_process_services(State = #state{opts = Opts}) ->
Opts1 = lists:map(fun post_process_services_opt/1, Opts),
State#state{opts = Opts1}.

post_process_services_opt({services, Services}) ->
ServicesWithDeps = mongoose_service_deps:resolve_deps(Services),
{services, unfold_all_opts(ServicesWithDeps)};
post_process_services_opt(Other) ->
Other.

-spec post_process_modules(state()) -> state().
post_process_modules(State = #state{opts = Opts}) ->
Opts2 = lists:map(fun post_process_modules_opt/1, Opts),
State#state{opts = Opts2}.
Opts1 = lists:map(fun post_process_modules_opt/1, Opts),
State#state{opts = Opts1}.

post_process_modules_opt({{modules, HostType}, Modules}) ->
ModulesWithDeps = gen_mod_deps:resolve_deps(HostType, Modules),
{{modules, HostType}, unfold_opts(ModulesWithDeps)};
{{modules, HostType}, unfold_all_opts(ModulesWithDeps)};
post_process_modules_opt(Other) ->
Other.

unfold_opts(Modules) ->
maps:map(fun(_Mod, Opts) -> mongoose_modules:unfold_opts(Opts) end, Modules).
unfold_all_opts(Modules) ->
maps:map(fun(_Mod, Opts) -> unfold_opts(Opts) end, Modules).

unfold_opts(Opts) when is_map(Opts) -> Opts;
unfold_opts(Opts) -> proplists:unfold(Opts).

%% local functions

Expand Down
13 changes: 1 addition & 12 deletions src/config/mongoose_config_parser_toml.erl
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ process(Content) ->
HostTypes = proplists:get_value(host_types, Config, []),
case extract_errors(Config) of
[] ->
build_state(Hosts, HostTypes, Config);
mongoose_config_parser:build_state(Hosts, HostTypes, Config);
Errors ->
error(config_error(Errors))
end.
Expand Down Expand Up @@ -305,17 +305,6 @@ item_key(_, _) -> item.

%% Processing of the parsed options

-spec build_state([jid:server()], [jid:server()], [top_level_config()]) ->
mongoose_config_parser:state().
build_state(Hosts, HostTypes, Opts) ->
lists:foldl(fun(F, StateIn) -> F(StateIn) end,
mongoose_config_parser:new_state(),
[fun(S) -> mongoose_config_parser:set_hosts(Hosts, S) end,
fun(S) -> mongoose_config_parser:set_host_types(HostTypes, S) end,
fun(S) -> mongoose_config_parser:set_opts(Opts, S) end,
fun mongoose_config_parser:unfold_globals/1,
fun mongoose_config_parser:post_process_modules/1]).

%% Any nested config_part() may be a config_error() - this function extracts them all recursively
-spec extract_errors([config()]) -> [config_error()].
extract_errors(Config) ->
Expand Down
4 changes: 3 additions & 1 deletion src/config/mongoose_config_spec.erl
Original file line number Diff line number Diff line change
Expand Up @@ -779,7 +779,9 @@ services() ->
|| Service <- configurable_services()],
#section{
items = maps:from_list(Services),
wrap = global_config
format_items = map,
wrap = global_config,
include = always
}.

configurable_services() ->
Expand Down
19 changes: 2 additions & 17 deletions src/ejabberd_app.erl
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ start(normal, _Args) ->
ejabberd_ctl:init(),
ejabberd_commands:init(),
mongoose_commands:init(),
mongoose_service:start(),
mongoose_config:start(),
mongoose_router:start(),
mongoose_logs:set_global_loglevel(mongoose_config:get_opt(loglevel)),
Expand All @@ -65,7 +64,7 @@ start(normal, _Args) ->
ejabberd_sm:start(),
ejabberd_auth:start(),
mongoose_cluster_id:start(),
start_services(),
mongoose_service:start(),
mongoose_modules:start(),
service_mongoose_system_metrics:verify_if_configured(),
mongoose_metrics:init(),
Expand All @@ -84,7 +83,7 @@ prep_stop(State) ->
mongoose_deprecations:stop(),
ejabberd_listener:stop_listeners(),
mongoose_modules:stop(),
stop_services(),
mongoose_service:stop(),
broadcast_c2s_shutdown(),
mongoose_wpool:stop(),
mongoose_metrics:remove_all_metrics(),
Expand Down Expand Up @@ -114,20 +113,6 @@ db_init() ->
end,
mnesia:wait_for_tables(mnesia:system_info(local_tables), infinity).

-spec start_services() -> ok.
start_services() ->
lists:foreach(
fun({Service, Opts}) -> mongoose_service:ensure_loaded(Service, Opts) end,
mongoose_config:get_opt(services, [])
).

-spec stop_services() -> ok.
stop_services() ->
lists:foreach(
fun({Service, _Options}) -> mongoose_service:stop_service(Service) end,
mongoose_service:loaded_services_with_opts()
).

-spec broadcast_c2s_shutdown() -> 'ok'.
broadcast_c2s_shutdown() ->
Children = supervisor:which_children(ejabberd_c2s_sup),
Expand Down
8 changes: 2 additions & 6 deletions src/mongoose_modules.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
-include("mongoose.hrl").

%% API
-export([start/0, stop/0, unfold_opts/1]).
-export([start/0, stop/0]).

%% Module management utilities for tests
-export([replace_modules/3, ensure_stopped/2, ensure_started/3]).
Expand Down Expand Up @@ -68,7 +68,7 @@ ensure_stopped(HostType, Module) ->
-spec ensure_started(mongooseim:host_type(), module(), module_opts()) ->
already_started | {started, term()} | {restarted, module_opts(), term()}.
ensure_started(HostType, Module, RawOpts) ->
Opts = unfold_opts(RawOpts),
Opts = mongoose_config_parser:unfold_opts(RawOpts),
Modules = get_modules(HostType),
case maps:find(Module, Modules) of
error ->
Expand All @@ -82,10 +82,6 @@ ensure_started(HostType, Module, RawOpts) ->
{restarted, PrevOpts, Result}
end.

-spec unfold_opts(gen_mod:module_opts()) -> gen_mod:module_opts().
unfold_opts(Opts) when is_map(Opts) -> Opts;
unfold_opts(Opts) -> proplists:unfold(Opts).

%% Helpers

-spec start_module(mongooseim:host_type(), module(), module_opts(), module_map()) -> {ok, term()}.
Expand Down
Loading

0 comments on commit 6fcb515

Please sign in to comment.