Merge pull request #269 from bsinno/feature_allow_disable_amqp_interface_in_simulator

introduce property to disable amqp interface in simulator
This commit is contained in:
Michael Hirsch
2016-08-17 10:05:59 +02:00
committed by GitHub
11 changed files with 78 additions and 22 deletions

View File

@@ -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 an amqp message broker.
Configuration property `hawkbit.device.simulator.amqp.enabled=true`
## Usage
### Graphical User Interface

View File

@@ -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

View File

@@ -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())

View File

@@ -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();
}
}

View File

@@ -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<ContextRefreshedEve
@Autowired
private SimulationProperties simulationProperties;
@Autowired
private SpSenderService spSenderService;
@Autowired
private DeviceSimulatorRepository repository;
@Autowired
private SimulatedDeviceFactory deviceFactory;
@Autowired
private AmqpProperties amqpProperties;
@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()));
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);
}

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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);

View File

@@ -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) {

View File

@@ -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();
@@ -266,9 +270,8 @@ 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()));
}
private ProtocolConverter createProtocolConverter() {

View File

@@ -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