emqx/apps/emqx_gateway/src/emqx_gateway.erl

148 lines
4.3 KiB
Erlang

%%--------------------------------------------------------------------
%% Copyright (c) 2021-2022 EMQ Technologies Co., Ltd. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%--------------------------------------------------------------------
-module(emqx_gateway).
-include("include/emqx_gateway.hrl").
%% Gateway APIs
-export([
registered_gateway/0,
load/2,
unload/1,
lookup/1,
update/2,
start/1,
stop/1,
list/0
]).
%% APIs For `emqx_telemetry'
-export([get_basic_usage_info/0]).
%%--------------------------------------------------------------------
%% APIs
%%--------------------------------------------------------------------
-spec registered_gateway() ->
[{gateway_name(), emqx_gateway_registry:descriptor()}].
registered_gateway() ->
emqx_gateway_registry:list().
%%--------------------------------------------------------------------
%% Gateway APIs
%% @doc List the load gateways
-spec list() -> [gateway()].
list() ->
emqx_gateway_sup:list_gateway_insta().
-spec load(gateway_name(), emqx_config:config()) ->
{ok, pid()}
| {error, any()}.
load(Name, Config) ->
Gateway = #{
name => Name,
descr => undefined,
config => Config
},
emqx_gateway_sup:load_gateway(Gateway).
-spec unload(gateway_name()) -> ok | {error, not_found}.
unload(Name) ->
emqx_gateway_sup:unload_gateway(Name).
-spec lookup(gateway_name()) -> gateway() | undefined.
lookup(Name) ->
emqx_gateway_sup:lookup_gateway(Name).
-spec update(gateway_name(), emqx_config:config()) -> ok | {error, any()}.
%% @doc This function only supports full configuration updates
%%
%% Note: If the `enable` option is missing, it will be set to true by default
update(Name, Config) ->
emqx_gateway_sup:update_gateway(Name, Config).
-spec start(gateway_name()) -> ok | {error, any()}.
start(Name) ->
emqx_gateway_sup:start_gateway_insta(Name).
-spec stop(gateway_name()) -> ok | {error, any()}.
stop(Name) ->
emqx_gateway_sup:stop_gateway_insta(Name).
%% @doc Expose basic info for `emqx_telemetry'.
-spec get_basic_usage_info() ->
#{
authn => Authn,
num_clients => non_neg_integer(),
listeners => [
#{
type => atom(),
authn => Authn
}
]
}
when
Authn :: binary().
get_basic_usage_info() ->
lists:foldl(
fun(GatewayInfo, Acc) ->
Config = maps:get(config, GatewayInfo, #{}),
GatewayType = maps:get(name, GatewayInfo),
GatewayAuthn = get_authn_type(Config),
Listeners = get_listeners(Config),
TabName = emqx_gateway_cm:tabname(chan, GatewayType),
NumClients = ets:info(TabName, size),
Acc#{
GatewayType => #{
authn => GatewayAuthn,
listeners => Listeners,
num_clients => NumClients
}
}
end,
#{},
list()
).
%%--------------------------------------------------------------------
%% Internal funcs
%%--------------------------------------------------------------------
get_authn_type(#{authentication := Authn = #{mechanism := Mechanism, backend := Backend}}) when
is_atom(Mechanism), is_atom(Backend)
->
emqx_authentication_config:authenticator_id(Authn);
get_authn_type(_) ->
<<"undefined">>.
get_listeners(#{listeners := Listeners0}) when is_map(Listeners0) ->
Listeners = [
{ListenerType, Config}
|| {ListenerType, Listeners1} <- maps:to_list(Listeners0),
{_Name, Config} <- maps:to_list(Listeners1)
],
lists:map(
fun({ListenerType, ListenerConfig}) ->
ListenerAuthn = get_authn_type(ListenerConfig),
#{type => ListenerType, authn => ListenerAuthn}
end,
Listeners
);
get_listeners(_) ->
[].