From adaf3db7198d494cad6f0f4b99cd82ff6246120b Mon Sep 17 00:00:00 2001 From: JianBo He Date: Wed, 29 Sep 2021 19:25:53 +0800 Subject: [PATCH] refactor(gw): put conf operations into emqx_gateway_conf mod --- apps/emqx_gateway/src/emqx_gateway_api.erl | 16 +-- .../src/emqx_gateway_api_listeners.erl | 4 +- apps/emqx_gateway/src/emqx_gateway_conf.erl | 98 +++++++++++++++++-- apps/emqx_gateway/src/emqx_gateway_http.erl | 76 +------------- apps/emqx_gateway/src/emqx_gateway_utils.erl | 10 ++ 5 files changed, 105 insertions(+), 99 deletions(-) diff --git a/apps/emqx_gateway/src/emqx_gateway_api.erl b/apps/emqx_gateway/src/emqx_gateway_api.erl index 26b1a30ad..a517d1b83 100644 --- a/apps/emqx_gateway/src/emqx_gateway_api.erl +++ b/apps/emqx_gateway/src/emqx_gateway_api.erl @@ -93,16 +93,13 @@ gateway_insta(delete, #{bindings := #{name := Name0}}) -> end); gateway_insta(get, #{bindings := #{name := Name0}}) -> with_gateway(Name0, fun(_, _) -> - GwConf = filled_raw_confs([<<"gateway">>, Name0]), - LisConf = maps:get(<<"listeners">>, GwConf, #{}), - NLisConf = emqx_gateway_http:mapping_listener_m2l(Name0, LisConf), - {200, GwConf#{<<"name">> => Name0, <<"listeners">> => NLisConf}} + GwConf = emqx_gateway_conf:gateway(Name0), + {200, GwConf#{<<"name">> => Name0}} end); -gateway_insta(put, #{body := GwConf0, +gateway_insta(put, #{body := GwConf, bindings := #{name := Name0} }) -> with_gateway(Name0, fun(GwName, _) -> - GwConf = maps:without([<<"authentication">>, <<"listeners">>], GwConf0), case emqx_gateway_conf:update_gateway(GwName, GwConf) of ok -> {200}; @@ -114,13 +111,6 @@ gateway_insta(put, #{body := GwConf0, gateway_insta_stats(get, _Req) -> return_http_error(401, "Implement it later (maybe 5.1)"). -filled_raw_confs(Path) -> - RawConf = emqx_config:fill_defaults( - emqx_config:get_root_raw(Path) - ), - Confs = emqx_map_lib:deep_get(Path, RawConf), - emqx_map_lib:jsonable_map(Confs). - %%-------------------------------------------------------------------- %% Swagger defines %%-------------------------------------------------------------------- diff --git a/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl b/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl index a9e16704e..b3df7bb35 100644 --- a/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl +++ b/apps/emqx_gateway/src/emqx_gateway_api_listeners.erl @@ -57,7 +57,7 @@ apis() -> listeners(get, #{bindings := #{name := Name0}}) -> with_gateway(Name0, fun(GwName, _) -> - {200, emqx_gateway_http:listeners(GwName)} + {200, emqx_gateway_conf:listeners(GwName)} end); listeners(post, #{bindings := #{name := Name0}, body := LConf}) -> @@ -90,7 +90,7 @@ listeners_insta(delete, #{bindings := #{name := Name0, id := ListenerId0}}) -> listeners_insta(get, #{bindings := #{name := Name0, id := ListenerId0}}) -> ListenerId = emqx_mgmt_util:urldecode(ListenerId0), with_gateway(Name0, fun(_GwName, _) -> - case emqx_gateway_http:listener(ListenerId) of + case emqx_gateway_conf:listener(ListenerId) of {ok, Listener} -> {200, Listener}; {error, not_found} -> diff --git a/apps/emqx_gateway/src/emqx_gateway_conf.erl b/apps/emqx_gateway/src/emqx_gateway_conf.erl index 2b804a704..343276add 100644 --- a/apps/emqx_gateway/src/emqx_gateway_conf.erl +++ b/apps/emqx_gateway/src/emqx_gateway_conf.erl @@ -23,13 +23,20 @@ ]). %% APIs --export([ load_gateway/2 +-export([ gateway/1 + , load_gateway/2 , update_gateway/2 , unload_gateway/1 + ]). + +-export([ listeners/1 + , listener/1 , add_listener/3 , update_listener/3 , remove_listener/2 - , add_authn/2 + ]). + +-export([ add_authn/2 , add_authn/3 , update_authn/2 , update_authn/3 @@ -67,20 +74,16 @@ load_gateway(GwName, Conf) -> NConf = case maps:take(<<"listeners">>, Conf) of error -> Conf; {Ls, Conf1} -> - Conf1#{<<"listeners">> => mapping(Ls)} + Conf1#{<<"listeners">> => unconvert_listeners(Ls)} end, update({?FUNCTION_NAME, bin(GwName), NConf}). -mapping(Ls) when is_list(Ls) -> - convert_to_map(Ls); -mapping(Ls) when is_map(Ls) -> - Ls. - -convert_to_map(Listeners) when is_list(Listeners) -> +%% @doc convert listener array to map +unconvert_listeners(Ls) when is_list(Ls) -> lists:foldl(fun(Lis, Acc) -> {[Type, Name], Lis1} = maps_key_take([<<"type">>, <<"name">>], Lis), emqx_map_lib:deep_merge(Acc, #{Type => #{Name => Lis1}}) - end, #{}, Listeners). + end, #{}, Ls). maps_key_take(Ks, M) -> maps_key_take(Ks, M, []). @@ -103,6 +106,81 @@ update_gateway(GwName, Conf0) -> unload_gateway(GwName) -> update({?FUNCTION_NAME, bin(GwName)}). +%% @doc Get the gateway configurations. +%% Missing fields are filled with default values. This function is typically +%% used to show the user what configuration value is currently in effect. +-spec gateway(atom_or_bin()) -> map(). +gateway(GwName0) -> + GwName = bin(GwName0), + Path = [<<"gateway">>, GwName], + RawConf = emqx_config:fill_defaults( + emqx_config:get_root_raw(Path) + ), + Confs = emqx_map_lib:jsonable_map( + emqx_map_lib:deep_get(Path, RawConf)), + LsConf = maps:get(<<"listeners">>, Confs, #{}), + Confs#{<<"listeners">> => convert_listeners(GwName, LsConf)}. + +%% @doc convert listeners map to array +convert_listeners(GwName, Ls) when is_map(Ls) -> + lists:append([do_convert_listener(GwName, Type, maps:to_list(Conf)) + || {Type, Conf} <- maps:to_list(Ls)]). + +do_convert_listener(GwName, Type, Conf) -> + [begin + ListenerId = emqx_gateway_utils:listener_id(GwName, Type, LName), + Running = emqx_gateway_utils:is_running(ListenerId, LConf), + bind2str( + LConf#{ + id => ListenerId, + type => Type, + name => LName, + running => Running + }) + end || {LName, LConf} <- Conf, is_map(LConf)]. + +bind2str(LConf = #{bind := Bind}) when is_integer(Bind) -> + maps:put(bind, integer_to_binary(Bind), LConf); +bind2str(LConf = #{<<"bind">> := Bind}) when is_integer(Bind) -> + maps:put(<<"bind">>, integer_to_binary(Bind), LConf); +bind2str(LConf = #{bind := Bind}) when is_binary(Bind) -> + LConf; +bind2str(LConf = #{<<"bind">> := Bind}) when is_binary(Bind) -> + LConf. + +-spec listeners(atom_or_bin()) -> map(). +listeners(GwName0) -> + GwName = bin(GwName0), + RawConf = emqx_config:fill_defaults( + emqx_config:get_root_raw([<<"gateway">>])), + Listeners = emqx_map_lib:jsonable_map( + emqx_map_lib:deep_get( + [<<"gateway">>, GwName, <<"listeners">>], RawConf)), + convert_listeners(GwName, Listeners). + +-spec listener(binary()) -> {ok, map()} | {error, not_found} | {error, any()}. +listener(ListenerId) -> + {GwName, Type, LName} = emqx_gateway_utils:parse_listener_id(ListenerId), + RootConf = emqx_config:fill_defaults( + emqx_config:get_root_raw([<<"gateway">>])), + try + Path = [<<"gateway">>, GwName, <<"listeners">>, Type, LName], + LConf = emqx_map_lib:deep_get(Path, RootConf), + Running = emqx_gateway_utils:is_running( + binary_to_existing_atom(ListenerId), LConf), + {ok, emqx_map_lib:jsonable_map( + LConf#{ + id => ListenerId, + type => Type, + name => LName, + running => Running})} + catch + error : {config_not_found, _} -> + {error, not_found}; + _Class : Reason -> + {error, Reason} + end. + -spec add_listener(atom_or_bin(), listener_ref(), map()) -> ok_or_err(). add_listener(GwName, ListenerRef, Conf) -> update({?FUNCTION_NAME, bin(GwName), bin(ListenerRef), Conf}). diff --git a/apps/emqx_gateway/src/emqx_gateway_http.erl b/apps/emqx_gateway/src/emqx_gateway_http.erl index fc3ded3c9..e5c927a1a 100644 --- a/apps/emqx_gateway/src/emqx_gateway_http.erl +++ b/apps/emqx_gateway/src/emqx_gateway_http.erl @@ -24,13 +24,10 @@ -export([ gateways/1 ]). -%% Mgmt APIs - listeners --export([ listeners/1 - , listener/1 - , add_listener/2 +%% Mgmt APIs +-export([ add_listener/2 , remove_listener/1 , update_listener/2 - , mapping_listener_m2l/2 ]). -export([ authn/1 @@ -140,75 +137,6 @@ get_listeners_status(GwName, Config) -> %% Mgmt APIs - listeners %%-------------------------------------------------------------------- --spec listeners(atom() | binary()) -> list(). -listeners(GwName) when is_atom(GwName) -> - listeners(atom_to_binary(GwName)); -listeners(GwName) -> - RawConf = emqx_config:fill_defaults( - emqx_config:get_root_raw([<<"gateway">>])), - Listeners = emqx_map_lib:jsonable_map( - emqx_map_lib:deep_get( - [<<"gateway">>, GwName, <<"listeners">>], RawConf)), - mapping_listener_m2l(GwName, Listeners). - --spec listener(binary()) -> {ok, map()} | {error, not_found} | {error, any()}. -listener(ListenerId) -> - {GwName, Type, LName} = emqx_gateway_utils:parse_listener_id(ListenerId), - RootConf = emqx_config:fill_defaults( - emqx_config:get_root_raw([<<"gateway">>])), - try - Path = [<<"gateway">>, GwName, <<"listeners">>, Type, LName], - LConf = emqx_map_lib:deep_get(Path, RootConf), - Running = is_running(binary_to_existing_atom(ListenerId), LConf), - {ok, emqx_map_lib:jsonable_map( - LConf#{ - id => ListenerId, - type => Type, - name => LName, - running => Running})} - catch - error : {config_not_found, _} -> - {error, not_found}; - _Class : Reason -> - {error, Reason} - end. - -mapping_listener_m2l(GwName, Listeners0) -> - Listeners = maps:to_list(Listeners0), - lists:append([listener(GwName, Type, maps:to_list(Conf)) - || {Type, Conf} <- Listeners]). - -listener(GwName, Type, Conf) -> - [begin - ListenerId = emqx_gateway_utils:listener_id(GwName, Type, LName), - Running = is_running(ListenerId, LConf), - bind2str( - LConf#{ - id => ListenerId, - type => Type, - name => LName, - running => Running - }) - end || {LName, LConf} <- Conf, is_map(LConf)]. - -is_running(ListenerId, #{<<"bind">> := ListenOn0}) -> - ListenOn = emqx_gateway_utils:parse_listenon(ListenOn0), - try esockd:listener({ListenerId, ListenOn}) of - Pid when is_pid(Pid)-> - true - catch _:_ -> - false - end. - -bind2str(LConf = #{bind := Bind}) when is_integer(Bind) -> - maps:put(bind, integer_to_binary(Bind), LConf); -bind2str(LConf = #{<<"bind">> := Bind}) when is_integer(Bind) -> - maps:put(<<"bind">>, integer_to_binary(Bind), LConf); -bind2str(LConf = #{bind := Bind}) when is_binary(Bind) -> - LConf; -bind2str(LConf = #{<<"bind">> := Bind}) when is_binary(Bind) -> - LConf. - -spec add_listener(atom() | binary(), map()) -> ok. add_listener(ListenerId, NewConf0) -> {GwName, Type, Name} = emqx_gateway_utils:parse_listener_id(ListenerId), diff --git a/apps/emqx_gateway/src/emqx_gateway_utils.erl b/apps/emqx_gateway/src/emqx_gateway_utils.erl index 8120b5d48..0f8ee99b0 100644 --- a/apps/emqx_gateway/src/emqx_gateway_utils.erl +++ b/apps/emqx_gateway/src/emqx_gateway_utils.erl @@ -33,6 +33,7 @@ , unix_ts_to_rfc3339/2 , listener_id/3 , parse_listener_id/1 + , is_running/2 ]). -export([ stringfy/1 @@ -148,6 +149,15 @@ parse_listener_id(Id) -> _ : _ -> error({invalid_listener_id, Id}) end. +is_running(ListenerId, #{<<"bind">> := ListenOn0}) -> + ListenOn = emqx_gateway_utils:parse_listenon(ListenOn0), + try esockd:listener({ListenerId, ListenOn}) of + Pid when is_pid(Pid)-> + true + catch _:_ -> + false + end. + bin(A) when is_atom(A) -> atom_to_binary(A); bin(L) when is_list(L); is_binary(L) ->