Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
chrzaszcz committed Aug 10, 2023
1 parent 2667580 commit 94ecf32
Show file tree
Hide file tree
Showing 31 changed files with 224 additions and 258 deletions.
94 changes: 34 additions & 60 deletions src/config/mongoose_config.erl
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@
get_opt/1]).

%% Test API, do not use outside of test suites, options set here are not cleaned up by stop/0
-export([set_opt/2,
-export([set_opts/1,
get_opts/0,
erase_opts/0,
set_opt/2,
unset_opt/1]).

%% Shell utilities intended for debugging and system inspection
-export([config_state/0,
config_states/0]).

-ignore_xref([set_opt/2, unset_opt/1, config_state/0, config_states/0]).
-ignore_xref([set_opts/1, get_opts/0, erase_opts/0, set_opt/2, unset_opt/1]).

-include("mongoose.hrl").

Expand All @@ -34,16 +33,14 @@
-spec start() -> ok.
start() ->
Path = get_config_path(),
State = mongoose_config_parser:parse_file(Path),
persistent_term:put(mongoose_config_state, State),
set_opts(State).
Opts = mongoose_config_parser:parse_file(Path),
persistent_term:put(?MODULE, maps:from_list(Opts)).

-spec stop() -> ok | {error, not_started}.
stop() ->
try persistent_term:get(mongoose_config_state) of
State ->
unset_opts(State),
persistent_term:erase(mongoose_config_state),
try persistent_term:get(?MODULE) of
_Opts ->
persistent_term:erase(?MODULE),
ok
catch
_:_ ->
Expand All @@ -62,40 +59,40 @@ get_config_path() ->
end,
application:get_env(mongooseim, config, DefaultPath).

-spec set_opts(mongoose_config_parser:state()) -> ok.
set_opts(State) ->
Opts = mongoose_config_parser:get_opts(State),
lists:foreach(fun({Key, Value}) -> set_opt(Key, Value) end, Opts).
-spec set_opts(#{key() => value()}) -> ok.
set_opts(Opts) ->
persistent_term:put(?MODULE, Opts).

-spec get_opts() -> #{key() => value()}.
get_opts() ->
persistent_term:get(?MODULE).

-spec unset_opts(mongoose_config_parser:state()) -> ok.
unset_opts(State) ->
Opts = mongoose_config_parser:get_opts(State),
lists:foreach(fun unset_opt/1, proplists:get_keys(Opts)).
-spec erase_opts() -> boolean().
erase_opts() ->
persistent_term:erase(?MODULE).

-spec set_opt(key() | key_path(), value()) -> ok.
set_opt([Key], Value) ->
set_opt(Key, Value);
set_opt([Key | Rest], Value) ->
set_opt(Key, set_nested_opt(get_opt(Key), Rest, Value));
set_opt(KeyPath, Value) when is_list(KeyPath) ->
Opts = persistent_term:get(?MODULE),
NewOpts = set_nested_opt(Opts, KeyPath, Value),
persistent_term:put(?MODULE, NewOpts);
set_opt(Key, Value) ->
persistent_term:put({?MODULE, Key}, Value).
set_opt([Key], Value).

-spec unset_opt(key() | key_path()) -> ok.
unset_opt([Key]) ->
unset_opt(Key);
unset_opt([Key | Rest]) ->
set_opt(Key, unset_nested_opt(get_opt(Key), Rest));
unset_opt(KeyPath) when is_list(KeyPath) ->
Opts = persistent_term:get(?MODULE),
NewOpts = unset_nested_opt(Opts, KeyPath),
persistent_term:put(?MODULE, NewOpts);
unset_opt(Key) ->
persistent_term:erase({?MODULE, Key}),
ok.
unset_opt([Key]).

%% @doc Use instead of get_opt(Key, undefined)
-spec lookup_opt(key() | key_path()) -> {ok, value()} | {error, not_found}.
lookup_opt(Key) ->
try get_opt(Key) of
Value -> {ok, Value}
catch
error:badarg -> {error, not_found}; % missing persistent term
error:{badkey, _} -> {error, not_found} % missing map key
end.

Expand All @@ -105,39 +102,16 @@ get_opt(Key, Default) ->
try
get_opt(Key)
catch
error:badarg -> Default; % missing persistent term
error:{badkey, _} -> Default % missing map key
end.

%% @doc Fails if the option does not exist
-spec get_opt(key() | key_path()) -> value().
get_opt([Key | Rest]) ->
Config = persistent_term:get({?MODULE, Key}),
lists:foldl(fun maps:get/2, Config, Rest);
get_opt(KeyPath) when is_list(KeyPath) ->
Opts = persistent_term:get(?MODULE),
lists:foldl(fun maps:get/2, Opts, KeyPath);
get_opt(Key) ->
persistent_term:get({?MODULE, Key}).

-spec config_state() -> mongoose_config_parser:state().
config_state() ->
persistent_term:get(mongoose_config_state).

-spec config_states() -> [mongoose_config_parser:state()].
config_states() ->
config_states(mongoose_cluster:all_cluster_nodes()).

-spec config_states([node()]) -> [mongoose_config_parser:state()].
%% @doc Returns config states from all nodes in cluster
%% State from the local node comes as head of a list
config_states(Nodes) ->
{States, FailedNodes} = rpc:multicall(Nodes, ?MODULE, config_state, [], 30000),
case FailedNodes of
[] ->
States;
[_|_] ->
erlang:error(#{issue => config_state_failed,
cluster_nodes => Nodes,
failed_nodes => FailedNodes})
end.
get_opt([Key]).

%% Internal functions

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

%% state API
-export([build_state/3, get_opts/1]).
-export([build_state/3]).

%% only for tests
-export([get_opts/1]).

-ignore_xref([get_opts/1]).

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

Expand All @@ -25,11 +30,12 @@

%% Parser API

-spec parse_file(FileName :: string()) -> state().
-spec parse_file(FileName :: string()) -> opts().
parse_file(FileName) ->
ParserModule = parser_module(filename:extension(FileName)),
try
ParserModule:parse_file(FileName)
try ParserModule:parse_file(FileName) of
State ->
get_opts(State)
catch
error:{config_error, ExitMsg, Errors} ->
halt_with_msg(ExitMsg, Errors)
Expand Down
2 changes: 1 addition & 1 deletion src/pubsub/mod_pubsub.erl
Original file line number Diff line number Diff line change
Expand Up @@ -4034,7 +4034,7 @@ host_to_host_type(Host) ->
-spec tree(HostType :: mongooseim:host_type() | host()) -> module() | nodetree_virtual.
tree(HostType) ->
try gen_mod:get_module_opt(HostType, ?MODULE, nodetree)
catch error:badarg ->
catch error:{badkey, _} ->
%todo remove when pubsub supports dynamic domains
HT = host_to_host_type(HostType),
gen_mod:get_module_opt(HT, ?MODULE, nodetree)
Expand Down
7 changes: 2 additions & 5 deletions test/acl_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,11 @@ end_per_group(_Group, Config) ->
Config.

init_per_testcase(_TC, Config) ->
mongoose_config:set_opts(#{}),
Config.

end_per_testcase(_TC, _Config) ->
clean_config().
mongoose_config:erase_opts().

host_type() ->
<<"test host type">>.
Expand Down Expand Up @@ -287,10 +288,6 @@ different_specs_matching_the_same_user(Config) ->
acl(Spec) ->
[maps:merge(#{match => current_domain}, Spec)].

clean_config() ->
[persistent_term:erase(Key) || {Key = {mongoose_config, _}, _Value} <- persistent_term:get()],
ok.

given_registered_domains(Config, DomainsList) ->
case proplists:get_value(dynamic_domains, Config, false) of
true ->
Expand Down
8 changes: 4 additions & 4 deletions test/auth_dummy_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@ all() -> [

init_per_suite(C) ->
{ok, _} = application:ensure_all_started(jid),
mongoose_config:set_opt({auth, ?HOST_TYPE}, #{methods => [dummy],
dummy => #{base_time => 5,
variance => 10}}),
AuthOpts = #{methods => [dummy],
dummy => #{base_time => 5, variance => 10}},
mongoose_config:set_opts(#{{auth, ?HOST_TYPE} => AuthOpts}),
C.

end_per_suite(_C) ->
mongoose_config:unset_opt({auth, ?HOST_TYPE}).
mongoose_config:erase_opts().

%%--------------------------------------------------------------------
%% Authentication tests
Expand Down
8 changes: 4 additions & 4 deletions test/auth_external_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,12 @@ given_user_registered() ->

set_opts(Config) ->
DataDir = ?config(data_dir, Config),
mongoose_config:set_opt({auth, ?HOST_TYPE},
#{external => #{program => DataDir ++ "sample_external_auth.py",
instances => 1}}).
mongoose_config:set_opts(#{{auth, ?HOST_TYPE} =>
#{external => #{program => DataDir ++ "sample_external_auth.py",
instances => 1}}}).

