From f193671a9a09d24707c80f394bdab65caf041aca Mon Sep 17 00:00:00 2001 From: Andreas Schultz Date: Thu, 21 Jan 2021 17:20:22 +0100 Subject: [PATCH] shuffle the config loading to make it available earlier Our configuration loading and checking always had problems with when to load and apply what. This reshuffle the part to separate configuration validation and the actual application of the handler and socket config. --- src/ergw.erl | 48 +++++++++++++------------------------ src/ergw_app.erl | 6 ++--- src/ergw_config.erl | 30 +++++++++++++++++++---- src/ergw_sup.erl | 10 ++++---- test/gtp_proxy_ds_SUITE.erl | 13 +++++++--- 5 files changed, 61 insertions(+), 46 deletions(-) diff --git a/src/ergw.erl b/src/ergw.erl index 69283c50..74891246 100644 --- a/src/ergw.erl +++ b/src/ergw.erl @@ -10,17 +10,16 @@ -behavior(gen_server). %% API --export([start_link/0]). +-export([start_link/1]). -export([start_socket/1, start_ip_pool/2, connect_sx_node/2, attach_tdf/2, attach_protocol/5]). -export([handler/2]). --export([load_config/1]). -export([get_plmn_id/0, get_node_id/0, get_accept_new/0]). -export([system_info/0, system_info/1, system_info/2]). -export([i/0, i/1, i/2]). --ignore_xref([start_link/0, i/0, i/1, i/2]). +-ignore_xref([start_link/1, i/0, i/1, i/2]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, @@ -39,8 +38,8 @@ %% API %%==================================================================== -start_link() -> - gen_server:start_link(?MODULE, [], []). +start_link(Config) -> + gen_server:start_link(?MODULE, [Config], []). %% get global PLMN Id (aka MCC/MNC) get_plmn_id() -> @@ -72,29 +71,6 @@ system_info(accept_new, New) when is_boolean(New) -> system_info(Key, Value) -> error(badarg, [Key, Value]). -load_config([]) -> - ok; -load_config([{plmn_id, {MCC, MNC}} | T]) -> - true = ets:insert(?SERVER, {config, plmn_id, MCC, MNC}), - load_config(T); -load_config([{accept_new, Value} | T]) -> - true = ets:insert(?SERVER, {config, accept_new, Value}), - load_config(T); -load_config([{Key, Value} | T]) - when Key =:= path_management; - Key =:= node_selection; - Key =:= nodes; - Key =:= ip_pools; - Key =:= apns; - Key =:= charging; - Key =:= proxy_map; - Key =:= teid; - Key =:= node_id -> - ok = application:set_env(ergw, Key, Value), - load_config(T); -load_config([_ | T]) -> - load_config(T). - %% %% Initialize a new PFCP, GTPv1/v2-c or GTPv1-u socket %% @@ -222,11 +198,10 @@ i(memory, context) -> %%% gen_server callbacks %%%=================================================================== -init([]) -> +init([Config]) -> TID = ets:new(?SERVER, [ordered_set, named_table, public, {keypos, 2}, {read_concurrency, true}]), - true = ets:insert(TID, {config, plmn_id, <<"001">>, <<"01">>}), - true = ets:insert(TID, {config, accpept_new, true}), + load_config(Config), {ok, #state{tid = TID}}. handle_call(_Request, _From, State) -> @@ -248,3 +223,14 @@ code_change(_OldVsn, State, _Extra) -> %%%=================================================================== %%% Internal functions %%%=================================================================== + +load_config([]) -> + ok; +load_config([{plmn_id, {MCC, MNC}} | T]) -> + true = ets:insert(?SERVER, {config, plmn_id, MCC, MNC}), + load_config(T); +load_config([{accept_new, Value} | T]) -> + true = ets:insert(?SERVER, {config, accept_new, Value}), + load_config(T); +load_config([_ | T]) -> + load_config(T). diff --git a/src/ergw_app.erl b/src/ergw_app.erl index 4d24b9f5..640a6bf9 100644 --- a/src/ergw_app.erl +++ b/src/ergw_app.erl @@ -21,11 +21,11 @@ start(_StartType, _StartArgs) -> do([error_m || - gtp_config:init(), + Config <- ergw_config:load(), ergw_prometheus:declare(), ensure_jobs_queues(), - Pid <- ergw_sup:start_link(), - ergw_config:load_config(setup:get_all_env(ergw)), + Pid <- ergw_sup:start_link(Config), + ergw_config:apply(Config), return(Pid) ]). diff --git a/src/ergw_config.erl b/src/ergw_config.erl index b10fd2f0..69d73e9a 100644 --- a/src/ergw_config.erl +++ b/src/ergw_config.erl @@ -10,7 +10,8 @@ -compile({parse_transform, cut}). %% API --export([load_config/1, +-export([load/0, + apply/1, validate_options/4, validate_apn_name/1, check_unique_keys/2, @@ -61,9 +62,30 @@ %%% API %%%=================================================================== -load_config(Config0) -> - Config = validate_config(Config0), - ergw:load_config(Config), +load() -> + Config = validate_config(setup:get_all_env(ergw)), + load_env_config(Config), + ok = gtp_config:init(), + {ok, Config}. + +load_env_config([]) -> + ok; +load_env_config([{Key, Value} | T]) + when Key =:= path_management; + Key =:= node_selection; + Key =:= nodes; + Key =:= ip_pools; + Key =:= apns; + Key =:= charging; + Key =:= proxy_map; + Key =:= teid; + Key =:= node_id -> + ok = application:set_env(ergw, Key, Value), + load_env_config(T); +load_env_config([_ | T]) -> + load_env_config(T). + +apply(Config) -> lists:foreach(fun ergw:start_socket/1, proplists:get_value(sockets, Config)), maps:map(fun load_sx_node/2, proplists:get_value(nodes, Config)), lists:foreach(fun load_handler/1, proplists:get_value(handlers, Config)), diff --git a/src/ergw_sup.erl b/src/ergw_sup.erl index a8dcf3b5..32968b75 100644 --- a/src/ergw_sup.erl +++ b/src/ergw_sup.erl @@ -10,7 +10,7 @@ -behaviour(supervisor). %% API --export([start_link/0]). +-export([start_link/1]). %% Supervisor callbacks -export([init/1]). @@ -22,14 +22,14 @@ %% API functions %% =================================================================== -start_link() -> - supervisor:start_link({local, ?MODULE}, ?MODULE, []). +start_link(Config) -> + supervisor:start_link({local, ?MODULE}, ?MODULE, [Config]). %% =================================================================== %% Supervisor callbacks %% =================================================================== -init([]) -> +init([Config]) -> ok = ergw_node_selection_cache:init(), {ok, {{one_for_one, 5, 10}, [?CHILD(gtp_path_reg, worker, []), ?CHILD(ergw_tei_mngr, worker, []), @@ -44,5 +44,5 @@ init([]) -> ?CHILD(ergw_sx_node_mngr, worker, []), ?CHILD(gtp_proxy_ds, worker, []), ?CHILD(ergw_ip_pool_sup, supervisor, []), - ?CHILD(ergw, worker, []) + ?CHILD(ergw, worker, [Config]) ]} }. diff --git a/test/gtp_proxy_ds_SUITE.erl b/test/gtp_proxy_ds_SUITE.erl index c459807e..84278488 100644 --- a/test/gtp_proxy_ds_SUITE.erl +++ b/test/gtp_proxy_ds_SUITE.erl @@ -25,9 +25,16 @@ init_per_suite(Config) -> {[<<"apn2">>], [<<"example2">>, <<"com">>]} ]} ], - {ok, Pid} = gen_server:start(ergw, [], []), - ergw:load_config([{plmn_id, {<<"001">>, <<"01">>}}, - {proxy_map, ProxyMap}]), + Cfg = [{plmn_id, {<<"001">>, <<"01">>}}, + {proxy_map, ProxyMap}, + {sockets, []}, + {handlers, []}, + {ip_pools, #{}}, + {nodes, #{}} + ], + application:load(ergw), + [application:set_env(ergw, K, V) || {K, V} <- Cfg], + {ok, Pid} = gen_server:start(ergw, [Cfg], []), gen_server:start({local, gtp_proxy_ds_test}, gtp_proxy_ds, [], []), [{ergw, Pid}|Config].