[mqtt] Remove MQTT System Broker (#12157)

Signed-off-by: Jimmy Tanagra <jcode@tanagra.id.au>
This commit is contained in:
jimtng 2022-02-02 23:00:33 +10:00 committed by GitHub
parent ca73548af2
commit 36ab0cdc87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 2 additions and 501 deletions

View File

@ -17,7 +17,6 @@ MQTT topics. Please check out the available extensions:
## Supported Bridges
* Broker: This bridge represents an MQTT Broker connection, configured and managed by this binding.
* SystemBroker: A system configured broker cannot be changed by this binding and will be listed as read-only system-broker.
## Bridge Configuration

View File

@ -26,7 +26,6 @@ public class MqttBindingConstants {
public static final String BINDING_ID = "mqtt";
// List of all Thing Type UIDs
public static final ThingTypeUID BRIDGE_TYPE_SYSTEMBROKER = new ThingTypeUID(BINDING_ID, "systemBroker");
public static final ThingTypeUID BRIDGE_TYPE_BROKER = new ThingTypeUID(BINDING_ID, "broker");
public static final String PUBLISH_TRIGGER_CHANNEL = "publishTrigger";

View File

@ -1,143 +0,0 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.mqtt.handler;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
import org.openhab.core.io.transport.mqtt.MqttConnectionState;
import org.openhab.core.io.transport.mqtt.MqttService;
import org.openhab.core.io.transport.mqtt.MqttServiceObserver;
import org.openhab.core.io.transport.mqtt.MqttWillAndTestament;
import org.openhab.core.io.transport.mqtt.reconnect.PeriodicReconnectStrategy;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.ThingStatus;
import org.openhab.core.thing.ThingStatusDetail;
/**
* This handler does not much except providing all information from a
* {@link MqttBrokerConnection} via Thing properties and put the Thing
* offline or online depending on the connection.
*
* @author David Graeff - Initial contribution
*/
@NonNullByDefault
public class SystemBrokerHandler extends AbstractBrokerHandler implements MqttServiceObserver {
// Properties
public static final String PROPERTY_URL = "url";
public static final String PROPERTY_USERNAME = "username";
public static final String PROPERTY_PASSWORD = "password";
public static final String PROPERTY_QOS = "qos";
public static final String PROPERTY_RETAIN = "retain";
public static final String PROPERTY_LAST_WILL = "lastwill";
public static final String PROPERTY_RECONNECT_TIME = "reconnect_time_ms";
public static final String PROPERTY_KEEP_ALIVE_TIME = "keep_alive_time_ms";
public static final String PROPERTY_CONNECT_TIMEOUT = "connect_timeout_ms";
protected final MqttService service;
protected String brokerID = "";
protected boolean discoveryEnabled = true;
public SystemBrokerHandler(Bridge thing, MqttService service) {
super(thing);
this.service = service;
}
@Override
public void connectionStateChanged(MqttConnectionState state, @Nullable Throwable error) {
Map<String, String> properties = new HashMap<>();
properties.put(PROPERTY_URL, connection.getHost() + ":" + String.valueOf(connection.getPort()));
final String username = connection.getUser();
final String password = connection.getPassword();
if (username != null && password != null) {
properties.put(PROPERTY_USERNAME, username);
properties.put(PROPERTY_PASSWORD, password);
}
properties.put(PROPERTY_QOS, String.valueOf(connection.getQos()));
final MqttWillAndTestament lastWill = connection.getLastWill();
if (lastWill != null) {
properties.put(PROPERTY_LAST_WILL, lastWill.toString());
} else {
properties.put(PROPERTY_LAST_WILL, "");
}
if (connection.getReconnectStrategy() instanceof PeriodicReconnectStrategy) {
final PeriodicReconnectStrategy strategy = (PeriodicReconnectStrategy) connection.getReconnectStrategy();
if (strategy != null) {
properties.put(PROPERTY_RECONNECT_TIME, String.valueOf(strategy.getReconnectFrequency()));
}
}
properties.put(PROPERTY_KEEP_ALIVE_TIME, String.valueOf(connection.getKeepAliveInterval()));
updateProperties(properties);
super.connectionStateChanged(state, error);
}
/**
* The base implementation will set the connection variable to the given broker
* if it matches the brokerID and will start to connect to the broker if there
* is no connection established yet.
*/
@Override
@SuppressWarnings("PMD.CompareObjectsWithEquals")
public void brokerAdded(String connectionName, MqttBrokerConnection addedConnection) {
if (!connectionName.equals(brokerID) || connection == addedConnection) {
return;
}
this.connection = addedConnection;
super.initialize();
}
@Override
public void brokerRemoved(String connectionName, MqttBrokerConnection removedConnection) {
final MqttBrokerConnection connection = this.connection;
if (removedConnection.equals(connection)) {
connection.removeConnectionObserver(this);
this.connection = null;
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "@text/offline.sharedremoved");
return;
}
}
@Override
public void initialize() {
this.brokerID = getThing().getConfiguration().get("brokerid").toString();
this.discoveryEnabled = (Boolean) getThing().getConfiguration().get("enableDiscovery");
service.addBrokersListener(this);
connection = service.getBrokerConnection(brokerID);
if (connection == null) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"@text/offline.notextualconfig [\"" + brokerID + "\"");
return;
}
super.initialize();
}
@Override
public void dispose() {
service.removeBrokersListener(this);
super.dispose();
}
@Override
public boolean discoveryEnabled() {
return discoveryEnabled;
}
}

