chore(gw): adapt the lates minirest and emqx-config

This commit is contained in:
JianBo He 2021-08-27 11:25:00 +08:00 committed by turtleDeng
parent dacc53facf
commit fdb41fe137
4 changed files with 80 additions and 55 deletions

View File

@ -22,7 +22,7 @@
%% callbacks for emqx_config_handler %% callbacks for emqx_config_handler
-export([ pre_config_update/2 -export([ pre_config_update/2
, post_config_update/3 , post_config_update/4
]). ]).
%% APIs %% APIs
@ -88,7 +88,10 @@ stop(Name) ->
-> ok -> ok
| {error, any()}. | {error, any()}.
update_rawconf(RawName, RawConfDiff) -> update_rawconf(RawName, RawConfDiff) ->
emqx:update_config([gateway], {RawName, RawConfDiff}). case emqx:update_config([gateway], {RawName, RawConfDiff}) of
{ok, _Result} -> ok;
{error, Reason} -> {error, Reason}
end.
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Config Handler %% Config Handler
@ -99,8 +102,9 @@ pre_config_update({RawName, RawConfDiff}, RawConf) ->
{ok, emqx_map_lib:deep_merge(RawConf, #{RawName => RawConfDiff})}. {ok, emqx_map_lib:deep_merge(RawConf, #{RawName => RawConfDiff})}.
-spec post_config_update(emqx_config:update_request(), emqx_config:config(), -spec post_config_update(emqx_config:update_request(), emqx_config:config(),
emqx_config:config()) -> ok | {ok, Result::any()} | {error, Reason::term()}. emqx_config:config(), emqx_config:app_envs())
post_config_update({RawName, _}, NewConfig, OldConfig) -> -> ok | {ok, Result::any()} | {error, Reason::term()}.
post_config_update({RawName, _}, NewConfig, OldConfig, _AppEnvs) ->
GwName = binary_to_existing_atom(RawName), GwName = binary_to_existing_atom(RawName),
SubConf = maps:get(GwName, NewConfig), SubConf = maps:get(GwName, NewConfig),
case maps:get(GwName, OldConfig, undefined) of case maps:get(GwName, OldConfig, undefined) of

View File

@ -29,6 +29,7 @@
%% http handlers %% http handlers
-export([ gateway/2 -export([ gateway/2
, gateway_insta/2 , gateway_insta/2
, gateway_insta_stats/2
]). ]).
-define(EXAMPLE_GATEWAY_LIST, -define(EXAMPLE_GATEWAY_LIST,
@ -240,7 +241,7 @@ metadata(gateway_insta) ->
requestBody => schema(schema_for_gateway_conf()), requestBody => schema(schema_for_gateway_conf()),
responses => #{ responses => #{
<<"404">> => NameNotFoundRespDef, <<"404">> => NameNotFoundRespDef,
<<"204">> => #{description => <<"Created">>} <<"200">> => #{description => <<"Changed">>}
} }
} }
}; };
@ -336,41 +337,45 @@ schema_for_gateway_stats() ->
%% http handlers %% http handlers
gateway(get, Request) -> gateway(get, Request) ->
Params = cowboy_req:parse_qs(Request), Params = maps:get(query_string, Request, #{}),
Status = case proplists:get_value(<<"status">>, Params) of Status = case maps:get(<<"status">>, Params, undefined) of
undefined -> all; undefined -> all;
S0 -> binary_to_existing_atom(S0, utf8) S0 -> binary_to_existing_atom(S0, utf8)
end, end,
{200, emqx_gateway_intr:gateways(Status)}. {200, emqx_gateway_intr:gateways(Status)}.
gateway_insta(delete, Request) -> gateway_insta(delete, #{bindings := #{name := Name0}}) ->
Name = binary_to_existing_atom(cowboy_req:binding(name, Request)), Name = binary_to_existing_atom(Name0),
case emqx_gateway:unload(Name) of case emqx_gateway:unload(Name) of
ok -> ok ->
{200, ok}; {200, ok};
{error, not_found} -> {error, not_found} ->
{404, <<"Not Found">>} {404, <<"Not Found">>}
end; end;
gateway_insta(get, Request) -> gateway_insta(get, #{bindings := #{name := Name0}}) ->
Name = binary_to_existing_atom(cowboy_req:binding(name, Request)), Name = binary_to_existing_atom(Name0),
case emqx_gateway:lookup(Name) of case emqx_gateway:lookup(Name) of
#{config := Config} -> #{config := _Config} ->
%% TODO: ??? RawConf or Config or RunningState ??? %% FIXME: Got the parsed config, but we should return rawconfig to
{200, Config}; %% frontend
RawConf = emqx_config:fill_defaults(
emqx_config:get_root_raw([<<"gateway">>])
),
{200, emqx_map_lib:deep_get([<<"gateway">>, Name0], RawConf)};
undefined -> undefined ->
{404, <<"Not Found">>} {404, <<"Not Found">>}
end; end;
gateway_insta(post, Request) -> gateway_insta(put, #{body := RawConfsIn,
Name = cowboy_req:binding(name, Request), bindings := #{name := Name}
{ok, RawConf, _NRequest} = cowboy_req:read_body(Request), }) ->
%% XXX: Consistence ?? %% FIXME: Cluster Consistence ??
case emqx_gateway:update_rawconf(Name, RawConf) of case emqx_gateway:update_rawconf(Name, RawConfsIn) of
ok -> ok ->
{200, ok}; {200, <<"Changed">>};
{error, not_found} -> {error, not_found} ->
{404, <<"Not Found">>}; {404, <<"Not Found">>};
{error, Reason} -> {error, Reason} ->
{500, Reason} {500, emqx_gateway_utils:stringfy(Reason)}
end. end.
gateway_insta_stats(get, _Req) -> gateway_insta_stats(get, _Req) ->

View File

@ -183,13 +183,15 @@ code_change(_OldVsn, State, _Extra) ->
{ok, State}. {ok, State}.
detailed_gateway_info(State) -> detailed_gateway_info(State) ->
#{name => State#state.name, maps:filter(
config => State#state.config, fun(_, V) -> V =/= undefined end,
status => State#state.status, #{name => State#state.name,
created_at => State#state.created_at, config => State#state.config,
started_at => State#state.started_at, status => State#state.status,
stopped_at => State#state.stopped_at created_at => State#state.created_at,
}. started_at => State#state.started_at,
stopped_at => State#state.stopped_at
}).
%%-------------------------------------------------------------------- %%--------------------------------------------------------------------
%% Internal funcs %% Internal funcs
@ -226,7 +228,7 @@ do_deinit_authn(undefined) ->
ok; ok;
do_deinit_authn(AuthnRef) -> do_deinit_authn(AuthnRef) ->
%% TODO: %% TODO:
?LOG(error, "Failed to clean authn ~p, not suppported now", [AuthnRef]). ?LOG(warning, "Failed to clean authn ~p, not suppported now", [AuthnRef]).
%case emqx_authn:delete_chain(AuthnRef) of %case emqx_authn:delete_chain(AuthnRef) of
% ok -> ok; % ok -> ok;
% {error, {not_found, _}} -> % {error, {not_found, _}} ->
@ -307,33 +309,40 @@ cb_gateway_unload(State = #state{name = GwName,
cb_gateway_load(State = #state{name = GwName, cb_gateway_load(State = #state{name = GwName,
config = Config, config = Config,
ctx = Ctx}) -> ctx = Ctx}) ->
Gateway = detailed_gateway_info(State), Gateway = detailed_gateway_info(State),
try
AuthnRef = do_init_authn(GwName, Config), case maps:get(enable, Config, true) of
NCtx = Ctx#{auth => AuthnRef}, false ->
#{cbkmod := CbMod} = emqx_gateway_registry:lookup(GwName), ?LOG(info, "Skipp to start ~s gateway due to disabled", [GwName]);
case CbMod:on_gateway_load(Gateway, NCtx) of true ->
{error, Reason} -> try
do_deinit_authn(AuthnRef), AuthnRef = do_init_authn(GwName, Config),
throw({callback_return_error, Reason}); NCtx = Ctx#{auth => AuthnRef},
{ok, ChildPidOrSpecs, GwState} -> #{cbkmod := CbMod} = emqx_gateway_registry:lookup(GwName),
ChildPids = start_child_process(ChildPidOrSpecs), case CbMod:on_gateway_load(Gateway, NCtx) of
{ok, State#state{ {error, Reason} ->
ctx = NCtx, do_deinit_authn(AuthnRef),
status = running, throw({callback_return_error, Reason});
child_pids = ChildPids, {ok, ChildPidOrSpecs, GwState} ->
gw_state = GwState, ChildPids = start_child_process(ChildPidOrSpecs),
stopped_at = undefined, {ok, State#state{
started_at = erlang:system_time(millisecond) ctx = NCtx,
}} status = running,
end child_pids = ChildPids,
catch gw_state = GwState,
Class : Reason1 : Stk -> stopped_at = undefined,
?LOG(error, "Failed to load ~s gateway (~0p, ~0p) crashed: " started_at = erlang:system_time(millisecond)
"{~p, ~p}, stacktrace: ~0p", }}
[GwName, Gateway, Ctx, end
Class, Reason1, Stk]), catch
{error, {Class, Reason1, Stk}} Class : Reason1 : Stk ->
?LOG(error, "Failed to load ~s gateway (~0p, ~0p) "
"crashed: {~p, ~p}, stacktrace: ~0p",
[GwName, Gateway, Ctx,
Class, Reason1, Stk]),
{error, {Class, Reason1, Stk}}
end
end. end.
cb_gateway_update(Config, cb_gateway_update(Config,

View File

@ -31,6 +31,9 @@
, unix_ts_to_rfc3339/2 , unix_ts_to_rfc3339/2
]). ]).
-export([ stringfy/1
]).
-export([ normalize_config/1 -export([ normalize_config/1
]). ]).
@ -118,6 +121,10 @@ unix_ts_to_rfc3339(Key, Map) ->
emqx_rule_funcs:unix_ts_to_rfc3339(Ts, <<"millisecond">>)} emqx_rule_funcs:unix_ts_to_rfc3339(Ts, <<"millisecond">>)}
end. end.
-spec stringfy(term()) -> binary().
stringfy(T) ->
iolist_to_binary(io_lib:format("~0p", [T])).
-spec normalize_config(emqx_config:config()) -spec normalize_config(emqx_config:config())
-> list({ Type :: udp | tcp | ssl | dtls -> list({ Type :: udp | tcp | ssl | dtls
, Name :: atom() , Name :: atom()