Add get_forwards and get_subscriptions protal APIs
This commit is contained in:
parent
67376727c9
commit
9e78c18681
|
@ -31,7 +31,7 @@
|
||||||
-type(pubsub() :: publish | subscribe).
|
-type(pubsub() :: publish | subscribe).
|
||||||
-type(topic() :: binary()).
|
-type(topic() :: binary()).
|
||||||
-type(subid() :: binary() | atom()).
|
-type(subid() :: binary() | atom()).
|
||||||
-type(subopts() :: #{qos := integer(),
|
-type(subopts() :: #{qos := eqmx_mqtt_types:qos(),
|
||||||
share => binary(),
|
share => binary(),
|
||||||
atom() => term()
|
atom() => term()
|
||||||
}).
|
}).
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
%% | | |
|
%% | | |
|
||||||
%% '--(1)---'--------(3)------'
|
%% '--(1)---'--------(3)------'
|
||||||
%%
|
%%
|
||||||
%% (1): timeout
|
%% (1): retry timeout
|
||||||
%% (2): successfuly connected to remote node/cluster
|
%% (2): successfuly connected to remote node/cluster
|
||||||
%% (3): received {disconnected, conn_ref(), Reason} OR
|
%% (3): received {disconnected, conn_ref(), Reason} OR
|
||||||
%% failed to send to remote node/cluster.
|
%% failed to send to remote node/cluster.
|
||||||
|
@ -72,11 +72,17 @@
|
||||||
%% state functions
|
%% state functions
|
||||||
-export([connecting/3, connected/3]).
|
-export([connecting/3, connected/3]).
|
||||||
|
|
||||||
|
%% management APIs
|
||||||
|
-export([get_forwards/1]). %, add_forward/2, del_forward/2]).
|
||||||
|
-export([get_subscriptions/1]). %, add_subscription/3, del_subscription/2]).
|
||||||
|
|
||||||
-export_type([config/0,
|
-export_type([config/0,
|
||||||
batch/0,
|
batch/0,
|
||||||
ack_ref/0
|
ack_ref/0
|
||||||
]).
|
]).
|
||||||
|
|
||||||
|
-type id() :: atom() | string() | pid().
|
||||||
|
-type qos() :: emqx_mqtt_types:qos().
|
||||||
-type config() :: map().
|
-type config() :: map().
|
||||||
-type batch() :: [emqx_portal_msg:exp_msg()].
|
-type batch() :: [emqx_portal_msg:exp_msg()].
|
||||||
-type ack_ref() :: term().
|
-type ack_ref() :: term().
|
||||||
|
@ -131,6 +137,11 @@ handle_ack(Pid, Ref) when node() =:= node(Pid) ->
|
||||||
Pid ! {batch_ack, Ref},
|
Pid ! {batch_ack, Ref},
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
-spec get_forwards(id()) -> [emqx_topic:topic()].
|
||||||
|
get_forwards(Id) -> gen_statem:call(id(Id), get_forwards).
|
||||||
|
|
||||||
|
-spec get_subscriptions(id()) -> [{emqx_topic:topic(), qos()}].
|
||||||
|
get_subscriptions(Id) -> gen_statem:call(id(Id), get_subscriptions).
|
||||||
|
|
||||||
callback_mode() -> [state_functions, state_enter].
|
callback_mode() -> [state_functions, state_enter].
|
||||||
|
|
||||||
|
@ -150,7 +161,12 @@ init(Config) ->
|
||||||
end,
|
end,
|
||||||
Queue = replayq:open(QueueConfig#{sizer => fun emqx_portal_msg:estimate_size/1,
|
Queue = replayq:open(QueueConfig#{sizer => fun emqx_portal_msg:estimate_size/1,
|
||||||
marshaller => fun msg_marshaller/1}),
|
marshaller => fun msg_marshaller/1}),
|
||||||
Topics = Get(forwards, []),
|
Topics = lists:sort([iolist_to_binary(T) || T <- Get(forwards, [])]),
|
||||||
|
Subs = lists:keysort(1, lists:map(fun({T0, QoS}) ->
|
||||||
|
T = iolist_to_binary(T0),
|
||||||
|
true = emqx_topic:validate({filter, T}),
|
||||||
|
{T, QoS}
|
||||||
|
end, Get(subscriptions, []))),
|
||||||
ok = subscribe_local_topics(Topics),
|
ok = subscribe_local_topics(Topics),
|
||||||
ConnectModule = maps:get(connect_module, Config),
|
ConnectModule = maps:get(connect_module, Config),
|
||||||
ConnectConfig = maps:without([connect_module,
|
ConnectConfig = maps:without([connect_module,
|
||||||
|
@ -159,7 +175,7 @@ init(Config) ->
|
||||||
max_inflight_batches,
|
max_inflight_batches,
|
||||||
mountpoint,
|
mountpoint,
|
||||||
forwards
|
forwards
|
||||||
], Config),
|
], Config#{subscriptions => Subs}),
|
||||||
ConnectFun = fun() -> emqx_portal_connect:start(ConnectModule, ConnectConfig) end,
|
ConnectFun = fun() -> emqx_portal_connect:start(ConnectModule, ConnectConfig) end,
|
||||||
{ok, connecting,
|
{ok, connecting,
|
||||||
#{connect_module => ConnectModule,
|
#{connect_module => ConnectModule,
|
||||||
|
@ -170,6 +186,7 @@ init(Config) ->
|
||||||
max_inflight_batches => Get(max_inflight_batches, ?DEFAULT_SEND_AHEAD),
|
max_inflight_batches => Get(max_inflight_batches, ?DEFAULT_SEND_AHEAD),
|
||||||
mountpoint => format_mountpoint(Get(mountpoint, undefined)),
|
mountpoint => format_mountpoint(Get(mountpoint, undefined)),
|
||||||
topics => Topics,
|
topics => Topics,
|
||||||
|
subscriptions => Subs,
|
||||||
replayq => Queue,
|
replayq => Queue,
|
||||||
inflight => []
|
inflight => []
|
||||||
}}.
|
}}.
|
||||||
|
@ -255,6 +272,10 @@ connected(Type, Content, State) ->
|
||||||
common(connected, Type, Content, State).
|
common(connected, Type, Content, State).
|
||||||
|
|
||||||
%% Common handlers
|
%% Common handlers
|
||||||
|
common(_StateName, {call, From}, get_forwards, #{forwards := Forwards}) ->
|
||||||
|
{keep_state_and_data, [{reply, From, Forwards}]};
|
||||||
|
common(_StateName, {call, From}, get_subscriptions, #{subscriptions := Subs}) ->
|
||||||
|
{keep_state_and_data, [{reply, From, Subs}]};
|
||||||
common(_StateName, info, {dispatch, _, Msg},
|
common(_StateName, info, {dispatch, _, Msg},
|
||||||
#{replayq := Q} = State) ->
|
#{replayq := Q} = State) ->
|
||||||
NewQ = replayq:append(Q, collect([Msg])),
|
NewQ = replayq:append(Q, collect([Msg])),
|
||||||
|
@ -363,3 +384,6 @@ name() -> {_, Name} = process_info(self(), registered_name), Name.
|
||||||
|
|
||||||
name(Id) -> list_to_atom(lists:concat([?MODULE, "_", Id])).
|
name(Id) -> list_to_atom(lists:concat([?MODULE, "_", Id])).
|
||||||
|
|
||||||
|
id(Pid) when is_pid(Pid) -> Pid;
|
||||||
|
id(Name) -> name(Name).
|
||||||
|
|
||||||
|
|
|
@ -149,9 +149,10 @@ make_hdlr(Parent, AckCollector, Ref) ->
|
||||||
}.
|
}.
|
||||||
|
|
||||||
subscribe_remote_topics(ClientPid, Subscriptions) ->
|
subscribe_remote_topics(ClientPid, Subscriptions) ->
|
||||||
[case emqx_client:subscribe(ClientPid, {bin(Topic), Qos}) of
|
lists:foreach(fun({Topic, Qos}) ->
|
||||||
{ok, _, _} -> ok;
|
case emqx_client:subscribe(ClientPid, Topic, Qos) of
|
||||||
Error -> throw(Error)
|
{ok, _, _} -> ok;
|
||||||
end || {Topic, Qos} <- Subscriptions, emqx_topic:validate({filter, bin(Topic)})].
|
Error -> throw(Error)
|
||||||
|
end
|
||||||
|
end, Subscriptions).
|
||||||
|
|
||||||
bin(L) -> iolist_to_binary(L).
|
|
||||||
|
|
|
@ -16,7 +16,8 @@
|
||||||
|
|
||||||
-export([all/0, init_per_suite/1, end_per_suite/1]).
|
-export([all/0, init_per_suite/1, end_per_suite/1]).
|
||||||
-export([t_rpc/1,
|
-export([t_rpc/1,
|
||||||
t_mqtt/1
|
t_mqtt/1,
|
||||||
|
t_forwards_mngr/1
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-include_lib("eunit/include/eunit.hrl").
|
-include_lib("eunit/include/eunit.hrl").
|
||||||
|
@ -27,7 +28,8 @@
|
||||||
-define(wait(For, Timeout), emqx_ct_helpers:wait_for(?FUNCTION_NAME, ?LINE, fun() -> For end, Timeout)).
|
-define(wait(For, Timeout), emqx_ct_helpers:wait_for(?FUNCTION_NAME, ?LINE, fun() -> For end, Timeout)).
|
||||||
|
|
||||||
all() -> [t_rpc,
|
all() -> [t_rpc,
|
||||||
t_mqtt
|
t_mqtt,
|
||||||
|
t_forwards_mngr
|
||||||
].
|
].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
|
@ -43,6 +45,24 @@ init_per_suite(Config) ->
|
||||||
end_per_suite(_Config) ->
|
end_per_suite(_Config) ->
|
||||||
emqx_ct_broker_helpers:run_teardown_steps().
|
emqx_ct_broker_helpers:run_teardown_steps().
|
||||||
|
|
||||||
|
t_forwards_mngr(Config) when is_list(Config) ->
|
||||||
|
Subs = [{<<"a">>, 1}, {<<"b">>, 2}],
|
||||||
|
Cfg = #{address => node(),
|
||||||
|
forwards => [<<"mngr">>],
|
||||||
|
connect_module => emqx_portal_rpc,
|
||||||
|
mountpoint => <<"forwarded">>,
|
||||||
|
subscriptions => Subs
|
||||||
|
},
|
||||||
|
Name = ?FUNCTION_NAME,
|
||||||
|
{ok, Pid} = emqx_portal:start_link(Name, Cfg),
|
||||||
|
try
|
||||||
|
?assertEqual([<<"mngr">>], emqx_portal:get_forwards(Name)),
|
||||||
|
?assertEqual(Subs, emqx_portal:get_subscriptions(Pid))
|
||||||
|
after
|
||||||
|
ok = emqx_portal:stop(Pid)
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
%% A loopback RPC to local node
|
%% A loopback RPC to local node
|
||||||
t_rpc(Config) when is_list(Config) ->
|
t_rpc(Config) when is_list(Config) ->
|
||||||
Cfg = #{address => node(),
|
Cfg = #{address => node(),
|
||||||
|
|
Loading…
Reference in New Issue