View File

@ -27,7 +27,6 @@ import org.openhab.binding.mqtt.discovery.MQTTTopicDiscoveryParticipant;
import org.openhab.binding.mqtt.discovery.MQTTTopicDiscoveryService;
import org.openhab.binding.mqtt.handler.AbstractBrokerHandler;
import org.openhab.binding.mqtt.handler.BrokerHandler;
import org.openhab.binding.mqtt.handler.SystemBrokerHandler;
import org.openhab.core.io.transport.mqtt.MqttService;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
@ -54,8 +53,7 @@ import org.slf4j.LoggerFactory;
public class MqttBrokerHandlerFactory extends BaseThingHandlerFactory implements MQTTTopicDiscoveryService {
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Stream
.of(MqttBindingConstants.BRIDGE_TYPE_SYSTEMBROKER, MqttBindingConstants.BRIDGE_TYPE_BROKER)
.collect(Collectors.toSet());
.of(MqttBindingConstants.BRIDGE_TYPE_BROKER).collect(Collectors.toSet());
private final Logger logger = LoggerFactory.getLogger(MqttBrokerHandlerFactory.class);
@ -107,9 +105,7 @@ public class MqttBrokerHandlerFactory extends BaseThingHandlerFactory implements
final ThingTypeUID thingTypeUID = thing.getThingTypeUID();
final AbstractBrokerHandler handler;
if (thingTypeUID.equals(MqttBindingConstants.BRIDGE_TYPE_SYSTEMBROKER)) {
handler = new SystemBrokerHandler((Bridge) thing, mqttService);
} else if (thingTypeUID.equals(MqttBindingConstants.BRIDGE_TYPE_BROKER)) {
if (thingTypeUID.equals(MqttBindingConstants.BRIDGE_TYPE_BROKER)) {
handler = new BrokerHandler((Bridge) thing);
} else {
throw new IllegalStateException("Not supported " + thingTypeUID.toString());

View File

@ -38,8 +38,4 @@ public class MqttThingID {
public static ThingUID getThingUID(String host, int port) {
return new ThingUID(MqttBindingConstants.BRIDGE_TYPE_BROKER, getThingID(host, port));
}
public static ThingUID getTextualThingUID(String host, int port) {
return new ThingUID(MqttBindingConstants.BRIDGE_TYPE_SYSTEMBROKER, getThingID(host, port));
}
}

View File

@ -1,116 +0,0 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.mqtt.internal.discovery;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.openhab.binding.mqtt.MqttBindingConstants;
import org.openhab.core.config.discovery.AbstractDiscoveryService;
import org.openhab.core.config.discovery.DiscoveryResultBuilder;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
import org.openhab.core.io.transport.mqtt.MqttService;
import org.openhab.core.io.transport.mqtt.MqttServiceObserver;
import org.openhab.core.thing.ThingUID;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The {@link MqttServiceDiscoveryService} is responsible for discovering connections on
* the MqttService shared connection pool.
*
* @author David Graeff - Initial contribution
*/
@Component(service = DiscoveryService.class, configurationPid = "discovery.systemmqttbroker")
public class MqttServiceDiscoveryService extends AbstractDiscoveryService implements MqttServiceObserver {
private final Logger logger = LoggerFactory.getLogger(MqttServiceDiscoveryService.class);
MqttService mqttService;
public MqttServiceDiscoveryService() {
super(Stream.of(MqttBindingConstants.BRIDGE_TYPE_SYSTEMBROKER, MqttBindingConstants.BRIDGE_TYPE_BROKER)
.collect(Collectors.toSet()), 0, true);
}
@Override
@Activate
protected void activate(Map<String, Object> config) {
super.activate(config);
}
@Override
@Deactivate
protected void deactivate() {
super.deactivate();
}
@Reference
public void setMqttService(MqttService service) {
mqttService = service;
}
public void unsetMqttService(MqttService service) {
mqttService = null;
}
@Override
protected void startScan() {
mqttService.addBrokersListener(this);
mqttService.getAllBrokerConnections().forEach((brokerId, broker) -> brokerAdded(brokerId, broker));
stopScan();
}
@Override
protected void startBackgroundDiscovery() {
if (mqttService == null) {
return;
}
mqttService.addBrokersListener(this);
mqttService.getAllBrokerConnections().forEach((brokerId, broker) -> brokerAdded(brokerId, broker));
}
@Override
protected void stopBackgroundDiscovery() {
if (mqttService == null) {
return;
}
mqttService.removeBrokersListener(this);
}
@Override
public void brokerAdded(String brokerId, MqttBrokerConnection broker) {
logger.trace("Found broker connection {}", brokerId);
Map<String, Object> properties = new HashMap<>();
properties.put("host", broker.getHost());
properties.put("port", broker.getPort());
properties.put("brokerid", brokerId);
ThingUID thingUID;
thingUID = new ThingUID(MqttBindingConstants.BRIDGE_TYPE_SYSTEMBROKER, brokerId);
thingDiscovered(DiscoveryResultBuilder.create(thingUID).withProperties(properties)
.withRepresentationProperty("brokerid").withLabel("MQTT Broker").build());
}
@Override
public void brokerRemoved(String brokerId, MqttBrokerConnection broker) {
ThingUID thingUID;
thingUID = new ThingUID(MqttBindingConstants.BRIDGE_TYPE_SYSTEMBROKER, brokerId);
thingRemoved(thingUID);
}
}

View File

@ -7,8 +7,6 @@ binding.mqtt.description = Allows management of MQTT broker connections and link
thing-type.mqtt.broker.label = MQTT Broker
thing-type.mqtt.broker.description = A connection to a MQTT broker
thing-type.mqtt.systemBroker.label = System MQTT Broker
thing-type.mqtt.systemBroker.description = A system configured and therefore read-only broker connection. Properties are reflecting the configuration and internal connection status.
# thing types config
@ -53,10 +51,6 @@ thing-type.config.mqtt.broker.secure.label = Secure Connection
thing-type.config.mqtt.broker.secure.description = Uses TLS/SSL to establish a secure connection to the broker.
thing-type.config.mqtt.broker.username.label = Username
thing-type.config.mqtt.broker.username.description = The MQTT username
thing-type.config.mqtt.systemBroker.brokerid.label = Broker ID
thing-type.config.mqtt.systemBroker.brokerid.description = Each system wide configured MQTT broker has a unique broker ID.
thing-type.config.mqtt.systemBroker.enableDiscovery.label = Enable Discovery
thing-type.config.mqtt.systemBroker.enableDiscovery.description = If set to true enables this broker for all discovery services.
# channel types

View File

@ -7,8 +7,6 @@ binding.mqtt.description = MQTT bróker kezelését teszi lehetővé, mellyel MQ
thing-type.mqtt.broker.label = MQTT bróker
thing-type.mqtt.broker.description = Kapcsolat az MQTT brókerhez
thing-type.mqtt.systemBroker.label = Rendszer MQTT bróker
thing-type.mqtt.systemBroker.description = Rendszerbeállított és ezért csak olvasható bróker kapcsolat. A tulajdonságok a beállítások és belső kapcsolat állapotot tükrözik.
# thing types config
@ -53,10 +51,6 @@ thing-type.config.mqtt.broker.secure.label = Biztonságos kapcsolat
thing-type.config.mqtt.broker.secure.description = TLS/SSL használata a bróker biztonságos kapcsolódásához.
thing-type.config.mqtt.broker.username.label = Felhasználónév
thing-type.config.mqtt.broker.username.description = Az MQTT felhasználói neve
thing-type.config.mqtt.systemBroker.brokerid.label = Bróker azonosító
thing-type.config.mqtt.systemBroker.brokerid.description = Minden rendszerszintú MQTT brókerhez egyedi bórker azonosító tartozik.
thing-type.config.mqtt.systemBroker.enableDiscovery.label = Felderítés használata
thing-type.config.mqtt.systemBroker.enableDiscovery.description = Ha bekapcsolja a felderítés szolgáltatótk ezt a brókert fogják használni.
# channel types

View File

@ -7,8 +7,6 @@ binding.mqtt.description = Consente la gestione delle connessioni dei broker MQT
thing-type.mqtt.broker.label = Broker MQTT
thing-type.mqtt.broker.description = Una connessione a un broker MQTT
thing-type.mqtt.systemBroker.label = Broker MQTT di Sistema
thing-type.mqtt.systemBroker.description = Un sistema configurato e quindi con connessione broker di sola lettura. Le proprietà riflettono lo stato della configurazione e della connessione interna.
# thing types config
@ -53,10 +51,6 @@ thing-type.config.mqtt.broker.secure.label = Connessione Sicura
thing-type.config.mqtt.broker.secure.description = Utilizza TLS/SSL per stabilire una connessione sicura al broker.
thing-type.config.mqtt.broker.username.label = Username
thing-type.config.mqtt.broker.username.description = Il nome utente MQTT
thing-type.config.mqtt.systemBroker.brokerid.label = ID Broker
thing-type.config.mqtt.systemBroker.brokerid.description = Ogni broker MQTT configurato in tutto il sistema ha un ID broker unico.
thing-type.config.mqtt.systemBroker.enableDiscovery.label = Abilita Ricerca
thing-type.config.mqtt.systemBroker.enableDiscovery.description = Se impostato a true abilita questo broker per la scoperta di tutti i servizi.
# channel types

View File

@ -144,36 +144,6 @@
</config-description>
</bridge-type>
<bridge-type id="systemBroker" extensible="publishTrigger">
<label>System MQTT Broker</label>
<description>A system configured and therefore read-only broker connection. Properties are reflecting the
configuration and internal connection status.</description>
<properties>
<property name="url"/>
<property name="username"/>
<property name="password"/>
<property name="qos"/>
<property name="retain"/>
<property name="lastwill"/>
<property name="reconnect_time_ms"/>
<property name="keep_alive_time_ms"/>
</properties>
<config-description>
<parameter name="brokerid" type="text" required="true">
<label>Broker ID</label>
<description>Each system wide configured MQTT broker has a unique broker ID.</description>
</parameter>
<parameter name="enableDiscovery" type="boolean">
<label>Enable Discovery</label>
<description>If set to true enables this broker for all discovery services.</description>
<advanced>true</advanced>
<default>true</default>
</parameter>
</config-description>
</bridge-type>
<channel-type id="publishTrigger">
<kind>trigger</kind>
<label>Publish Trigger</label>

View File

@ -1,100 +0,0 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.mqtt.handler;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.*;
import java.util.Collections;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.openhab.binding.mqtt.internal.MqttThingID;
import org.openhab.core.config.core.Configuration;
import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
import org.openhab.core.io.transport.mqtt.MqttException;
import org.openhab.core.io.transport.mqtt.MqttService;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.binding.ThingHandlerCallback;
import org.osgi.service.cm.ConfigurationException;
/**
* Tests cases for {@link org.openhab.binding.mqtt.handler.AbstractBrokerHandler}.
*
* @author David Graeff - Initial contribution
*/
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.WARN)
public class AbstractBrokerHandlerTest {
private final String HOST = "tcp://123.1.2.3";
private final int PORT = 80;
private SystemBrokerHandler handler;
int stateChangeCounter = 0;
private @Mock ThingHandlerCallback callback;
private @Mock Bridge thing;
private @Mock MqttService service;
@BeforeEach
public void setUp() {
doReturn(new Configuration(Collections.singletonMap("brokerid", MqttThingID.getThingUID(HOST, PORT).getId())))
.when(thing).getConfiguration();
handler = new SystemBrokerHandler(thing, service);
handler.setCallback(callback);
assertThat(handler.getThing().getConfiguration().get("brokerid"), is(MqttThingID.getThingID(HOST, PORT)));
stateChangeCounter = 0;
}
@Test
public void brokerAddedWrongID() throws ConfigurationException, MqttException {
MqttBrokerConnection brokerConnection = mock(MqttBrokerConnection.class);
handler.brokerAdded("nonsense_id", brokerConnection);
assertNull(handler.connection);
// We do not expect a status change, because brokerAdded will do nothing with invalid connections.
verify(callback, times(0)).statusUpdated(any(), any());
}
@Test
public void brokerRemovedBroker() throws ConfigurationException, MqttException {
MqttBrokerConnectionEx connection = spy(
new MqttBrokerConnectionEx("10.10.0.10", 80, false, "BrokerHandlerTest"));
handler.brokerAdded(handler.brokerID, connection);
assertThat(handler.connection, is(connection));
handler.brokerRemoved("something", connection);
assertNull(handler.connection);
}
@Test
public void brokerAdded() throws ConfigurationException, MqttException {
MqttBrokerConnectionEx connection = spy(
new MqttBrokerConnectionEx("10.10.0.10", 80, false, "BrokerHandlerTest"));
verify(callback, times(0)).statusUpdated(any(), any());
handler.brokerAdded(handler.brokerID, connection);
assertThat(handler.connection, is(connection));
verify(connection).start();
// First connecting then connected and another connected after the future completes
verify(callback, times(3)).statusUpdated(any(), any());
}
}

View File

@ -1,82 +0,0 @@
/**
* Copyright (c) 2010-2022 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.mqtt.internal.discovery;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.openhab.binding.mqtt.MqttBindingConstants;
import org.openhab.core.config.discovery.DiscoveryListener;
import org.openhab.core.config.discovery.DiscoveryResult;
import org.openhab.core.io.transport.mqtt.MqttBrokerConnection;
import org.openhab.core.io.transport.mqtt.MqttService;
/**
* Tests cases for {@link org.openhab.binding.mqtt.internal.discovery.MqttServiceDiscoveryService}.
*
* @author David Graeff - Initial contribution
*/
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.WARN)
public class ServiceDiscoveryServiceTest {
private @Mock MqttService service;
private @Mock DiscoveryListener discoverListener;
@BeforeEach
public void initMocks() {
Map<String, MqttBrokerConnection> brokers = new TreeMap<>();
brokers.put("testname", new MqttBrokerConnection("tcp://123.123.123.123", null, false, null));
brokers.put("textual", new MqttBrokerConnection("tcp://123.123.123.123", null, true, null));
when(service.getAllBrokerConnections()).thenReturn(brokers);
}
@Test
public void testDiscovery() {
// Setting the MqttService will enable the background scanner
MqttServiceDiscoveryService d = new MqttServiceDiscoveryService();
d.addDiscoveryListener(discoverListener);
d.setMqttService(service);
d.startScan();
// We expect 3 discoveries. An embedded thing, a textual configured one, a non-textual one
ArgumentCaptor<DiscoveryResult> discoveryCapture = ArgumentCaptor.forClass(DiscoveryResult.class);
verify(discoverListener, times(2)).thingDiscovered(eq(d), discoveryCapture.capture());
List<DiscoveryResult> discoveryResults = discoveryCapture.getAllValues();
assertThat(discoveryResults.size(), is(2));
assertThat(discoveryResults.get(0).getThingTypeUID(), is(MqttBindingConstants.BRIDGE_TYPE_SYSTEMBROKER));
assertThat(discoveryResults.get(1).getThingTypeUID(), is(MqttBindingConstants.BRIDGE_TYPE_SYSTEMBROKER));
// Add another thing
d.brokerAdded("anotherone", new MqttBrokerConnection("tcp://123.123.123.123", null, false, null));
discoveryCapture = ArgumentCaptor.forClass(DiscoveryResult.class);
verify(discoverListener, times(3)).thingDiscovered(eq(d), discoveryCapture.capture());
discoveryResults = discoveryCapture.getAllValues();
assertThat(discoveryResults.size(), is(3));
assertThat(discoveryResults.get(2).getThingTypeUID(), is(MqttBindingConstants.BRIDGE_TYPE_SYSTEMBROKER));
}
}