unset_opts() ->
mongoose_config:unset_opt({auth, ?HOST_TYPE}).
mongoose_config:erase_opts().

gen_user() ->
U = random_binary(5),
Expand Down
10 changes: 5 additions & 5 deletions test/auth_http_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -244,13 +244,13 @@ set_opts(Config) ->
_ -> scram
end,
HttpOpts = #{basic_auth => ?BASIC_AUTH},
mongoose_config:set_opt({auth, ?HOST_TYPE}, #{methods => [http],
password => #{format => PasswordFormat,
scram_iterations => 10},
http => HttpOpts}).
mongoose_config:set_opts(#{{auth, ?HOST_TYPE} => #{methods => [http],
password => #{format => PasswordFormat,
scram_iterations => 10},
http => HttpOpts}}).

unset_opts() ->
mongoose_config:unset_opt({auth, ?HOST_TYPE}).
mongoose_config:erase_opts().

do_scram(Pass, Config) ->
case lists:keyfind(scram_group, 1, Config) of
Expand Down
10 changes: 5 additions & 5 deletions test/auth_internal_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ init_per_suite(C) ->
application:ensure_all_started(jid),
ok = mnesia:create_schema([node()]),
ok = mnesia:start(),
mongoose_config:set_opt({auth, host_type()}, #{methods => [internal],
internal => #{},
password => #{format => scram,
scram_iterations => 10}}),
AuthOpts = #{methods => [internal],
internal => #{},
password => #{format => scram, scram_iterations => 10}},
mongoose_config:set_opts(#{{auth, host_type()} => AuthOpts}),
ejabberd_auth_internal:start(host_type()),
C.

end_per_suite(_C) ->
ejabberd_auth_internal:stop(host_type()),
mongoose_config:unset_opt({auth, host_type()}),
mongoose_config:erase_opts(),
mnesia:stop(),
mnesia:delete_schema([node()]).

Expand Down
8 changes: 4 additions & 4 deletions test/auth_jwt_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,12 @@ check_password_succeeds_for_pubkey_signed_token(C) ->
%%--------------------------------------------------------------------

set_auth_opts(Secret, Algorithm, Key) ->
mongoose_config:set_opt({auth, ?HOST_TYPE}, #{jwt => #{secret => Secret,
algorithm => Algorithm,
username_key => Key}}).
mongoose_config:set_opts(#{{auth, ?HOST_TYPE} => #{jwt => #{secret => Secret,
algorithm => Algorithm,
username_key => Key}}}).

