Added simulator autostart and cf deployment.
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
The device simulator handles software update commands from the update server.
|
The device simulator handles software update commands from the update server.
|
||||||
|
|
||||||
## Run
|
## Run on your own workstation
|
||||||
```
|
```
|
||||||
java -jar examples/hawkbit-device-simulator/target/hawkbit-device-simulator-*-SNAPSHOT.jar
|
java -jar examples/hawkbit-device-simulator/target/hawkbit-device-simulator-*-SNAPSHOT.jar
|
||||||
```
|
```
|
||||||
@@ -11,6 +11,11 @@ Or:
|
|||||||
run org.eclipse.hawkbit.simulator.DeviceSimulator
|
run org.eclipse.hawkbit.simulator.DeviceSimulator
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Deploy to cloud foundry environment
|
||||||
|
|
||||||
|
- Go to ```target``` subfolder.
|
||||||
|
- Run ```cf push```
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
The simulator has user authentication enabled in **cloud profile**. Default credentials:
|
The simulator has user authentication enabled in **cloud profile**. Default credentials:
|
||||||
@@ -30,9 +35,9 @@ http://localhost:8083
|
|||||||
```
|
```
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
@@ -54,12 +59,12 @@ Example: for 20 simulated devices (default)
|
|||||||
http://localhost:8083/start
|
http://localhost:8083/start
|
||||||
```
|
```
|
||||||
|
|
||||||
Example: for 10 simulated devices that start with the name prefix "activeSim":
|
Example: for 10 simulated devices that start with the name prefix "activeSim":
|
||||||
```
|
```
|
||||||
http://localhost:8083/start?amount=10&name=activeSim
|
http://localhost:8083/start?amount=10&name=activeSim
|
||||||
```
|
```
|
||||||
|
|
||||||
Example: for 5 simulated devices that start with the name prefix "ddi" using the Direct Device Integration API (http):
|
Example: for 5 simulated devices that start with the name prefix "ddi" using the Direct Device Integration API (http):
|
||||||
```
|
```
|
||||||
http://localhost:8083/start?amount=5&name=ddi?api=ddi
|
http://localhost:8083/start?amount=5&name=ddi?api=ddi
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -9,13 +9,13 @@
|
|||||||
---
|
---
|
||||||
applications:
|
applications:
|
||||||
- name: hawkbit-simulator
|
- name: hawkbit-simulator
|
||||||
memory: 512M
|
memory: 1024M
|
||||||
instances: 1
|
instances: 1
|
||||||
buildpack: https://github.com/cloudfoundry/java-buildpack
|
buildpack: https://github.com/cloudfoundry/java-buildpack
|
||||||
path: hawkbit-example-app-0.2.0-SNAPSHOT.jar
|
path: ${project.build.finalName}.jar
|
||||||
services:
|
services:
|
||||||
- dmf-rabbit
|
- dmf-rabbit
|
||||||
env:
|
env:
|
||||||
SPRING_PROFILES_ACTIVE: cloudsandbox,amqp
|
SPRING_PROFILES_ACTIVE: cloud,amqp
|
||||||
CF_STAGING_TIMEOUT: 15
|
CF_STAGING_TIMEOUT: 15
|
||||||
CF_STARTUP_TIMEOUT: 15
|
CF_STARTUP_TIMEOUT: 15
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ public class SimulationController {
|
|||||||
* number of delay in milliseconds to delay polling of DDI
|
* number of delay in milliseconds to delay polling of DDI
|
||||||
* devices
|
* devices
|
||||||
* @param gatewayToken
|
* @param gatewayToken
|
||||||
* the hawkbit-update-server gatwaytoken in case authentication
|
* the hawkbit-update-server gatewaytoken in case authentication
|
||||||
* is enforced in hawkbit
|
* is enforced in hawkbit
|
||||||
* @return a response string that devices has been created
|
* @return a response string that devices has been created
|
||||||
* @throws MalformedURLException
|
* @throws MalformedURLException
|
||||||
@@ -68,7 +68,7 @@ public class SimulationController {
|
|||||||
@RequestParam(value = "endpoint", defaultValue = "http://localhost:8080") final String endpoint,
|
@RequestParam(value = "endpoint", defaultValue = "http://localhost:8080") final String endpoint,
|
||||||
@RequestParam(value = "polldelay", defaultValue = "30") final int pollDelay,
|
@RequestParam(value = "polldelay", defaultValue = "30") final int pollDelay,
|
||||||
@RequestParam(value = "gatewaytoken", defaultValue = "") final String gatewayToken)
|
@RequestParam(value = "gatewaytoken", defaultValue = "") final String gatewayToken)
|
||||||
throws MalformedURLException {
|
throws MalformedURLException {
|
||||||
|
|
||||||
final Protocol protocol;
|
final Protocol protocol;
|
||||||
switch (api.toLowerCase()) {
|
switch (api.toLowerCase()) {
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* 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.hawkbit.simulator;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol;
|
||||||
|
import org.hibernate.validator.constraints.NotEmpty;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General simulator service properties.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
@ConfigurationProperties("hawkbit.device.simulator")
|
||||||
|
public class SimulationProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of tenants where the simulator should auto start simulations after
|
||||||
|
* startup.
|
||||||
|
*/
|
||||||
|
private final List<Autostart> autostarts = new ArrayList<>();
|
||||||
|
|
||||||
|
public List<Autostart> getAutostarts() {
|
||||||
|
return this.autostarts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto start configuration for simulation setups that the simulator begins
|
||||||
|
* after startup.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public static class Autostart {
|
||||||
|
/**
|
||||||
|
* Name prefix of simulated devices, followed by counter, e.g.
|
||||||
|
* simulated0, simulated1, simulated2....
|
||||||
|
*/
|
||||||
|
private String name = "simulated";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Amount of simulated devices.
|
||||||
|
*/
|
||||||
|
private int amount = 20;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tenant name for the simulation.
|
||||||
|
*/
|
||||||
|
@NotEmpty
|
||||||
|
private String tenant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* API for simulation.
|
||||||
|
*/
|
||||||
|
private Protocol api = Protocol.DMF_AMQP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Endpoint in case of DDI API based simulation.
|
||||||
|
*/
|
||||||
|
private String endpoint = "http://localhost:8080";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Poll time in case of DDI API based simulation.
|
||||||
|
*/
|
||||||
|
private int pollDelay = 30;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional gateway token for DDI API based simulation.
|
||||||
|
*/
|
||||||
|
private String gatewayToken = "";
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAmount(final int amount) {
|
||||||
|
this.amount = amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTenant() {
|
||||||
|
return tenant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTenant(final String tenant) {
|
||||||
|
this.tenant = tenant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Protocol getApi() {
|
||||||
|
return api;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApi(final Protocol api) {
|
||||||
|
this.api = api;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEndpoint() {
|
||||||
|
return endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEndpoint(final String endpoint) {
|
||||||
|
this.endpoint = endpoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPollDelay() {
|
||||||
|
return pollDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPollDelay(final int pollDelay) {
|
||||||
|
this.pollDelay = pollDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGatewayToken() {
|
||||||
|
return gatewayToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGatewayToken(final String gatewayToken) {
|
||||||
|
this.gatewayToken = gatewayToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package org.eclipse.hawkbit.simulator;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.simulator.amqp.SpSenderService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationListener;
|
||||||
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execution of operations after startup. Set up of simulations.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class SimulatorStartup implements ApplicationListener<ContextRefreshedEvent> {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(SimulatorStartup.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SimulationProperties simulationProperties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SpSenderService spSenderService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DeviceSimulatorRepository repository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private SimulatedDeviceFactory deviceFactory;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onApplicationEvent(final ContextRefreshedEvent event) {
|
||||||
|
simulationProperties.getAutostarts().forEach(autostart -> {
|
||||||
|
for (int i = 0; i < autostart.getAmount(); i++) {
|
||||||
|
final String deviceId = autostart.getName() + i;
|
||||||
|
try {
|
||||||
|
repository.add(deviceFactory.createSimulatedDevice(deviceId, autostart.getTenant(),
|
||||||
|
autostart.getApi(), autostart.getPollDelay(), new URL(autostart.getEndpoint()),
|
||||||
|
autostart.getGatewayToken()));
|
||||||
|
} catch (final Exception e) {
|
||||||
|
LOGGER.error("Creation of simulated device at startup failed.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
spSenderService.createOrUpdateThing(autostart.getTenant(), deviceId);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -19,26 +19,25 @@ import org.springframework.stereotype.Component;
|
|||||||
@Component
|
@Component
|
||||||
@ConfigurationProperties("hawkbit.device.simulator.amqp")
|
@ConfigurationProperties("hawkbit.device.simulator.amqp")
|
||||||
public class AmqpProperties {
|
public class AmqpProperties {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queue for receiving DMF messages from update server.
|
* Queue for receiving DMF messages from update server.
|
||||||
*/
|
*/
|
||||||
private String receiverConnectorQueueFromSp;
|
private String receiverConnectorQueueFromSp = "simulator_receiver";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exchange for sending DMF messages to update server.
|
* Exchange for sending DMF messages to update server.
|
||||||
*/
|
*/
|
||||||
private String senderForSpExchange;
|
private String senderForSpExchange = "simulator.replyTo";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simulator dead letter queue.
|
* Simulator dead letter queue.
|
||||||
*/
|
*/
|
||||||
private String deadLetterQueue;
|
private String deadLetterQueue = "simulator_deadletter";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simulator dead letter exchange.
|
* Simulator dead letter exchange.
|
||||||
*/
|
*/
|
||||||
private String deadLetterExchange;
|
private String deadLetterExchange = "simulator.deadletter";
|
||||||
|
|
||||||
public String getReceiverConnectorQueueFromSp() {
|
public String getReceiverConnectorQueueFromSp() {
|
||||||
return receiverConnectorQueueFromSp;
|
return receiverConnectorQueueFromSp;
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import org.springframework.stereotype.Component;
|
|||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
public class SpReceiverService extends ReceiverService {
|
public class SpReceiverService extends ReceiverService {
|
||||||
|
|
||||||
private static final Logger LOGGER = LoggerFactory.getLogger(ReceiverService.class);
|
private static final Logger LOGGER = LoggerFactory.getLogger(ReceiverService.class);
|
||||||
|
|
||||||
public static final String SOFTWARE_MODULE_FIRMWARE = "firmware";
|
public static final String SOFTWARE_MODULE_FIRMWARE = "firmware";
|
||||||
|
|||||||
@@ -13,8 +13,11 @@ hawkbit.device.simulator.amqp.deadLetterQueue=simulator_deadletter
|
|||||||
hawkbit.device.simulator.amqp.deadLetterExchange=simulator.deadletter
|
hawkbit.device.simulator.amqp.deadLetterExchange=simulator.deadletter
|
||||||
hawkbit.device.simulator.amqp.senderForSpExchange=simulator.replyTo
|
hawkbit.device.simulator.amqp.senderForSpExchange=simulator.replyTo
|
||||||
|
|
||||||
|
## Configuration for simulations
|
||||||
|
hawkbit.device.simulator.autostarts.[0].tenant=DEFAULT
|
||||||
|
|
||||||
## Configuration for RabbitMQ integration
|
|
||||||
|
## Configuration for local RabbitMQ integration
|
||||||
spring.rabbitmq.username=guest
|
spring.rabbitmq.username=guest
|
||||||
spring.rabbitmq.password=guest
|
spring.rabbitmq.password=guest
|
||||||
spring.rabbitmq.virtualHost=/
|
spring.rabbitmq.virtualHost=/
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ The Management API can be accessed via http://localhost:8080/rest/v1
|
|||||||
|
|
||||||
## Deploy example app to Cloud Foundry
|
## Deploy example app to Cloud Foundry
|
||||||
|
|
||||||
- Go to ```cf``` subfolder.
|
- Go to ```target``` subfolder.
|
||||||
- Select one of the two manifests
|
- Select one of the two manifests
|
||||||
- **manifest-simple.yml** for a standalone hawkBit installation with embedded H2.
|
- **manifest-simple.yml** for a standalone hawkBit installation with embedded H2.
|
||||||
- **manifest.yml** for a standalone hawkBit installation with embedded H2 and RabbitMQ service binding for DMF integration (note: this manifest is used for the sandbox above).
|
- **manifest.yml** for a standalone hawkBit installation with embedded H2 and RabbitMQ service binding for DMF integration (note: this manifest is used for the sandbox above).
|
||||||
|
- Run ```cf push``` against you cloud foundry environment.
|
||||||
|
|||||||
@@ -7,5 +7,4 @@
|
|||||||
# http://www.eclipse.org/legal/epl-v10.html
|
# http://www.eclipse.org/legal/epl-v10.html
|
||||||
#
|
#
|
||||||
|
|
||||||
spring.profiles.active=
|
|
||||||
vaadin.servlet.productionMode=true
|
vaadin.servlet.productionMode=true
|
||||||
|
|||||||
Reference in New Issue
Block a user