From 25fb8e55143b0c7d7d9470bc04a1f0e0c5427923 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 11 Aug 2016 09:50:38 +0200 Subject: [PATCH 1/5] introduce property to disable amqp interface in simulator Signed-off-by: Michael Hirsch --- examples/hawkbit-device-simulator/README.md | 6 +++++ .../simulator/SimulationController.java | 23 +++++++++++++------ .../simulator/amqp/AmqpConfiguration.java | 4 ++++ .../simulator/amqp/AmqpProperties.java | 19 +++++++++++++++ .../simulator/amqp/SpReceiverService.java | 4 ++++ .../hawkbit/simulator/ui/GenerateDialog.java | 14 ++++++++--- .../hawkbit/simulator/ui/SimulatorView.java | 6 ++++- .../src/main/resources/application.properties | 1 + 8 files changed, 66 insertions(+), 11 deletions(-) diff --git a/examples/hawkbit-device-simulator/README.md b/examples/hawkbit-device-simulator/README.md index 1ba29bb7e..ba241601a 100644 --- a/examples/hawkbit-device-simulator/README.md +++ b/examples/hawkbit-device-simulator/README.md @@ -24,6 +24,12 @@ The simulator has user authentication enabled in **cloud profile**. Default cred This can be configured/disabled by spring boot properties +## hawkBit APIs + +The simulator supports `DDI` as well as the `DMF` integration APIs. +In case there is no AMQP message broker (like rabbitMQ) running, you can disable the AMQP support for the device simulator, so the simulator is not trying to connect to a amqp message broker. +Configuration property `hawkbit.device.simulator.amqp.enabled=true` + ## Usage ### Graphical User Interface diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java index 43f954c00..b100cb28f 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java @@ -8,11 +8,13 @@ */ package org.eclipse.hawkbit.simulator; +import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX; + import java.net.MalformedURLException; import java.net.URL; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol; -import org.eclipse.hawkbit.simulator.amqp.SpSenderService; +import org.eclipse.hawkbit.simulator.amqp.AmqpProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; @@ -21,22 +23,19 @@ import org.springframework.web.bind.annotation.RestController; /** * REST endpoint for controlling the device simulator. - * - * - * */ @RestController public class SimulationController { - @Autowired - private SpSenderService spSenderService; - @Autowired private DeviceSimulatorRepository repository; @Autowired private SimulatedDeviceFactory deviceFactory; + @Autowired + private AmqpProperties amqpProperties; + /** * The start resource to start a device creation. * @@ -82,6 +81,12 @@ public class SimulationController { return ResponseEntity.badRequest().body("query param api only allows value of 'dmf' or 'ddi'"); } + if (protocol == Protocol.DMF_AMQP && isDmfDisabled()) { + return ResponseEntity.badRequest() + .body("The AMQP interface has been disabled, to use DMF protocol you need to enable the AMQP interface via '" + + CONFIGURATION_PREFIX + ".enabled=true'"); + } + for (int i = 0; i < amount; i++) { final String deviceId = name + i; repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant, protocol, pollDelay, new URL(endpoint), @@ -90,4 +95,8 @@ public class SimulationController { return ResponseEntity.ok("Updated " + amount + " DMF connected targets!"); } + + private boolean isDmfDisabled() { + return !amqpProperties.isEnabled(); + } } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java index edaf9d11a..5e9b3e049 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.simulator.amqp; +import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX; + import java.time.Duration; import java.util.HashMap; import java.util.Map; @@ -27,6 +29,7 @@ import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.amqp.RabbitProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -39,6 +42,7 @@ import org.springframework.retry.support.RetryTemplate; */ @Configuration @EnableConfigurationProperties(AmqpProperties.class) +@ConditionalOnProperty(prefix = CONFIGURATION_PREFIX, name = "enabled") public class AmqpConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(AmqpConfiguration.class); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java index 8fba3ac5b..3730a3350 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java @@ -19,6 +19,17 @@ import org.springframework.stereotype.Component; @Component @ConfigurationProperties("hawkbit.device.simulator.amqp") public class AmqpProperties { + + /** + * The prefix for this configuration. + */ + public static final String CONFIGURATION_PREFIX = "hawkbit.device.simulator.amqp"; + + /** + * Indicates if the AMQP interface is enabled for the device simulator. + */ + private boolean enabled; + /** * Queue for receiving DMF messages from update server. */ @@ -84,4 +95,12 @@ public class AmqpProperties { public void setDeadLetterTtl(final int deadLetterTtl) { this.deadLetterTtl = deadLetterTtl; } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + } } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java index 7d55fb375..8dac6d4bc 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.simulator.amqp; +import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX; + import java.util.Map; import org.eclipse.hawkbit.dmf.amqp.api.EventTopic; @@ -22,6 +24,7 @@ import org.springframework.amqp.core.MessageProperties; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.messaging.handler.annotation.Header; import org.springframework.stereotype.Component; @@ -32,6 +35,7 @@ import com.google.common.collect.Lists; * */ @Component +@ConditionalOnProperty(prefix = CONFIGURATION_PREFIX, name = "enabled") public class SpReceiverService extends ReceiverService { private static final Logger LOGGER = LoggerFactory.getLogger(ReceiverService.class); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java index b50098829..6d1806463 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java @@ -52,6 +52,7 @@ public class GenerateDialog extends Window { private final TextField gatewayTokenTextField; private OptionGroup protocolGroup; private Button buttonOk; + private final boolean dmfEnabled; /** * Creates a new pop window for setting the configuration of simulating @@ -60,9 +61,12 @@ public class GenerateDialog extends Window { * @param callback * the callback which is called when the dialog has been * successfully confirmed. + * @param dmfEnabled + * indicates if the AMQP/DMF interface is enabled by + * configuration and if the option DMF should be enabled or not */ - public GenerateDialog(final GenerateDialogCallback callback) { - + public GenerateDialog(final GenerateDialogCallback callback, final boolean dmfEnabled) { + this.dmfEnabled = dmfEnabled; formLayout.setSpacing(true); formLayout.setMargin(true); @@ -187,15 +191,19 @@ public class GenerateDialog extends Window { this.protocolGroup = new OptionGroup("Simulated Device Protocol"); protocolGroup.addItem(Protocol.DMF_AMQP); protocolGroup.addItem(Protocol.DDI_HTTP); + protocolGroup.select(Protocol.DMF_AMQP); protocolGroup.setItemCaption(Protocol.DMF_AMQP, "Device Management Federation API (AMQP push)"); protocolGroup.setItemCaption(Protocol.DDI_HTTP, "Direct Device Interface (HTTP poll)"); protocolGroup.setNullSelectionAllowed(false); - protocolGroup.select(Protocol.DMF_AMQP); protocolGroup.addValueChangeListener(event -> { final boolean directDeviceOptionSelected = event.getProperty().getValue().equals(Protocol.DDI_HTTP); pollUrlTextField.setVisible(directDeviceOptionSelected); gatewayTokenTextField.setVisible(directDeviceOptionSelected); }); + protocolGroup.setItemEnabled(Protocol.DMF_AMQP, dmfEnabled); + if (!dmfEnabled) { + protocolGroup.select(Protocol.DDI_HTTP); + } } private void createOkButton(final GenerateDialogCallback callback) { diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java index 686945407..25e575cf1 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java @@ -17,6 +17,7 @@ import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Status; import org.eclipse.hawkbit.simulator.DeviceSimulatorRepository; import org.eclipse.hawkbit.simulator.SimulatedDeviceFactory; import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus; +import org.eclipse.hawkbit.simulator.amqp.AmqpProperties; import org.eclipse.hawkbit.simulator.amqp.SpSenderService; import org.eclipse.hawkbit.simulator.event.InitUpdate; import org.eclipse.hawkbit.simulator.event.NextPollCounterUpdate; @@ -90,6 +91,9 @@ public class SimulatorView extends VerticalLayout implements View { @Autowired private transient EventBus eventbus; + @Autowired + private transient AmqpProperties amqpProperties; + private final Label caption = new Label("DMF/DDI Simulated Devices"); private final HorizontalLayout toolbar = new HorizontalLayout(); private final Grid grid = new Grid(); @@ -268,7 +272,7 @@ public class SimulatorView extends VerticalLayout implements View { tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken))); spSenderService.createOrUpdateThing(tenant, deviceId); } - })); + }, amqpProperties.isEnabled())); } private ProtocolConverter createProtocolConverter() { diff --git a/examples/hawkbit-device-simulator/src/main/resources/application.properties b/examples/hawkbit-device-simulator/src/main/resources/application.properties index 5d3f04be7..60fa817e2 100644 --- a/examples/hawkbit-device-simulator/src/main/resources/application.properties +++ b/examples/hawkbit-device-simulator/src/main/resources/application.properties @@ -8,6 +8,7 @@ # ## Configuration for DMF communication +hawkbit.device.simulator.amqp.enabled=true hawkbit.device.simulator.amqp.receiverConnectorQueueFromSp=simulator_receiver hawkbit.device.simulator.amqp.deadLetterQueue=simulator_deadletter hawkbit.device.simulator.amqp.deadLetterExchange=simulator.deadletter From e8393af749d8a93606ea21ae08f5c8dd8c675312 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 12 Aug 2016 09:54:18 +0200 Subject: [PATCH 2/5] adapt manifest Signed-off-by: Michael Hirsch --- examples/hawkbit-device-simulator/cf/manifest.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/hawkbit-device-simulator/cf/manifest.yml b/examples/hawkbit-device-simulator/cf/manifest.yml index 51a43ace6..188ef7780 100644 --- a/examples/hawkbit-device-simulator/cf/manifest.yml +++ b/examples/hawkbit-device-simulator/cf/manifest.yml @@ -17,6 +17,4 @@ applications: services: - dmf-rabbit env: - SPRING_PROFILES_ACTIVE: cloud,amqp - CF_STAGING_TIMEOUT: 15 - CF_STARTUP_TIMEOUT: 15 + SPRING_PROFILES_ACTIVE: cloud From 196ce5643e02bc90ccf0b4c38bb2f636defb6474 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 15 Aug 2016 14:33:03 +0200 Subject: [PATCH 3/5] don't send amqp message when protocol is DDI Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java | 1 + .../java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java index 8d5c5e0b1..3a8690cb3 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java @@ -72,6 +72,7 @@ public class SimulatedDeviceFactory { final int pollDelaySec, final URL baseEndpoint, final String gatewayToken) { switch (protocol) { case DMF_AMQP: + spSenderService.createOrUpdateThing(tenant, id); return new DMFSimulatedDevice(id, tenant, spSenderService, pollDelaySec); case DDI_HTTP: final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger()) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java index 25e575cf1..4a81547c5 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java @@ -270,7 +270,6 @@ public class SimulatorView extends VerticalLayout implements View { final String deviceId = namePrefix + index; beanContainer.addBean(repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken))); - spSenderService.createOrUpdateThing(tenant, deviceId); } }, amqpProperties.isEnabled())); } From 9d54aa8c34c28754b714923131bb716153040445 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 15 Aug 2016 15:16:02 +0200 Subject: [PATCH 4/5] grammar corrected Signed-off-by: Michael Hirsch --- examples/hawkbit-device-simulator/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hawkbit-device-simulator/README.md b/examples/hawkbit-device-simulator/README.md index ba241601a..0d73f3f3f 100644 --- a/examples/hawkbit-device-simulator/README.md +++ b/examples/hawkbit-device-simulator/README.md @@ -27,7 +27,7 @@ This can be configured/disabled by spring boot properties ## hawkBit APIs The simulator supports `DDI` as well as the `DMF` integration APIs. -In case there is no AMQP message broker (like rabbitMQ) running, you can disable the AMQP support for the device simulator, so the simulator is not trying to connect to a amqp message broker. +In case there is no AMQP message broker (like rabbitMQ) running, you can disable the AMQP support for the device simulator, so the simulator is not trying to connect to an amqp message broker. Configuration property `hawkbit.device.simulator.amqp.enabled=true` ## Usage From 7164b33e941f950da25488874e62474561db7b05 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 15 Aug 2016 15:33:18 +0200 Subject: [PATCH 5/5] don't generate amqp devices at startup if amqp is disabled Signed-off-by: Michael Hirsch --- .../hawkbit/simulator/SimulatorStartup.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java index 486eb4b5e..69ff765d0 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java @@ -11,7 +11,7 @@ package org.eclipse.hawkbit.simulator; import java.net.MalformedURLException; import java.net.URL; -import org.eclipse.hawkbit.simulator.amqp.SpSenderService; +import org.eclipse.hawkbit.simulator.amqp.AmqpProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -32,24 +32,27 @@ public class SimulatorStartup implements ApplicationListener { 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())); + if (amqpProperties.isEnabled()) { + repository.add(deviceFactory.createSimulatedDevice(deviceId, autostart.getTenant(), + autostart.getApi(), autostart.getPollDelay(), new URL(autostart.getEndpoint()), + autostart.getGatewayToken())); + } + } catch (final MalformedURLException e) { LOGGER.error("Creation of simulated device at startup failed.", e); }