unset_auth_opts() ->
mongoose_config:unset_opt({auth, ?HOST_TYPE}).
mongoose_config:erase_opts().

generate_token(Alg, NbfDelta, Key) ->
Now = erlang:system_time(second),
Expand Down
11 changes: 6 additions & 5 deletions test/auth_tokens_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,14 @@ groups() ->

init_per_suite(C) ->
{ok, _} = application:ensure_all_started(jid),
mongoose_config:set_opt({modules, host_type()},
#{?TESTED => config_parser_helper:default_mod_config(?TESTED)}),
mongoose_config:set_opts(opts()),
C.

end_per_suite(C) ->
mongoose_config:unset_opt({modules, host_type()}),
C.
end_per_suite(_C) ->
mongoose_config:erase_opts().

opts() ->
#{{modules, host_type()} => #{?TESTED => config_parser_helper:default_mod_config(?TESTED)}}.

init_per_testcase(Test, Config)
when Test =:= serialize_deserialize_property;
Expand Down
11 changes: 5 additions & 6 deletions test/component_reg_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ init_per_suite(C) ->
{ok, _} = application:ensure_all_started(jid),
ok = mnesia:create_schema([node()]),
ok = mnesia:start(),
[mongoose_config:set_opt(Key, Value) || {Key, Value} <- opts()],
mongoose_config:set_opts(opts()),
meck:new(mongoose_domain_api, [no_link]),
meck:expect(mongoose_domain_api, get_host_type,
fun(_) -> {error, not_found} end),
Expand All @@ -31,13 +31,12 @@ end_per_suite(_C) ->
mnesia:stop(),
mnesia:delete_schema([node()]),
meck:unload(),
[mongoose_config:unset_opt(Key) || {Key, _Value} <- opts()],
ok.
mongoose_config:erase_opts().

opts() ->
[{all_metrics_are_global, false},
{component_backend, mnesia},
{routing_modules, [xmpp_router_a, xmpp_router_b, xmpp_router_c]}].
#{all_metrics_are_global => false,
component_backend => mnesia,
routing_modules => [xmpp_router_a, xmpp_router_b, xmpp_router_c]}.

