|
|
@@ -75,6 +75,7 @@
|
|
|
connect/1,
|
|
|
status/1,
|
|
|
ping/1,
|
|
|
+ info/1,
|
|
|
send_to_remote/2,
|
|
|
send_to_remote_async/3
|
|
|
]).
|
|
|
@@ -114,7 +115,7 @@ start_link(Name, BridgeOpts) ->
|
|
|
name => Name,
|
|
|
options => BridgeOpts
|
|
|
}),
|
|
|
- Conf = init_config(BridgeOpts),
|
|
|
+ Conf = init_config(Name, BridgeOpts),
|
|
|
Options = mk_client_options(Conf, BridgeOpts),
|
|
|
case emqtt:start_link(Options) of
|
|
|
{ok, Pid} ->
|
|
|
@@ -129,13 +130,13 @@ start_link(Name, BridgeOpts) ->
|
|
|
Error
|
|
|
end.
|
|
|
|
|
|
-init_config(Opts) ->
|
|
|
+init_config(Name, Opts) ->
|
|
|
Mountpoint = maps:get(forward_mountpoint, Opts, undefined),
|
|
|
Subscriptions = maps:get(subscriptions, Opts, undefined),
|
|
|
Forwards = maps:get(forwards, Opts, undefined),
|
|
|
#{
|
|
|
mountpoint => format_mountpoint(Mountpoint),
|
|
|
- subscriptions => pre_process_subscriptions(Subscriptions),
|
|
|
+ subscriptions => pre_process_subscriptions(Subscriptions, Name, Opts),
|
|
|
forwards => pre_process_forwards(Forwards)
|
|
|
}.
|
|
|
|
|
|
@@ -145,6 +146,16 @@ mk_client_options(Conf, BridgeOpts) ->
|
|
|
Mountpoint = maps:get(receive_mountpoint, BridgeOpts, undefined),
|
|
|
Subscriptions = maps:get(subscriptions, Conf),
|
|
|
Vars = emqx_connector_mqtt_msg:make_pub_vars(Mountpoint, Subscriptions),
|
|
|
+ CleanStart =
|
|
|
+ case Subscriptions of
|
|
|
+ #{remote := _} ->
|
|
|
+ maps:get(clean_start, BridgeOpts);
|
|
|
+ undefined ->
|
|
|
+ %% NOTE
|
|
|
+ %% We are ignoring the user configuration here because there's currently no reliable way
|
|
|
+ %% to ensure proper session recovery according to the MQTT spec.
|
|
|
+ true
|
|
|
+ end,
|
|
|
Opts = maps:without(
|
|
|
[
|
|
|
address,
|
|
|
@@ -160,6 +171,7 @@ mk_client_options(Conf, BridgeOpts) ->
|
|
|
Opts#{
|
|
|
msg_handler => mk_client_event_handler(Vars, #{server => Server}),
|
|
|
hosts => [HostPort],
|
|
|
+ clean_start => CleanStart,
|
|
|
force_ping => true,
|
|
|
proto_ver => maps:get(proto_ver, BridgeOpts, v4)
|
|
|
}.
|
|
|
@@ -205,10 +217,12 @@ subscribe_remote_topics(_Ref, undefined) ->
|
|
|
stop(Ref) ->
|
|
|
emqtt:stop(ref(Ref)).
|
|
|
|
|
|
+info(Ref) ->
|
|
|
+ emqtt:info(ref(Ref)).
|
|
|
+
|
|
|
status(Ref) ->
|
|
|
try
|
|
|
- Info = emqtt:info(ref(Ref)),
|
|
|
- case proplists:get_value(socket, Info) of
|
|
|
+ case proplists:get_value(socket, info(Ref)) of
|
|
|
Socket when Socket /= undefined ->
|
|
|
connected;
|
|
|
undefined ->
|
|
|
@@ -282,11 +296,18 @@ format_mountpoint(undefined) ->
|
|
|
format_mountpoint(Prefix) ->
|
|
|
binary:replace(iolist_to_binary(Prefix), <<"${node}">>, atom_to_binary(node(), utf8)).
|
|
|
|
|
|
-pre_process_subscriptions(undefined) ->
|
|
|
+pre_process_subscriptions(undefined, _, _) ->
|
|
|
undefined;
|
|
|
-pre_process_subscriptions(#{local := LC} = Conf) when is_map(Conf) ->
|
|
|
- Conf#{local => pre_process_in_out_common(LC)};
|
|
|
-pre_process_subscriptions(Conf) when is_map(Conf) ->
|
|
|
+pre_process_subscriptions(
|
|
|
+ #{remote := RC, local := LC} = Conf,
|
|
|
+ BridgeName,
|
|
|
+ BridgeOpts
|
|
|
+) when is_map(Conf) ->
|
|
|
+ Conf#{
|
|
|
+ remote => pre_process_in_remote(RC, BridgeName, BridgeOpts),
|
|
|
+ local => pre_process_in_out_common(LC)
|
|
|
+ };
|
|
|
+pre_process_subscriptions(Conf, _, _) when is_map(Conf) ->
|
|
|
%% have no 'local' field in the config
|
|
|
undefined.
|
|
|
|
|
|
@@ -314,6 +335,27 @@ pre_process_conf(Key, Conf) ->
|
|
|
Conf#{Key => Val}
|
|
|
end.
|
|
|
|
|
|
+pre_process_in_remote(#{qos := QoSIn} = Conf, BridgeName, BridgeOpts) ->
|
|
|
+ QoS = downgrade_ingress_qos(QoSIn),
|
|
|
+ case QoS of
|
|
|
+ QoSIn ->
|
|
|
+ ok;
|
|
|
+ _ ->
|
|
|
+ ?SLOG(warning, #{
|
|
|
+ msg => "downgraded_unsupported_ingress_qos",
|
|
|
+ qos_configured => QoSIn,
|
|
|
+ qos_used => QoS,
|
|
|
+ name => BridgeName,
|
|
|
+ options => BridgeOpts
|
|
|
+ })
|
|
|
+ end,
|
|
|
+ Conf#{qos => QoS}.
|
|
|
+
|
|
|
+downgrade_ingress_qos(2) ->
|
|
|
+ 1;
|
|
|
+downgrade_ingress_qos(QoS) ->
|
|
|
+ QoS.
|
|
|
+
|
|
|
get_pid(Name) ->
|
|
|
case gproc:where(?NAME(Name)) of
|
|
|
Pid when is_pid(Pid) ->
|