├── example-consumer
├── src
│ ├── main
│ │ ├── resources
│ │ │ └── application.yml
│ │ └── java
│ │ │ └── com
│ │ │ └── bosch
│ │ │ └── iothub
│ │ │ └── examples
│ │ │ ├── Application.java
│ │ │ ├── AppConfiguration.java
│ │ │ └── ExampleConsumer.java
│ └── test
│ │ └── java
│ │ └── com
│ │ └── bosch
│ │ └── iothub
│ │ └── examples
│ │ └── ExampleConsumerTest.java
├── README.md
└── pom.xml
├── command-and-control
├── src
│ └── main
│ │ ├── resources
│ │ └── application.yml
│ │ └── java
│ │ └── com
│ │ └── bosch
│ │ └── iothub
│ │ └── examples
│ │ ├── Application.java
│ │ ├── AppConfiguration.java
│ │ └── OneWayCommand.java
├── README.md
└── pom.xml
├── .gitignore
├── LICENSE
├── README.md
├── tinaworkflow.xml
└── pom.xml
/example-consumer/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | hono:
2 | client:
3 | host: messaging.bosch-iot-hub.com
--------------------------------------------------------------------------------
/command-and-control/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | hono:
2 | client:
3 | host: messaging.bosch-iot-hub.com
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Created by .ignore support plugin (hsz.mobi)
2 | target/
3 | .idea/
4 | example-consumer/example-receiver.iml
5 | *.iml
6 | .vertx/
7 |
--------------------------------------------------------------------------------
/command-and-control/src/main/java/com/bosch/iothub/examples/Application.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Bosch.IO GmbH. All rights reserved.
3 | */
4 | package com.bosch.iothub.examples;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 |
9 | @SpringBootApplication
10 | public class Application {
11 | public static void main(final String[] args) {
12 | SpringApplication.run(Application.class, args);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/example-consumer/src/main/java/com/bosch/iothub/examples/Application.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Bosch.IO GmbH. All rights reserved.
3 | */
4 | package com.bosch.iothub.examples;
5 |
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 |
9 | @SpringBootApplication
10 | public class Application {
11 |
12 | public static void main(final String[] args) {
13 | SpringApplication.run(Application.class, args);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/example-consumer/README.md:
--------------------------------------------------------------------------------
1 | # Example Consumer Application
2 |
3 | The example consumer application shows how to connect Hono client to the IoT Hub messaging (consumer) endpoint and create a telemetry consumer in order to consume telemetry messages. An existing IoT Hub service instance and a valid tenant ID are needed to run the example application. Please consult [IoT Hub documentation](https://docs.bosch-iot-hub.com/booktenant.html) on how to book a IoT Hub service instance.
4 |
5 | ## Build and Package
6 |
7 | To build and package the application as a runnable JAR file run:
8 |
9 | ~~~
10 | mvn clean package -DskipTests
11 | ~~~
12 |
13 | ## Run Example Consumer Application
14 |
15 | The example consumer application needs a few parameters set to run. Please make sure the following are set correctly:
16 |
17 | * `messaging-username`: the username for the IoT Hub messaging endpoint (messaging@tenant-id)
18 | * `messaging-password`: the password for the IoT Hub messaging endpoint
19 | * `tenant-id`: the tenant ID
20 |
21 | All the information needed for setting these parameters can be found in the 'Credentials' information of a IoT Hub service subscription information.
22 |
23 | To start the example consumer application (Linux & Mac), run:
24 |
25 | ~~~
26 | java -jar example-consumer/target/example-consumer-1.0-SNAPSHOT.jar --hono.client.tlsEnabled=true --hono.client.username={messaging-username} --hono.client.password={messaging-password} --tenant.id={tenant-id}
27 | ~~~
28 |
29 | The consumer application is ready as soon as 'Consumer ready' is printed on the console. The startup can take up to 10 seconds.
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Bosch SI Example Code License
2 | Version 1.0, January 2016
3 |
4 | Copyright 2020 Bosch.IO GmbH. All rights reserved.
5 |
6 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
7 | following conditions are met:
8 |
9 | 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
10 | disclaimer.
11 |
12 | 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
13 | following disclaimer in the documentation and/or other materials provided with the distribution.
14 |
15 | BOSCH SI PROVIDES THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT
16 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO
17 | THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
18 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION. THIS SHALL NOT APPLY TO MATERIAL DEFECTS AND DEFECTS OF TITLE WHICH
19 | BOSCH SI HAS FRAUDULENTLY CONCEALED. APART FROM THE CASES STIPULATED ABOVE, BOSCH SI SHALL BE LIABLE WITHOUT
20 | LIMITATION FOR INTENT OR GROSS NEGLIGENCE, FOR INJURIES TO LIFE, BODY OR HEALTH AND ACCORDING TO THE PROVISIONS OF
21 | THE GERMAN PRODUCT LIABILITY ACT (PRODUKTHAFTUNGSGESETZ). THE SCOPE OF A GUARANTEE GRANTED BY BOSCH SI SHALL REMAIN
22 | UNAFFECTED BY LIMITATIONS OF LIABILITY. IN ALL OTHER CASES, LIABILITY OF BOSCH SI IS EXCLUDED. THESE LIMITATIONS OF
23 | LIABILITY ALSO APPLY IN REGARD TO THE FAULT OF VICARIOUS AGENTS OF BOSCH SI AND THE PERSONAL LIABILITY OF BOSCH SI'S
24 | EMPLOYEES, REPRESENTATIVES AND ORGANS.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # [Repo Archived]
2 | This repo is archived because Bosch IoT Hub is no longer available as a standalone offering. IoT Hub is part of the Bosch IoT Device Management. If you are interested check out the [getting started guide for IoT Device Management](https://docs.bosch-iot-suite.com/device-management/Getting-started.html).
3 |
4 | # Examples for Bosch IoT Hub Cloud Service
5 | This repository contains examples for using the Bosch IoT Hub service in the cloud.
6 |
7 | Bosch IoT Hub is part of the [Bosch IoT Suite](https://www.bosch-iot-suite.com), which is a cloud-based IoT platform provided by Bosch Software Innovations, as part of the Bosch Group.
8 | Further background information regarding the platform is also available at the [Bosch Software Innovations](https://www.bosch-si.com/iot-platform/bosch-iot-suite/homepage-bosch-iot-suite.html) site.
9 |
10 | ## Examples
11 |
12 | The example code provided here shows a selection of the Bosch IoT Hub service functionality. However, the examples do not cover the complete service offering. If you need more information, please visit the links above or contact us.
13 |
14 | ### Example Consumer Application
15 | The example consumer application shows how to connect Hono client to the IoT Hub messaging (consumer) endpoint and create a telemetry consumer in order to consume telemetry messages. For details on how to build and start the example consumer application, please consult the example application [readme](example-consumer/README.md).
16 |
17 | ### Example Command & Control Application
18 | The application shows how to connect to the IoT Hub messaging endpoint and send a command to a device in one-way mode.
19 | See specific [readme](command-and-control/README.md) for more details.
20 |
21 | ## Acknowledgments
22 | The IoT Hub examples make use of the following open source software:
23 |
24 | * [Eclipse Hono](https://www.eclipse.org/hono/)
25 | * [Eclipse Vertx](https://vertx.io/)
26 |
27 | ## License
28 |
29 | The examples are made available under the terms of Bosch SI Example Code License. See individual files for details.
30 |
31 | ## Disclaimer
32 | All product names, service names, company names, logos, trademarks and brands are property of their respective owners. They are used in these examples for identification purposes only. Use of them does not imply any affiliation with or endorsement by them.
33 |
--------------------------------------------------------------------------------
/command-and-control/README.md:
--------------------------------------------------------------------------------
1 | # Command & Control Application
2 |
3 | The application shows how to connect to the IoT Hub messaging endpoint and send a command to a device in one-way mode.
4 | It sends automatically a "switchLight" command with the payload "On" to a device which must be connected.
5 |
6 | For a more complex example see the [Hono example application](https://github.com/eclipse/hono/tree/master/example).
7 | The guide only works for Linux & Mac systems, for MS Windows you have to adapt the paths and options.
8 |
9 | # Prerequisites
10 |
11 | following software must be installed:
12 |
13 | * Java 8 (Oracle JDK or OpenJDK) or newer
14 | * maven 3.5.2 or newer
15 | * [mosquitto_sub](https://mosquitto.org/) for subscribing to receive commands
16 |
17 |
18 | An existing IoT Hub service instance and a valid tenant ID are needed to run the application.
19 | Please consult [IoT Hub documentation](https://docs.bosch-iot-hub.com/booktenant.html) on how to book a IoT Hub service instance.
20 | In the 'Credentials' information of a IoT Hub service subscription information, you will find the 'tenant-id', the 'messaging-username' and 'messaging-password'.
21 | Please register a device and setup password credentials. You will need the 'device-id', 'auth-id' and the matching secret for the 'auth-id'.
22 |
23 | ## Subscribe to receive commands
24 |
25 | To receive commands, a device must subscribe to a specific command topic.
26 | As exemplary device the Eclipse Mosquitto MQTT client is used. Please make sure auth-id and the matching secret is set correctly.
27 |
28 | ~~~
29 | mosquitto_sub -d -h mqtt.bosch-iot-hub.com -p 8883 -k 30 -u {auth-id}@{tenant-id} -P {secret} --capath /etc/ssl/certs/ -t command/+/+/req/#
30 | ~~~
31 |
32 | ## Send commands
33 |
34 | To build and package the application as a runnable JAR file run:
35 |
36 | ~~~
37 | mvn clean package -DskipTests
38 | ~~~
39 |
40 | The command application needs a few parameters set to run. Please make sure the following are set correctly:
41 |
42 | * `messaging-username`: the username for the IoT Hub messaging endpoint (messaging@tenant-id)
43 | * `messaging-password`: the password for the IoT Hub messaging endpoint
44 | * `tenant-id`: the tenant ID
45 | * `device-id`: a device ID to send command
46 |
47 |
48 | To start the application, run:
49 |
50 | ~~~
51 | java -jar target/command-and-control-1.0-SNAPSHOT.jar --hono.client.tlsEnabled=true --hono.client.username={messaging-username} --hono.client.password={messaging-password} --tenant.id={tenant-id} --device.id={device-id}
52 | ~~~
53 |
54 | The application will connect to the IoT Hub and send the command to a subscribed device. You should see the received command in the 'mosquitto_sub' output.
--------------------------------------------------------------------------------
/command-and-control/src/main/java/com/bosch/iothub/examples/AppConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Bosch.IO GmbH. All rights reserved.
3 | */
4 | package com.bosch.iothub.examples;
5 |
6 | import io.vertx.core.Vertx;
7 | import io.vertx.core.VertxOptions;
8 | import io.vertx.core.dns.AddressResolverOptions;
9 | import org.eclipse.hono.client.ApplicationClientFactory;
10 | import org.eclipse.hono.client.HonoConnection;
11 | import org.eclipse.hono.client.impl.HonoConnectionImpl;
12 | import org.eclipse.hono.config.ClientConfigProperties;
13 | import org.eclipse.hono.connection.ConnectionFactory;
14 | import org.eclipse.hono.connection.impl.ConnectionFactoryImpl;
15 | import org.springframework.boot.context.properties.ConfigurationProperties;
16 | import org.springframework.context.annotation.Bean;
17 | import org.springframework.context.annotation.Configuration;
18 |
19 | /**
20 | * Configuration for Example application.
21 | */
22 | @Configuration
23 | public class AppConfiguration {
24 |
25 | private static final int DEFAULT_ADDRESS_RESOLUTION_TIMEOUT = 2000;
26 |
27 | /**
28 | * Exposes a Vert.x instance as a Spring bean.
29 | *
30 | * @return The Vert.x instance.
31 | */
32 | @Bean
33 | public Vertx vertx() {
34 | VertxOptions options = new VertxOptions()
35 | .setAddressResolverOptions(new AddressResolverOptions()
36 | .setCacheNegativeTimeToLive(0) // discard failed DNS lookup results immediately
37 | .setCacheMaxTimeToLive(0) // support DNS based service resolution
38 | .setRotateServers(true)
39 | .setQueryTimeout(DEFAULT_ADDRESS_RESOLUTION_TIMEOUT));
40 | return Vertx.vertx(options);
41 | }
42 |
43 | /**
44 | * Exposes client configuration properties as a Spring bean.
45 | *
46 | * @return The properties.
47 | */
48 | @ConfigurationProperties(prefix = "hono.client")
49 | @Bean
50 | public ClientConfigProperties honoClientConfig() {
51 | return new ClientConfigProperties();
52 | }
53 |
54 | /**
55 | * Exposes a factory for connections to the Hono server
56 | * as a Spring bean.
57 | *
58 | * @return The connection factory.
59 | */
60 | @Bean
61 | public ConnectionFactory honoConnectionFactory() {
62 | return new ConnectionFactoryImpl(vertx(), honoClientConfig());
63 | }
64 |
65 |
66 | /**
67 | * Exposes a {@code HonoConnection} as a Spring bean.
68 | *
69 | * @return The Hono connection.
70 | */
71 | @Bean
72 | public HonoConnection honoConnection() {
73 | return new HonoConnectionImpl(vertx(), honoConnectionFactory(), honoClientConfig());
74 | }
75 |
76 | /**
77 | * Exposes a {@code ApplicationClientFactory} as a Spring bean.
78 | * @return The Application client factory
79 | */
80 | @Bean
81 | public ApplicationClientFactory clientFactory() {
82 | return ApplicationClientFactory.create(honoConnection());
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/example-consumer/src/main/java/com/bosch/iothub/examples/AppConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Bosch.IO GmbH. All rights reserved.
3 | */
4 | package com.bosch.iothub.examples;
5 |
6 | import io.vertx.core.Vertx;
7 | import io.vertx.core.VertxOptions;
8 | import io.vertx.core.dns.AddressResolverOptions;
9 | import org.eclipse.hono.client.ApplicationClientFactory;
10 | import org.eclipse.hono.client.HonoConnection;
11 | import org.eclipse.hono.client.impl.HonoConnectionImpl;
12 | import org.eclipse.hono.config.ClientConfigProperties;
13 | import org.eclipse.hono.connection.ConnectionFactory;
14 | import org.eclipse.hono.connection.impl.ConnectionFactoryImpl;
15 | import org.springframework.boot.context.properties.ConfigurationProperties;
16 | import org.springframework.context.annotation.Bean;
17 | import org.springframework.context.annotation.Configuration;
18 |
19 | /**
20 | * Configuration for Example application.
21 | */
22 | @Configuration
23 | public class AppConfiguration {
24 |
25 | private static final int DEFAULT_ADDRESS_RESOLUTION_TIMEOUT = 2000;
26 |
27 | /**
28 | * Exposes a Vert.x instance as a Spring bean.
29 | *
30 | * @return The Vert.x instance.
31 | */
32 | @Bean
33 | public Vertx vertx() {
34 | VertxOptions options = new VertxOptions()
35 | .setAddressResolverOptions(new AddressResolverOptions()
36 | .setCacheNegativeTimeToLive(0) // discard failed DNS lookup results immediately
37 | .setCacheMaxTimeToLive(0) // support DNS based service resolution
38 | .setRotateServers(true)
39 | .setQueryTimeout(DEFAULT_ADDRESS_RESOLUTION_TIMEOUT));
40 | return Vertx.vertx(options);
41 | }
42 |
43 | /**
44 | * Exposes client configuration properties as a Spring bean.
45 | *
46 | * @return The properties.
47 | */
48 | @ConfigurationProperties(prefix = "hono.client")
49 | @Bean
50 | public ClientConfigProperties honoClientConfig() {
51 | return new ClientConfigProperties();
52 | }
53 |
54 | /**
55 | * Exposes a factory for connections to the Hono server
56 | * as a Spring bean.
57 | *
58 | * @return The connection factory.
59 | */
60 | @Bean
61 | public ConnectionFactory honoConnectionFactory() {
62 | return new ConnectionFactoryImpl(vertx(), honoClientConfig());
63 | }
64 |
65 |
66 | /**
67 | * Exposes a {@code HonoConnection} as a Spring bean.
68 | *
69 | * @return The Hono connection.
70 | */
71 | @Bean
72 | public HonoConnection honoConnection() {
73 | return new HonoConnectionImpl(vertx(), honoConnectionFactory(), honoClientConfig());
74 | }
75 |
76 | /**
77 | * Exposes a {@code ApplicationClientFactory} as a Spring bean.
78 | * @return The Application client factory
79 | */
80 | @Bean
81 | public ApplicationClientFactory clientFactory() {
82 | return ApplicationClientFactory.create(honoConnection());
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/tinaworkflow.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | IQ Analyzer
5 | com.bosch.tina.clm.SonatypeCLMCliAnalyzer
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Source Validator
21 | org.eclipse.sw360.antenna.validators.workflow.processors.SourceValidator
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Security Issue Validator
30 | org.eclipse.sw360.antenna.validators.workflow.processors.SecurityIssueValidator
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | License Validator
42 | org.eclipse.sw360.antenna.validators.workflow.processors.LicenseValidator
43 |
44 |
45 |
46 |
47 |
48 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | PDF Report Generator
57 | com.bosch.tina.workflow.generators.BoschDisclosureDocumentGenerator
58 |
59 |
60 |
62 |
63 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/command-and-control/src/main/java/com/bosch/iothub/examples/OneWayCommand.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Bosch.IO GmbH. All rights reserved.
3 | */
4 | package com.bosch.iothub.examples;
5 |
6 | import io.vertx.core.Future;
7 | import io.vertx.core.buffer.Buffer;
8 | import org.eclipse.hono.client.ApplicationClientFactory;
9 | import org.eclipse.hono.client.CommandClient;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.beans.factory.annotation.Value;
14 | import org.springframework.boot.ExitCodeGenerator;
15 | import org.springframework.boot.SpringApplication;
16 | import org.springframework.context.ApplicationContext;
17 | import org.springframework.stereotype.Component;
18 |
19 | import javax.annotation.PostConstruct;
20 | import java.util.concurrent.TimeUnit;
21 |
22 | @Component
23 | public class OneWayCommand {
24 | private static final Logger LOG = LoggerFactory.getLogger(OneWayCommand.class);
25 |
26 | @Value(value = "${tenant.id}")
27 | protected String tenantId;
28 |
29 | @Value(value = "${device.id}")
30 | protected String deviceId;
31 |
32 | private final ApplicationClientFactory clientFactory;
33 | private final ApplicationContext appContext;
34 |
35 | @Autowired
36 | public OneWayCommand(ApplicationClientFactory clientFactory, ApplicationContext appContext) {
37 | this.clientFactory = clientFactory;
38 | this.appContext = appContext;
39 | }
40 |
41 | @PostConstruct
42 | private void start() {
43 | LOG.info("Connecting to IoT Hub messaging endpoint...");
44 | clientFactory.connect().compose(connectedClient -> {
45 | LOG.info("Connected to IoT Hub messaging endpoint.");
46 | final Future commandClientFuture = clientFactory.getOrCreateCommandClient(tenantId);
47 | commandClientFuture.setHandler(commandClientResult -> {
48 | final CommandClient commandClient = commandClientResult.result();
49 | sendOneWayCommand(commandClient);
50 | });
51 | return Future.succeededFuture();
52 | }).otherwise(connectException -> {
53 | LOG.info("Connecting or creating a command client failed with an exception: ", connectException);
54 | return null;
55 | });
56 | }
57 |
58 | private void sendOneWayCommand(CommandClient commandClient) {
59 | LOG.info("Send command (one-way mode) to device '{}'", deviceId);
60 | commandClient.setRequestTimeout(TimeUnit.SECONDS.toMillis(2)); // increase to avoid errors with 200 ms default timeout
61 | final Buffer data = Buffer.buffer("on");
62 | final Future commandResult = commandClient.sendOneWayCommand(deviceId, "switchLight", data);
63 | commandResult.setHandler(result -> {
64 | if (result.succeeded()) {
65 | LOG.info("Command successfully send");
66 | SpringApplication.exit(appContext, (ExitCodeGenerator) () -> 0);
67 | } else {
68 | LOG.error("Command not successfully send: {}", result.cause().getMessage());
69 | SpringApplication.exit(appContext, (ExitCodeGenerator) () -> 1);
70 | }
71 | });
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/example-consumer/src/test/java/com/bosch/iothub/examples/ExampleConsumerTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Bosch.IO GmbH. All rights reserved.
3 | */
4 | package com.bosch.iothub.examples;
5 |
6 | import io.vertx.core.Vertx;
7 | import io.vertx.core.VertxOptions;
8 | import io.vertx.core.dns.AddressResolverOptions;
9 | import io.vertx.ext.unit.Async;
10 | import io.vertx.ext.unit.TestContext;
11 | import io.vertx.ext.unit.junit.VertxUnitRunner;
12 | import org.eclipse.hono.client.ApplicationClientFactory;
13 | import org.eclipse.hono.client.HonoConnection;
14 | import org.eclipse.hono.config.ClientConfigProperties;
15 | import org.junit.*;
16 | import org.junit.runner.RunWith;
17 | import org.slf4j.Logger;
18 | import org.slf4j.LoggerFactory;
19 |
20 | @RunWith(VertxUnitRunner.class)
21 | public class ExampleConsumerTest {
22 | private static final Logger LOG = LoggerFactory.getLogger(ExampleConsumerTest.class);
23 | private static final String IOT_HUB_MESSAGING_HOST = "iot-hub.messaging.host";
24 | private static final String IOT_HUB_TENANT_ID = "iot-hub.tenant.id";
25 | private static final String HONO_CLIENT_USERNAME = "hono.client.user";
26 | private static final String HONO_CLIENT_PASSWORD = "hono.client.password";
27 |
28 | private static Vertx vertx;
29 | private static ApplicationClientFactory clientFactory;
30 | private static ExampleConsumer exampleConsumer;
31 |
32 | @BeforeClass()
33 | public static void beforeClass() {
34 | vertx = Vertx.vertx(new VertxOptions().setWarningExceptionTime(1000 * 1500000000)
35 | .setAddressResolverOptions(new AddressResolverOptions().setCacheMaxTimeToLive(0) // support DNS based service resolution
36 | .setQueryTimeout(1000)));
37 | final ClientConfigProperties clientConfig = new ClientConfigProperties();
38 | clientConfig.setTlsEnabled(true);
39 | clientConfig.setHost(System.getProperty(IOT_HUB_MESSAGING_HOST));
40 | clientConfig.setUsername(System.getProperty(HONO_CLIENT_USERNAME));
41 | clientConfig.setPassword(System.getProperty(HONO_CLIENT_PASSWORD));
42 | clientConfig.setReconnectAttempts(0);
43 | clientFactory = ApplicationClientFactory.create(HonoConnection.newConnection(vertx, clientConfig));
44 | exampleConsumer = new ExampleConsumer();
45 | exampleConsumer.setClientFactory(clientFactory);
46 | exampleConsumer.setTenantId(System.getProperty(IOT_HUB_TENANT_ID));
47 | }
48 |
49 | @AfterClass
50 | public static void afterClass() {
51 | clientFactory.disconnect();
52 | vertx.close();
53 | }
54 |
55 | @Test
56 | public void testHonoClientConnection(final TestContext context) {
57 | final Async async = context.async();
58 | final String testName = "Hono Client: IoT Hub Connection Test.";
59 |
60 | LOG.info("[{}]: Starting...", testName);
61 |
62 | exampleConsumer.clientFactoryConnect(null).setHandler(clientConnected -> {
63 | context.assertTrue(clientConnected.succeeded(), "[" + testName +"]: Hono client connection attempt test failed.");
64 | LOG.info("[{}]: Hono client connection attempt test succeeded.", testName);
65 | clientFactory.isConnected().setHandler(result -> {
66 | context.assertTrue(result.succeeded(), "[" + testName +"]: Hono client failed to connect.");
67 | LOG.info("[{}]: Hono client connected.", testName);
68 | async.complete();
69 | });
70 | });
71 | }
72 |
73 | @Test
74 | public void testConsumerConnection(final TestContext context) {
75 | final Async async = context.async();
76 | final String testName = "Telemetry Consumer: IoT Hub Connection test.";
77 |
78 | LOG.info("[{}]: Starting...", testName);
79 |
80 | exampleConsumer.createTelemetryConsumer().setHandler(consumerCreated -> {
81 | context.assertTrue(consumerCreated.succeeded(), "[" + testName +"]: Telemetry consumer creation failed.");
82 | LOG.info("[{}]: Telemetry consumer successfully created.", testName);
83 | async.complete();
84 | });
85 | }
86 |
87 | }
--------------------------------------------------------------------------------
/example-consumer/src/main/java/com/bosch/iothub/examples/ExampleConsumer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Bosch.IO GmbH. All rights reserved.
3 | */
4 | package com.bosch.iothub.examples;
5 |
6 | import io.vertx.core.Future;
7 | import io.vertx.core.Vertx;
8 | import org.apache.qpid.proton.amqp.messaging.Data;
9 | import org.apache.qpid.proton.message.Message;
10 | import org.eclipse.hono.client.ApplicationClientFactory;
11 | import org.eclipse.hono.client.DisconnectListener;
12 | import org.eclipse.hono.client.HonoConnection;
13 | import org.eclipse.hono.client.MessageConsumer;
14 | import org.eclipse.hono.util.MessageHelper;
15 | import org.slf4j.Logger;
16 | import org.slf4j.LoggerFactory;
17 | import org.springframework.beans.factory.annotation.Autowired;
18 | import org.springframework.beans.factory.annotation.Value;
19 | import org.springframework.stereotype.Component;
20 |
21 | import javax.annotation.PostConstruct;
22 |
23 | @Component
24 | public class ExampleConsumer {
25 | private static final Logger LOG = LoggerFactory.getLogger(ExampleConsumer.class);
26 | private static final int RECONNECT_INTERVAL_MILLIS = 1000;
27 |
28 | @Value(value = "${tenant.id}")
29 | protected String tenantId;
30 |
31 | @Autowired
32 | private Vertx vertx;
33 |
34 | @Autowired
35 | private ApplicationClientFactory clientFactory;
36 |
37 | private long reconnectTimerId = -1;
38 |
39 | void setClientFactory(ApplicationClientFactory clientFactory) {
40 | this.clientFactory = clientFactory;
41 | }
42 |
43 | void setTenantId(String tenantId) {
44 | this.tenantId = tenantId;
45 | }
46 |
47 | @PostConstruct
48 | private void start() {
49 | connectWithRetry();
50 | }
51 |
52 | /**
53 | * Try to connect Hono client infinitely regardless of errors which may occur,
54 | * even if the Hono client itself is incorrectly configured (e.g. wrong credentials).
55 | * This is to ensure that client tries to re-connect in unforeseen situations.
56 | */
57 | private void connectWithRetry() {
58 | clientFactoryConnect(this::onDisconnect).compose(connection -> {
59 | LOG.info("Connected to IoT Hub messaging endpoint.");
60 | return createTelemetryConsumer().compose(createdConsumer -> {
61 | LOG.info("Consumer ready [tenant: {}, type: telemetry]. Hit ctrl-c to exit...", tenantId);
62 | return Future.succeededFuture();
63 | });
64 | }).otherwise(connectException -> {
65 | LOG.info("Connecting or creating a consumer failed with an exception: ", connectException);
66 | LOG.info("Reconnecting in {} ms...", RECONNECT_INTERVAL_MILLIS);
67 |
68 | // As timer could be triggered by detach or disconnect we need to ensure here that timer runs only once
69 | vertx.cancelTimer(reconnectTimerId);
70 | reconnectTimerId = vertx.setTimer(RECONNECT_INTERVAL_MILLIS, timerId -> connectWithRetry());
71 | return null;
72 | });
73 | }
74 |
75 | Future clientFactoryConnect(DisconnectListener disconnectHandler) {
76 | LOG.info("Connecting to IoT Hub messaging endpoint...");
77 | clientFactory.addDisconnectListener(disconnectHandler);
78 | return clientFactory.connect();
79 | }
80 |
81 | Future createTelemetryConsumer() {
82 | LOG.info("Creating telemetry consumer...");
83 | return clientFactory.createTelemetryConsumer(tenantId, this::handleMessage, this::onDetach);
84 | }
85 |
86 | private void onDisconnect(final HonoConnection connection) {
87 | LOG.info("Client got disconnected. Reconnecting...");
88 | connectWithRetry();
89 | }
90 |
91 | private void onDetach(Void event) {
92 | LOG.info("Client got detached. Reconnecting...");
93 | connectWithRetry();
94 | }
95 |
96 | private void handleMessage(final Message msg) {
97 | final String deviceId = MessageHelper.getDeviceId(msg);
98 | String content = ((Data) msg.getBody()).getValue().toString();
99 |
100 | LOG.info("Received message [device: {}, content-type: {}]: {}", deviceId, msg.getContentType(), content);
101 | LOG.info("... with application properties: {}", msg.getApplicationProperties());
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/command-and-control/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.bosch.iothub
8 | iot-hub-examples
9 | 1.0-SNAPSHOT
10 |
11 | command-and-control
12 | Bosch IoT Hub - Command & Control
13 | 1.0-SNAPSHOT
14 |
15 |
16 | UTF-8
17 | 11
18 | 11
19 |
20 |
21 |
22 |
23 |
24 | org.apache.maven.plugins
25 | maven-compiler-plugin
26 | 3.8.1
27 |
28 | ${maven.compiler.source}
29 | ${maven.compiler.target}
30 | ${project.build.sourceEncoding}
31 | -proc:none
32 |
33 |
34 |
35 | org.springframework.boot
36 | spring-boot-maven-plugin
37 |
38 |
39 | org.apache.maven.plugins
40 | maven-surefire-plugin
41 |
42 |
43 |
44 | iot-hub.messaging.host
45 | messaging.bosch-iot-hub.com
46 |
47 |
48 | hono.client.user
49 | UNSET
50 |
51 |
52 | hono.client.password
53 | UNSET
54 |
55 |
56 | iot-hub.tenant.id
57 | UNSET
58 |
59 |
60 |
61 | **/*Test.java
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | org.springframework.boot
71 | spring-boot
72 |
73 |
74 | org.springframework.boot
75 | spring-boot-autoconfigure
76 |
77 |
78 | org.springframework.boot
79 | spring-boot-starter-logging
80 | runtime
81 |
82 |
83 | javax.annotation
84 | javax.annotation-api
85 | 1.3.2
86 |
87 |
88 | org.yaml
89 | snakeyaml
90 |
91 |
92 | org.eclipse.hono
93 | hono-client
94 | ${hono.client.version}
95 |
96 |
97 | io.netty
98 | netty-buffer
99 | ${netty.version}
100 |
101 |
102 | io.netty
103 | netty-codec-dns
104 | ${netty.version}
105 |
106 |
107 | io.netty
108 | netty-codec-http
109 | ${netty.version}
110 |
111 |
112 | io.netty
113 | netty-codec-http2
114 | ${netty.version}
115 |
116 |
117 | io.netty
118 | netty-codec-mqtt
119 | ${netty.version}
120 |
121 |
122 | io.netty
123 | netty-common
124 | ${netty.version}
125 |
126 |
127 | io.netty
128 | netty-handler
129 | ${netty.version}
130 |
131 |
132 | io.netty
133 | netty-handler-proxy
134 | ${netty.version}
135 |
136 |
137 | io.netty
138 | netty-resolver
139 | ${netty.version}
140 |
141 |
142 | io.netty
143 | netty-resolver-dns
144 | ${netty.version}
145 |
146 |
147 | io.netty
148 | netty-transport
149 | ${netty.version}
150 |
151 |
152 |
153 | junit
154 | junit
155 | test
156 |
157 |
158 | io.vertx
159 | vertx-unit
160 | ${vertx.version}
161 | test
162 |
163 |
164 |
165 |
--------------------------------------------------------------------------------
/example-consumer/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | com.bosch.iothub
8 | iot-hub-examples
9 | 1.0-SNAPSHOT
10 |
11 | example-consumer
12 | 1.0-SNAPSHOT
13 |
14 |
15 | UTF-8
16 | 11
17 | 11
18 |
19 |
20 |
21 |
22 |
23 | org.apache.maven.plugins
24 | maven-compiler-plugin
25 | 3.8.1
26 |
27 | ${maven.compiler.source}
28 | ${maven.compiler.target}
29 | ${project.build.sourceEncoding}
30 | -proc:none
31 |
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-maven-plugin
36 |
37 |
38 | org.apache.maven.plugins
39 | maven-surefire-plugin
40 |
41 |
42 |
43 | iot-hub.messaging.host
44 | messaging.bosch-iot-hub.com
45 |
46 |
47 | hono.client.user
48 | UNSET
49 |
50 |
51 | hono.client.password
52 | UNSET
53 |
54 |
55 | iot-hub.tenant.id
56 | UNSET
57 |
58 |
59 |
60 | **/*Test.java
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | org.springframework.boot
70 | spring-boot
71 |
72 |
73 | org.springframework.boot
74 | spring-boot-autoconfigure
75 |
76 |
77 | org.springframework.boot
78 | spring-boot-starter-logging
79 | runtime
80 |
81 |
82 | javax.annotation
83 | javax.annotation-api
84 | 1.3.2
85 |
86 |
87 | org.yaml
88 | snakeyaml
89 |
90 |
91 | org.eclipse.hono
92 | hono-client
93 | ${hono.client.version}
94 |
95 |
96 | io.vertx
97 | vertx-core
98 | ${vertx.version}
99 |
100 |
101 | io.netty
102 | netty-buffer
103 | ${netty.version}
104 |
105 |
106 | io.netty
107 | netty-codec-dns
108 | ${netty.version}
109 |
110 |
111 | io.netty
112 | netty-codec-http
113 | ${netty.version}
114 |
115 |
116 | io.netty
117 | netty-codec-http2
118 | ${netty.version}
119 |
120 |
121 | io.netty
122 | netty-codec-mqtt
123 | ${netty.version}
124 |
125 |
126 | io.netty
127 | netty-common
128 | ${netty.version}
129 |
130 |
131 | io.netty
132 | netty-handler
133 | ${netty.version}
134 |
135 |
136 | io.netty
137 | netty-handler-proxy
138 | ${netty.version}
139 |
140 |
141 | io.netty
142 | netty-resolver
143 | ${netty.version}
144 |
145 |
146 | io.netty
147 | netty-resolver-dns
148 | ${netty.version}
149 |
150 |
151 | io.netty
152 | netty-transport
153 | ${netty.version}
154 |
155 |
156 |
157 | junit
158 | junit
159 | test
160 |
161 |
162 | io.vertx
163 | vertx-unit
164 | ${vertx.version}
165 | test
166 |
167 |
168 |
169 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.springframework.boot
8 | spring-boot-starter-parent
9 | 2.2.1.RELEASE
10 |
11 |
12 | com.bosch.iothub
13 | iot-hub-examples
14 | Bosch IoT Hub - Examples
15 | pom
16 | 1.0-SNAPSHOT
17 |
18 |
19 |
20 |
21 |
22 |
23 | 2.5.2
24 | 2.7.0
25 | 1.1.1
26 | 1.3.2
27 | 2.3.1
28 | 2.3.1
29 | 1.1.4
30 |
31 | 4.1.48.Final
32 | 2.0.30.Final
33 | 1.8.1
34 | 3.9.6
35 |
36 |
37 |
38 | example-consumer
39 | command-and-control
40 |
41 |
42 |
43 |
44 | org.apache.maven.plugins
45 | maven-antrun-plugin
46 |
47 |
48 | generate-copyright-header
49 | generate-sources
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | run
58 |
59 |
60 |
61 |
62 |
63 | com.mycila
64 | license-maven-plugin
65 | 3.0
66 |
67 |
68 |
69 | COPYRIGHT_SECTION
70 |
71 |
72 |
73 |
74 |
75 |
76 | .
77 | ${project.build.directory}/copyright-header.txt
78 | false
79 | true
80 | false
81 |
82 | src/main/**/*.java
83 | src/test/**/*.java
84 |
85 | UTF-8
86 | true
87 |
88 | SLASHSTAR_STYLE
89 |
90 |
91 |
92 |
93 |
94 | check
95 |
96 |
97 |
98 |
99 |
100 | org.apache.maven.plugins
101 | maven-dependency-plugin
102 | 3.0.2
103 |
104 |
105 | copy-dependencies
106 | package
107 |
108 | copy-dependencies
109 |
110 |
111 | ${project.build.directory}/dependencies
112 | false
113 | false
114 | true
115 |
116 |
117 |
118 |
119 |
120 | com.bosch.tina
121 | tina-bosch-mojo
122 | ${tina-bosch-mojo.version}
123 | false
124 |
125 | Bosch IoT Suite - IoT Hub examples
126 | Bosch IoT Suite - IoT Hub examples
127 | ${project.version}
128 | true
129 |
132 | ${project.basedir}/tinaworkflow.xml
133 | true
134 |
135 |
136 |
137 | com.bosch.tina
138 | tina-knowledge-base
139 | ${tina-knowledge-base.version}
140 |
141 |
142 | javax.annotation
143 | javax.annotation-api
144 | ${javax.annotation-api.version}
145 |
146 |
147 | javax.xml.bind
148 | jaxb-api
149 | ${jaxb-api.version}
150 |
151 |
152 | org.glassfish.jaxb
153 | jaxb-runtime
154 | ${jaxb-runtime.version}
155 |
156 |
157 | javax.activation
158 | activation
159 | ${activation.version}
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | com.fasterxml.jackson.core
169 | jackson-databind
170 | 2.9.10.7
171 |
172 |
173 |
174 |
--------------------------------------------------------------------------------