registering(_C) ->
Dom = <<"aaa.bbb.com">>,
Expand Down
3 changes: 1 addition & 2 deletions test/config_parser_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -3040,8 +3040,7 @@ test_config_file(Config, File) ->
ExpectedOpts = config_parser_helper:options(File),

TOMLPath = ejabberd_helper:data(Config, File ++ ".toml"),
State = mongoose_config_parser:parse_file(TOMLPath),
TOMLOpts = mongoose_config_parser:get_opts(State),
TOMLOpts = mongoose_config_parser:parse_file(TOMLPath),

%% Save the parsed TOML options
%% - for debugging
Expand Down
18 changes: 6 additions & 12 deletions test/ejabberd_sm_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ end_per_testcase(_, Config) ->
clean_sessions(Config),
terminate_sm(),
unload_meck(),
unset_opts(Config).
mongoose_config:erase_opts().

open_session(C) ->
{Sid, USR} = generate_random_user(<<"localhost">>),
Expand Down Expand Up @@ -610,7 +610,7 @@ is_redis_running() ->
end.

setup_sm(Config) ->
set_opts(Config),
mongoose_config:set_opts(opts(Config)),
set_meck(),
ejabberd_sm:start_link(),
case ?config(backend, Config) of
Expand All @@ -625,17 +625,11 @@ setup_sm(Config) ->
terminate_sm() ->
gen_server:stop(ejabberd_sm).

set_opts(Config) ->
[mongoose_config:set_opt(Key, Value) || {Key, Value} <- opts(Config)].

unset_opts(Config) ->
[mongoose_config:unset_opt(Key) || {Key, _Value} <- opts(Config)].

opts(Config) ->
[{hosts, [<<"localhost">>]},
{host_types, []},
{all_metrics_are_global, false},
{sm_backend, sm_backend(?config(backend, Config))}].
#{hosts => [<<"localhost">>],
host_types => [],
all_metrics_are_global => false,
sm_backend => sm_backend(?config(backend, Config))}.

sm_backend(ejabberd_sm_redis) -> redis;
sm_backend(ejabberd_sm_mnesia) -> mnesia;
Expand Down
Loading

0 comments on commit 94ecf32

Please sign in to comment.