Skip to content

Commit 7d5ae68

Browse files
committed
Merge pull request #40 from garyrussell/mqtt
* garyrussell-mqtt: INTEXT-64 - Polishing INTEXT-64 MQTT Adapters
2 parents b139943 + ac43f8e commit 7d5ae68

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+2946
-1
lines changed

README.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ The Spring Integration Extensions project provides extension modules for [Spring
1111
* [XQuery][] Support
1212
* [Splunk][] Support
1313
* [Amazon Web Services (AWS)][] Support
14+
* [MQ Telemetry Transport (MQTT)][] Support
1415

1516
## Samples
1617

@@ -133,4 +134,5 @@ The Spring Integration Extensions Framework is released under version 2.0 of the
133134
[Websockets]: http://www.html5rocks.com/en/tutorials/websockets/basics/
134135
[XQuery]: http://en.wikipedia.org/wiki/XQuery
135136
[Splunk]:http://www.splunk.com/
136-
[Amazon Web Services (AWS)]: http://aws.amazon.com/
137+
[Amazon Web Services (AWS)]: http://aws.amazon.com/
138+
[MQ Telemetry Transport (MQTT)]: http://mqtt.org/

spring-integration-mqtt/README.md

+77
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
Spring Integration Mqtt Adapters
2+
=================================================
3+
4+
`inbound` and `outbound` channel adapters are provided for [MQ Telemetry Transport (MQTT)][]. The current implementation uses the [Eclipse Paho][] client.
5+
6+
Example configurations...
7+
8+
<int-mqtt:message-driven-channel-adapter id="twoTopicsAdapter"
9+
client-id="foo"
10+
url="tcp://localhost:1883"
11+
topics="bar, baz"
12+
channel="out" />
13+
14+
<int-mqtt:outbound-channel-adapter id="withDefaultConverter"
15+
client-id="foo"
16+
url="tcp://localhost:1883"
17+
default-qos="1"
18+
default-retained="true"
19+
default-topic="bar"
20+
channel="target" />
21+
22+
23+
Spring integration messages sent to the outbound adapter can have headers `mqtt_topic, mqtt_qos, mqtt_retained` which will override the defaults configured on the adapter.
24+
25+
Inbound messages will have headers
26+
27+
mqtt_topic - the topic from which the message was received
28+
mqtt_duplicate - true if the message is a duplicate
29+
mqtt_qos - the quality of service
30+
31+
32+
33+
Both adapters use a `MqttPahoClientFactory` to get a client instance; the same factory also provides connection options from configured properties (such as user/password). The client factory bean (`DefaultMqttPahoClientFactory`) is provided to the adapter using the `client-factory` attribute. When not provided, a default factory instance is used.
34+
35+
36+
Currently tested with the RabbitMQ MQTT plugin.
37+
38+
39+
##Note:
40+
41+
Currently, the Paho java client is not mavenized; there is an [open paho bug][] to resolve this. In the meantime, you can manually add the jar to your maven repo:
42+
43+
mvn install:install-file -DgroupId=org.eclipse.paho -DartifactId=MQTT-Java -Dversion=3.0 -Dpackaging=jar -Dfile=/path/to/org.eclipse.paho.client.mqttv3.jar
44+
45+
46+
47+
Check out the [Spring Integration forums][] and the [spring-integration][spring-integration tag] tag
48+
on [Stack Overflow][]. [Commercial support][] is available, too.
49+
50+
## Related GitHub projects
51+
52+
* [Spring Integration][]
53+
* [Spring Integration Samples][]
54+
* [Spring Integration Templates][]
55+
* [Spring Integration Dsl Groovy][]
56+
* [Spring Integration Dsl Scala][]
57+
* [Spring Integration Pattern Catalog][]
58+
59+
For more information, please also don't forget to visit the [Spring Integration][] website.
60+
61+
## Eclipse Paho
62+
63+
* [Eclipse Paho][]
64+
65+
[Spring Integration]: https://github.com/SpringSource/spring-integration
66+
[Commercial support]: http://springsource.com/support/springsupport
67+
[Spring Integration forums]: http://forum.springsource.org/forumdisplay.php?42-Integration
68+
[spring-integration tag]: http://stackoverflow.com/questions/tagged/spring-integration
69+
[Spring Integration Samples]: https://github.com/SpringSource/spring-integration-samples
70+
[Spring Integration Templates]: https://github.com/SpringSource/spring-integration-templates/tree/master/si-sts-templates
71+
[Spring Integration Dsl Groovy]: https://github.com/SpringSource/spring-integration-dsl-groovy
72+
[Spring Integration Dsl Scala]: https://github.com/SpringSource/spring-integration-dsl-scala
73+
[Spring Integration Pattern Catalog]: https://github.com/SpringSource/spring-integration-pattern-catalog
74+
[Stack Overflow]: http://stackoverflow.com/faq
75+
[Eclipse Paho]: http://www.eclipse.org/paho/
76+
[open paho bug]: https://bugs.eclipse.org/bugs/show_bug.cgi?id=382471
77+
[MQ Telemetry Transport (MQTT)]: http://mqtt.org/

spring-integration-mqtt/build.gradle

+253
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
description = 'Spring Integration MQTT Adapter'
2+
3+
buildscript {
4+
repositories {
5+
maven { url 'https://repo.springsource.org/plugins-snapshot' }
6+
}
7+
}
8+
9+
apply plugin: 'java'
10+
apply from: "${rootProject.projectDir}/publish-maven.gradle"
11+
apply plugin: 'eclipse'
12+
apply plugin: 'idea'
13+
14+
group = 'org.springframework.integration.mqtt'
15+
16+
repositories {
17+
maven { url 'http://repo.springsource.org/libs-snapshot' }
18+
maven { url 'http://repo.springsource.org/plugins-release' }
19+
mavenLocal()
20+
}
21+
22+
sourceCompatibility=1.6
23+
targetCompatibility=1.6
24+
25+
ext {
26+
junitVersion = '4.11'
27+
log4jVersion = '1.2.17'
28+
mockitoVersion = '1.9.5'
29+
springVersion = '3.1.3.RELEASE'
30+
springIntegrationVersion = '3.0.0.BUILD-SNAPSHOT'
31+
32+
idPrefix = 'mqttadapter'
33+
}
34+
35+
eclipse {
36+
project {
37+
natures += 'org.springframework.ide.eclipse.core.springnature'
38+
}
39+
}
40+
41+
sourceSets {
42+
test {
43+
resources {
44+
srcDirs = ['src/test/resources', 'src/test/java']
45+
}
46+
}
47+
}
48+
49+
// See http://www.gradle.org/docs/current/userguide/dependency_management.html#sub:configurations
50+
// and http://www.gradle.org/docs/current/dsl/org.gradle.api.artifacts.ConfigurationContainer.html
51+
configurations {
52+
jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo
53+
}
54+
55+
dependencies {
56+
compile "org.springframework.integration:spring-integration-core:$springIntegrationVersion"
57+
compile "org.eclipse.paho:MQTT-Java:3.0"
58+
testCompile "org.springframework.integration:spring-integration-test:$springIntegrationVersion"
59+
testCompile "junit:junit-dep:$junitVersion"
60+
testCompile "log4j:log4j:$log4jVersion"
61+
testCompile "org.mockito:mockito-all:$mockitoVersion"
62+
testCompile "org.springframework:spring-test:$springVersion"
63+
jacoco group: "org.jacoco", name: "org.jacoco.agent", version: "0.6.2.201302030002", classifier: "runtime"
64+
}
65+
66+
67+
// enable all compiler warnings; individual projects may customize further
68+
ext.xLintArg = '-Xlint:all'
69+
[compileJava, compileTestJava]*.options*.compilerArgs = [xLintArg]
70+
71+
test {
72+
// suppress all console output during testing unless running `gradle -i`
73+
logging.captureStandardOutput(LogLevel.INFO)
74+
jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=*"
75+
}
76+
77+
task sourcesJar(type: Jar) {
78+
classifier = 'sources'
79+
from sourceSets.main.allJava
80+
}
81+
82+
task javadocJar(type: Jar) {
83+
classifier = 'javadoc'
84+
from javadoc
85+
}
86+
87+
artifacts {
88+
archives sourcesJar
89+
archives javadocJar
90+
}
91+
92+
apply plugin: 'sonar'
93+
94+
sonar {
95+
96+
if (rootProject.hasProperty('sonarHostUrl')) {
97+
server.url = rootProject.sonarHostUrl
98+
}
99+
100+
database {
101+
if (rootProject.hasProperty('sonarJdbcUrl')) {
102+
url = rootProject.sonarJdbcUrl
103+
}
104+
if (rootProject.hasProperty('sonarJdbcDriver')) {
105+
driverClassName = rootProject.sonarJdbcDriver
106+
}
107+
if (rootProject.hasProperty('sonarJdbcUsername')) {
108+
username = rootProject.sonarJdbcUsername
109+
}
110+
if (rootProject.hasProperty('sonarJdbcPassword')) {
111+
password = rootProject.sonarJdbcPassword
112+
}
113+
}
114+
115+
project {
116+
dynamicAnalysis = "reuseReports"
117+
withProjectProperties { props ->
118+
props["sonar.core.codeCoveragePlugin"] = "jacoco"
119+
props["sonar.jacoco.reportPath"] = "${buildDir.name}/jacoco.exec"
120+
}
121+
}
122+
123+
logger.info("Sonar parameters used: server.url='${server.url}'; database.url='${database.url}'; database.driverClassName='${database.driverClassName}'; database.username='${database.username}'")
124+
}
125+
126+
task api(type: Javadoc) {
127+
group = 'Documentation'
128+
description = 'Generates the Javadoc API documentation.'
129+
title = "${rootProject.description} ${version} API"
130+
options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED
131+
options.author = true
132+
options.header = rootProject.description
133+
options.overview = 'src/api/overview.html'
134+
135+
source = sourceSets.main.allJava
136+
classpath = project.sourceSets.main.compileClasspath
137+
destinationDir = new File(buildDir, "api")
138+
}
139+
140+
task schemaZip(type: Zip) {
141+
group = 'Distribution'
142+
classifier = 'schema'
143+
description = "Builds -${classifier} archive containing all " +
144+
"XSDs for deployment at static.springframework.org/schema."
145+
146+
def Properties schemas = new Properties();
147+
def shortName = idPrefix.replaceFirst("${idPrefix}-", '')
148+
149+
project.sourceSets.main.resources.find {
150+
it.path.endsWith('META-INF/spring.schemas')
151+
}?.withInputStream { schemas.load(it) }
152+
153+
for (def key : schemas.keySet()) {
154+
File xsdFile = project.sourceSets.main.resources.find {
155+
it.path.endsWith(schemas.get(key))
156+
}
157+
assert xsdFile != null
158+
into ("integration/${shortName}") {
159+
from xsdFile.path
160+
}
161+
}
162+
163+
}
164+
165+
task docsZip(type: Zip) {
166+
group = 'Distribution'
167+
classifier = 'docs'
168+
description = "Builds -${classifier} archive containing the api " +
169+
"for deployment at static.springframework.org/spring-integration/docs."
170+
171+
from('src/dist') {
172+
include 'changelog.txt'
173+
}
174+
175+
from (api) {
176+
into 'api'
177+
}
178+
}
179+
180+
task distZip(type: Zip, dependsOn: [docsZip, schemaZip]) {
181+
group = 'Distribution'
182+
classifier = 'dist'
183+
description = "Builds -${classifier} archive, containing all jars and docs, " +
184+
"suitable for community download page."
185+
186+
ext.baseDir = "${project.name}-${project.version}";
187+
188+
from('src/dist') {
189+
include 'readme.txt'
190+
include 'license.txt'
191+
include 'notice.txt'
192+
into "${baseDir}"
193+
}
194+
195+
from(zipTree(docsZip.archivePath)) {
196+
into "${baseDir}/docs"
197+
}
198+
199+
from(zipTree(schemaZip.archivePath)) {
200+
into "${baseDir}/schema"
201+
}
202+
203+
into ("${baseDir}/libs") {
204+
from project.jar
205+
from project.sourcesJar
206+
from project.javadocJar
207+
}
208+
}
209+
210+
// Create an optional "with dependencies" distribution.
211+
// Not published by default; only for use when building from source.
212+
task depsZip(type: Zip, dependsOn: distZip) { zipTask ->
213+
group = 'Distribution'
214+
classifier = 'dist-with-deps'
215+
description = "Builds -${classifier} archive, containing everything " +
216+
"in the -${distZip.classifier} archive plus all dependencies."
217+
218+
from zipTree(distZip.archivePath)
219+
220+
gradle.taskGraph.whenReady { taskGraph ->
221+
if (taskGraph.hasTask(":${zipTask.name}")) {
222+
def projectName = rootProject.name
223+
def artifacts = new HashSet()
224+
225+
rootProject.configurations.runtime.resolvedConfiguration.resolvedArtifacts.each { artifact ->
226+
def dependency = artifact.moduleVersion.id
227+
if (!projectName.equals(dependency.name)) {
228+
artifacts << artifact.file
229+
}
230+
}
231+
232+
zipTask.from(artifacts) {
233+
into "${distZip.baseDir}/deps"
234+
}
235+
}
236+
}
237+
}
238+
239+
artifacts {
240+
archives distZip
241+
archives docsZip
242+
archives schemaZip
243+
}
244+
245+
task dist(dependsOn: assemble) {
246+
group = 'Distribution'
247+
description = 'Builds -dist, -docs and -schema distribution archives.'
248+
}
249+
250+
task wrapper(type: Wrapper) {
251+
description = 'Generates gradlew[.bat] scripts'
252+
gradleVersion = '1.6'
253+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
version=1.0.0.BUILD-SNAPSHOT
Binary file not shown.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#Wed May 15 15:57:24 EDT 2013
2+
distributionBase=GRADLE_USER_HOME
3+
distributionPath=wrapper/dists
4+
zipStoreBase=GRADLE_USER_HOME
5+
zipStorePath=wrapper/dists
6+
distributionUrl=http\://services.gradle.org/distributions/gradle-1.6-bin.zip

0 commit comments

Comments
 (0)