This repository has been archived by the owner on May 7, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 783
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Mqtt transport: Redesign the service to cover more usecases. (#3715)
* This will keep the 'old' MqttService API untouched for full backwards compatibility. * MqttBrokerConnection is exported now. * Improve comments all over the code. MqttService: * Allows to add / remove / enumerate broker connections, additionally to the existing textual configuration. * A new listener interface allows to be notified of added / removed broker connections. * All proxy methods are deprecated now. The MqttBrokerConnection can be accessed directly. * Add unit tests MqttWillAndTestament: * Introduce an isValid() method used to make fromString return null if not all necessary properties are provided. MqttSenderChannel: * Is depreacted now. MqttBrokerConnection.publish() should be used instead, becaue the interface does not allow to implement an async behaviour. MqttBrokerConnection: * Reconnection is no longer handled via a fixed 60s interval timer, but fully customizable. The default implementation (PeriodicReconnectPolicy) resembles the old behaviour. * A SSL broker connection no longer uses a non-configurable "trust all and everything" SSL context provider, but an interface that have to provide the SSL context provider. A default implementation, again, resembles the old behaviour. * Remove 'async' configuration option. All communication aspects (connect/disconnect/publish/subscribe) are handled in an async fashion now. * Add unit tests Signed-off-by: David Gräff <david.graeff@web.de>
- Loading branch information
David Gräff
authored and
Simon Kaufmann
committed
Jul 12, 2017
1 parent
cb7b0ad
commit 7474e58
Showing
28 changed files
with
1,498 additions
and
861 deletions.
There are no files selected for viewing
7 changes: 7 additions & 0 deletions
7
bundles/io/org.eclipse.smarthome.io.transport.mqtt.test/.classpath
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<classpath> | ||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/> | ||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> | ||
<classpathentry kind="src" path="src/test/java"/> | ||
<classpathentry kind="output" path="target/test-classes"/> | ||
</classpath> |
28 changes: 28 additions & 0 deletions
28
bundles/io/org.eclipse.smarthome.io.transport.mqtt.test/.project
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<projectDescription> | ||
<name>org.eclipse.smarthome.io.transport.mqtt.test</name> | ||
<comment></comment> | ||
<projects> | ||
</projects> | ||
<buildSpec> | ||
<buildCommand> | ||
<name>org.eclipse.jdt.core.javabuilder</name> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
<buildCommand> | ||
<name>org.eclipse.pde.ManifestBuilder</name> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
<buildCommand> | ||
<name>org.eclipse.pde.SchemaBuilder</name> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
</buildSpec> | ||
<natures> | ||
<nature>org.eclipse.pde.PluginNature</nature> | ||
<nature>org.eclipse.jdt.core.javanature</nature> | ||
</natures> | ||
</projectDescription> |
8 changes: 8 additions & 0 deletions
8
bundles/io/org.eclipse.smarthome.io.transport.mqtt.test/.settings/org.eclipse.jdt.core.prefs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
eclipse.preferences.version=1 | ||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 | ||
org.eclipse.jdt.core.compiler.compliance=1.8 | ||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | ||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning | ||
org.eclipse.jdt.core.compiler.source=1.8 |
9 changes: 9 additions & 0 deletions
9
...les/io/org.eclipse.smarthome.io.transport.mqtt.test/.settings/org.maven.ide.eclipse.prefs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#Fri Feb 18 22:39:16 CET 2011 | ||
activeProfiles= | ||
eclipse.preferences.version=1 | ||
fullBuildGoals=process-test-resources | ||
includeModules=false | ||
resolveWorkspaceProjects=true | ||
resourceFilterGoals=process-resources resources\:testResources | ||
skipCompilerPlugin=true | ||
version=1 |
17 changes: 17 additions & 0 deletions
17
bundles/io/org.eclipse.smarthome.io.transport.mqtt.test/META-INF/MANIFEST.MF
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
Manifest-Version: 1.0 | ||
Bundle-ManifestVersion: 2 | ||
Bundle-Name: Tests for the Mqtt transport I/O bundle | ||
Bundle-SymbolicName: org.eclipse.smarthome.io.transport.mqtt.test | ||
Bundle-Version: 0.9.0.qualifier | ||
Bundle-Vendor: Eclipse.org/SmartHome | ||
Fragment-Host: org.eclipse.smarthome.io.transport.mqtt | ||
Bundle-RequiredExecutionEnvironment: JavaSE-1.8 | ||
Import-Package: org.eclipse.smarthome.io.transport.mqtt, | ||
org.eclipse.smarthome.test, | ||
org.eclipse.smarthome.test.java, | ||
org.hamcrest;core=split, | ||
org.junit, | ||
org.junit.runner, | ||
org.junit.runners, | ||
org.mockito | ||
Require-Bundle: org.junit,org.mockito,org.hamcrest |
28 changes: 28 additions & 0 deletions
28
bundles/io/org.eclipse.smarthome.io.transport.mqtt.test/about.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" | ||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | ||
<html xmlns="http://www.w3.org/1999/xhtml"> | ||
<head> | ||
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/> | ||
<title>About</title> | ||
</head> | ||
<body lang="EN-US"> | ||
<h2>About This Content</h2> | ||
|
||
<p>June 5, 2006</p> | ||
<h3>License</h3> | ||
|
||
<p>The Eclipse Foundation makes available all content in this plug-in ("Content"). Unless otherwise | ||
indicated below, the Content is provided to you under the terms and conditions of the | ||
Eclipse Public License Version 1.0 ("EPL"). A copy of the EPL is available | ||
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>. | ||
For purposes of the EPL, "Program" will mean the Content.</p> | ||
|
||
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is | ||
being redistributed by another party ("Redistributor") and different terms and conditions may | ||
apply to your use of any object code in the Content. Check the Redistributor's license that was | ||
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise | ||
indicated below, the terms and conditions of the EPL still apply to any source code in the Content | ||
and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p> | ||
|
||
</body> | ||
</html> |
4 changes: 4 additions & 0 deletions
4
bundles/io/org.eclipse.smarthome.io.transport.mqtt.test/build.properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
source.. = src/test/java/ | ||
output.. = target/test-classes/ | ||
bin.includes = META-INF/,\ | ||
about.html |
39 changes: 39 additions & 0 deletions
39
bundles/io/org.eclipse.smarthome.io.transport.mqtt.test/pom.xml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
|
||
<parent> | ||
<groupId>org.eclipse.smarthome.bundles</groupId> | ||
<artifactId>io</artifactId> | ||
<version>0.9.0-SNAPSHOT</version> | ||
</parent> | ||
|
||
<properties> | ||
<bundle.symbolicName>org.eclipse.smarthome.io.transport.mqtt.test</bundle.symbolicName> | ||
<bundle.namespace>org.eclipse.smarthome.io.transport.mqtt.test</bundle.namespace> | ||
</properties> | ||
|
||
<modelVersion>4.0.0</modelVersion> | ||
<groupId>org.eclipse.smarthome.io</groupId> | ||
<artifactId>org.eclipse.smarthome.io.transport.mqtt.test</artifactId> | ||
|
||
<name>Eclipse SmartHome Mqtt Transport I/O Tests</name> | ||
|
||
<packaging>eclipse-test-plugin</packaging> | ||
|
||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>${tycho-groupid}</groupId> | ||
<artifactId>target-platform-configuration</artifactId> | ||
<configuration> | ||
<environments combine.self="override"></environments> | ||
</configuration> | ||
</plugin> | ||
<plugin> | ||
<groupId>${tycho-groupid}</groupId> | ||
<artifactId>tycho-surefire-plugin</artifactId> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
|
||
</project> |
130 changes: 130 additions & 0 deletions
130
...src/test/java/org/eclipse/smarthome/io/transport/mqtt/test/MqttBrokerConnectionTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
/** | ||
* Copyright (c) 2014-2017 by the respective copyright holders. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
*/ | ||
package org.eclipse.smarthome.io.transport.mqtt.test; | ||
|
||
import static org.junit.Assert.*; | ||
import static org.mockito.Mockito.*; | ||
|
||
import java.util.Arrays; | ||
|
||
import javax.naming.ConfigurationException; | ||
|
||
import org.eclipse.paho.client.mqttv3.MqttException; | ||
import org.eclipse.smarthome.io.transport.mqtt.MqttBrokerConnection; | ||
import org.eclipse.smarthome.io.transport.mqtt.MqttConnectionObserver; | ||
import org.eclipse.smarthome.io.transport.mqtt.MqttMessageSubscriber; | ||
import org.eclipse.smarthome.io.transport.mqtt.MqttWillAndTestament; | ||
import org.junit.Test; | ||
|
||
/** | ||
* Tests the MqttBrokerConnection class | ||
* | ||
* @author David Graeff - Initial contribution | ||
*/ | ||
public class MqttBrokerConnectionTests { | ||
@Test | ||
public void testConstructor() throws ConfigurationException { | ||
// Test tcp and ssl URLs | ||
MqttBrokerConnection a = new MqttBrokerConnection("name", "tcp://123.123.123.123", false); | ||
MqttBrokerConnection b = new MqttBrokerConnection("name", "ssl://123.123.123.123", true); | ||
assertFalse(a.isTextualConfiguredBroker()); | ||
assertTrue(b.isTextualConfiguredBroker()); | ||
} | ||
|
||
@Test(expected = ConfigurationException.class) | ||
public void testConstructorInvalidProtocol() throws ConfigurationException { | ||
new MqttBrokerConnection("name", "unsupported://123.123.123.123", false); | ||
} | ||
|
||
@Test(expected = ConfigurationException.class) | ||
public void testConstructorInvalidName() throws ConfigurationException, MqttException { | ||
new MqttBrokerConnection(" ", "tcp://123.123.123.123", false); | ||
} | ||
|
||
@Test | ||
public void messageConsumerTests() throws ConfigurationException, MqttException { | ||
final String url = "tcp://123.123.123.123"; | ||
final String name = "TestName12@!"; | ||
MqttBrokerConnection a = new MqttBrokerConnection(name, url, false); | ||
assertFalse(a.isConsumers()); | ||
MqttMessageSubscriber subscriber = mock(MqttMessageSubscriber.class); | ||
when(subscriber.getTopic()).thenAnswer(i -> "topic"); | ||
a.addConsumer(subscriber); | ||
assertTrue(a.isConsumers()); | ||
a.removeConsumer(subscriber); | ||
assertFalse(a.isConsumers()); | ||
} | ||
|
||
@Test | ||
public void connectionObserverTests() throws ConfigurationException { | ||
final String url = "tcp://123.123.123.123"; | ||
final String name = "TestName12@!"; | ||
MqttBrokerConnection a = new MqttBrokerConnection(name, url, false); | ||
assertFalse(a.isConnectionObservers()); | ||
MqttConnectionObserver connectionObserver = mock(MqttConnectionObserver.class); | ||
a.addConnectionObserver(connectionObserver); | ||
// Adding a connection observer should immediately call its setConnected() method. | ||
verify(connectionObserver).setConnected(false); | ||
|
||
assertTrue(a.isConnectionObservers()); | ||
a.removeConnectionObserver(connectionObserver); | ||
assertFalse(a.isConnectionObservers()); | ||
} | ||
|
||
@Test | ||
public void setterGetterTests() throws ConfigurationException { | ||
final String url = "tcp://123.123.123.123"; | ||
final String name = "TestName12@!"; | ||
MqttBrokerConnection a = new MqttBrokerConnection(name, url, false); | ||
assertEquals("URL getter", a.getUrl(), url); | ||
assertEquals("Name getter", a.getName(), name); | ||
|
||
a.setClientId("clientid"); | ||
assertEquals("ClientID getter/setter", "clientid", a.getClientId()); | ||
// client ids longer than 23 characters should be ignored | ||
a.setClientId("clientidclientidclientidclientid"); | ||
assertEquals("ClientID too long check", "clientid", a.getClientId()); | ||
|
||
a.setCredentials("user@!", "password123@^"); | ||
assertEquals("User getter/setter", "user@!", a.getUser()); | ||
assertEquals("Password getter/setter", "password123@^", a.getPassword()); | ||
|
||
assertEquals(MqttBrokerConnection.DEFAULT_KEEPALIVE_INTERVAL, a.getKeepAliveInterval()); | ||
a.setKeepAliveInterval(80); | ||
assertEquals(80, a.getKeepAliveInterval()); | ||
|
||
assertFalse(a.isRetain()); | ||
a.setRetain(true); | ||
assertTrue(a.isRetain()); | ||
|
||
assertNull(a.getLastWill()); | ||
assertNull(MqttWillAndTestament.fromString("")); | ||
a.setLastWill(MqttWillAndTestament.fromString("topic:message:1:true")); | ||
assertTrue(a.getLastWill().getTopic().equals("topic")); | ||
assertEquals(1, a.getLastWill().getQos()); | ||
assertEquals(true, a.getLastWill().isRetain()); | ||
byte b[] = { 'm', 'e', 's', 's', 'a', 'g', 'e' }; | ||
assertTrue(Arrays.equals(a.getLastWill().getPayload(), b)); | ||
|
||
assertEquals(MqttBrokerConnection.DEFAULT_QOS, a.getQos()); | ||
a.setQos(10); | ||
assertEquals(MqttBrokerConnection.DEFAULT_QOS, a.getQos()); | ||
a.setQos(-10); | ||
assertEquals(MqttBrokerConnection.DEFAULT_QOS, a.getQos()); | ||
a.setQos(2); | ||
assertEquals(2, a.getQos()); | ||
a.setQos(1); | ||
assertEquals(1, a.getQos()); | ||
|
||
// Check for default ssl context provider and reconnect policy | ||
assertNotNull(a.getSSLContextProvider()); | ||
assertNotNull(a.getReconnectPolicy()); | ||
|
||
assertFalse(a.isConnected()); | ||
} | ||
} |
97 changes: 97 additions & 0 deletions
97
...qtt.test/src/test/java/org/eclipse/smarthome/io/transport/mqtt/test/MqttServiceTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/** | ||
* Copyright (c) 2014-2017 by the respective copyright holders. | ||
* All rights reserved. This program and the accompanying materials | ||
* are made available under the terms of the Eclipse Public License v1.0 | ||
* which accompanies this distribution, and is available at | ||
* http://www.eclipse.org/legal/epl-v10.html | ||
*/ | ||
package org.eclipse.smarthome.io.transport.mqtt.test; | ||
|
||
import static org.hamcrest.collection.IsCollectionWithSize.hasSize; | ||
import static org.junit.Assert.*; | ||
import static org.mockito.Mockito.*; | ||
|
||
import java.util.Dictionary; | ||
import java.util.Hashtable; | ||
import java.util.Map; | ||
|
||
import javax.naming.ConfigurationException; | ||
|
||
import org.eclipse.paho.client.mqttv3.MqttException; | ||
import org.eclipse.smarthome.io.transport.mqtt.MqttBrokerConnection; | ||
import org.eclipse.smarthome.io.transport.mqtt.MqttBrokersObserver; | ||
import org.eclipse.smarthome.io.transport.mqtt.MqttService; | ||
import org.junit.Test; | ||
|
||
/** | ||
* Tests the MqttService class | ||
* | ||
* @author David Graeff - Initial contribution | ||
*/ | ||
public class MqttServiceTests { | ||
// Tests addBrokersListener/removeBrokersListener | ||
@Test | ||
public void brokerConnectionListenerTests() throws ConfigurationException { | ||
MqttService service = new MqttService(); | ||
assertFalse(service.isBrokerObservers()); | ||
MqttBrokersObserver observer = mock(MqttBrokersObserver.class); | ||
|
||
service.addBrokersListener(observer); | ||
assertTrue(service.isBrokerObservers()); | ||
|
||
MqttBrokerConnection connection = new MqttBrokerConnection("name", "tcp://123.123.123.123", false); | ||
assertTrue(service.addBrokerConnection(connection)); | ||
verify(observer).brokerAdded(connection); | ||
|
||
service.removeBrokerConnection(connection); | ||
verify(observer).brokerRemoved(connection); | ||
|
||
service.removeBrokersListener(observer); | ||
assertFalse(service.isBrokerObservers()); | ||
} | ||
|
||
// Tests extractBrokerConfigurations() and addBrokerConnection(map) | ||
@Test | ||
public void textualConfigurationTests() throws ConfigurationException, MqttException { | ||
MqttService service = new MqttService(); | ||
|
||
Dictionary<String, String> properties = new Hashtable<>(); | ||
properties.put("bam.name", "brokername"); | ||
properties.put("bam.url", "tcp://123.123.123.123"); | ||
Map<String, Map<String, String>> map = service.extractBrokerConfigurations(properties); | ||
assertEquals(map.size(), 1); | ||
Map<String, String> data = map.get("bam"); | ||
assertNotNull(data); | ||
assertEquals("brokername", data.get("name")); | ||
assertEquals("tcp://123.123.123.123", data.get("url")); | ||
|
||
assertThat(service.getAllBrokerConnections(), hasSize(0)); | ||
service.addBrokerConnection(data); | ||
assertThat(service.getAllBrokerConnections(), hasSize(1)); | ||
assertNotNull(service.getBrokerConnection("brokername")); | ||
} | ||
|
||
@Test | ||
public void brokerConnectionAddRemoveEnumerateTests() { | ||
MqttService service = new MqttService(); | ||
MqttBrokerConnection connection; | ||
try { | ||
connection = new MqttBrokerConnection("name", "tcp://123.123.123.123", false); | ||
} catch (ConfigurationException c) { | ||
fail("Couldn't create a MqttBrokerConnection object"); | ||
return; | ||
} | ||
// Add | ||
assertThat(service.getAllBrokerConnections(), hasSize(0)); | ||
assertTrue(service.addBrokerConnection(connection)); | ||
assertFalse(service.addBrokerConnection(connection)); | ||
|
||
// Get/Enumerate | ||
assertNotNull(service.getBrokerConnection("name")); | ||
assertThat(service.getAllBrokerConnections(), hasSize(1)); | ||
|
||
// Remove | ||
service.removeBrokerConnection(connection); | ||
assertThat(service.getAllBrokerConnections(), hasSize(0)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.