Allow DMF to be disabled

Signed-off-by: Kai Zimmermann <kai.zimmermann@bosch-si.com>
This commit is contained in:
Kai Zimmermann
2016-09-07 09:30:48 +02:00
parent 2f415c4839
commit e03bca45d5
13 changed files with 94 additions and 116 deletions

View File

@@ -23,6 +23,7 @@ import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.PatternTopic;
import org.springframework.data.redis.listener.Topic;
import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
import org.springframework.stereotype.Service;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
@@ -32,6 +33,7 @@ import com.google.common.eventbus.Subscribe;
*
*/
@EventSubscriber
@Service
public class EventDistributor {
private static final Logger LOGGER = LoggerFactory.getLogger(EventDistributor.class);

View File

@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.eventbus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import com.google.common.eventbus.DeadEvent;
import com.google.common.eventbus.Subscribe;
@@ -22,6 +23,7 @@ import com.google.common.eventbus.Subscribe;
*
*/
@EventSubscriber
@Service
public class DeadEventListener {
private static final Logger LOG = LoggerFactory.getLogger(DeadEventListener.class);

View File

@@ -14,8 +14,6 @@ import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import org.springframework.stereotype.Service;
/**
* Marks an class as an event subscriber to listen on event on the event bus
* without explicit register this class to the event bus.
@@ -36,7 +34,6 @@ import org.springframework.stereotype.Service;
*/
@Target({ TYPE })
@Retention(RUNTIME)
@Service
public @interface EventSubscriber {
}

View File

@@ -17,6 +17,7 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.stereotype.Service;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
@@ -56,6 +57,7 @@ public class EventBusSubscriberProcessorTest {
}
@EventSubscriber
@Service
private class TestEventSubscriberClass {
@Subscribe
public void subscribe(final String s) {
@@ -64,6 +66,7 @@ public class EventBusSubscriberProcessorTest {
}
@EventSubscriber
@Service
private class TestWrongEventSubscriberClass {
public void methodWithoutAnnotation(final String s) {

View File

@@ -14,7 +14,13 @@ import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.ScheduledExecutorService;
import org.eclipse.hawkbit.api.ArtifactUrlHandler;
import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings;
import org.eclipse.hawkbit.repository.ControllerManagement;
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
import org.eclipse.hawkbit.security.DdiSecurityProperties;
import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Binding;
@@ -33,6 +39,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
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;
@@ -41,11 +48,12 @@ import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.ErrorHandler;
/**
* The spring AMQP configuration which is enabled by using the profile
* {@code amqp} to use a AMQP for communication with SP enabled devices.
* Spring configuration for AMQP 0.9 based DMF communication for indirect device
* integration.
*
*/
@EnableConfigurationProperties({ AmqpProperties.class, AmqpDeadletterProperties.class })
@ConditionalOnProperty(prefix = "hawkbit.dmf.rabbitmq", name = "enabled")
public class AmqpConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(AmqpConfiguration.class);
@@ -61,6 +69,7 @@ public class AmqpConfiguration {
@Configuration
@ConditionalOnMissingBean(ConnectionFactory.class)
@ConditionalOnProperty(prefix = "hawkbit.dmf.rabbitmq", name = "enabled")
protected static class RabbitConnectionFactoryCreator {
@Autowired
@@ -280,6 +289,20 @@ public class AmqpConfiguration {
return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory, errorHandler);
}
@Bean
public AmqpControllerAuthentication amqpControllerAuthentication(final ControllerManagement controllerManagement,
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
final DdiSecurityProperties ddiSecruityProperties, final SystemSecurityContext systemSecurityContext) {
return new AmqpControllerAuthentication(controllerManagement, tenantConfigurationManagement, tenantAware,
ddiSecruityProperties, systemSecurityContext);
}
@Bean
public AmqpMessageDispatcherService amqpMessageDispatcherService(final RabbitTemplate rabbitTemplate,
final AmqpSenderService amqpSenderService, final ArtifactUrlHandler artifactUrlHandler) {
return new AmqpMessageDispatcherService(rabbitTemplate, amqpSenderService, artifactUrlHandler);
}
private static Map<String, Object> getTTLMaxArgsAuthenticationQueue() {
final Map<String, Object> args = new HashMap<>();
args.put("x-message-ttl", Duration.ofSeconds(30).toMillis());

View File

@@ -29,44 +29,51 @@ import org.eclipse.hawkbit.security.SystemSecurityContext;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.stereotype.Component;
/**
*
* A controller which handles the amqp authentfication.
* A controller which handles the DMF AMQP authentication.
*/
@Component
public class AmqpControllerAuthentfication {
public class AmqpControllerAuthentication {
private static final Logger LOGGER = LoggerFactory.getLogger(AmqpControllerAuthentfication.class);
private static final Logger LOGGER = LoggerFactory.getLogger(AmqpControllerAuthentication.class);
private final PreAuthTokenSourceTrustAuthenticationProvider preAuthenticatedAuthenticationProvider;
private final PreAuthTokenSourceTrustAuthenticationProvider preAuthenticatedAuthenticationProvider = new PreAuthTokenSourceTrustAuthenticationProvider();
private final List<PreAuthentificationFilter> filterChain = new ArrayList<>();
@Autowired
private ControllerManagement controllerManagement;
private final ControllerManagement controllerManagement;
@Autowired
private TenantConfigurationManagement tenantConfigurationManagement;
private final TenantConfigurationManagement tenantConfigurationManagement;
@Autowired
private TenantAware tenantAware;
private final TenantAware tenantAware;
@Autowired
private DdiSecurityProperties ddiSecruityProperties;
private final DdiSecurityProperties ddiSecruityProperties;
@Autowired
private SystemSecurityContext systemSecurityContext;
private final SystemSecurityContext systemSecurityContext;
/**
* Constructor.
*
* @param controllerManagement
* @param tenantConfigurationManagement
* @param tenantAware
* current tenant
* @param ddiSecruityProperties
* security configurations
* @param systemSecurityContext
* security context
*/
public AmqpControllerAuthentfication() {
preAuthenticatedAuthenticationProvider = new PreAuthTokenSourceTrustAuthenticationProvider();
public AmqpControllerAuthentication(final ControllerManagement controllerManagement,
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
final DdiSecurityProperties ddiSecruityProperties, final SystemSecurityContext systemSecurityContext) {
this.controllerManagement = controllerManagement;
this.tenantConfigurationManagement = tenantConfigurationManagement;
this.tenantAware = tenantAware;
this.ddiSecruityProperties = ddiSecruityProperties;
this.systemSecurityContext = systemSecurityContext;
}
/**
@@ -139,23 +146,4 @@ public class AmqpControllerAuthentfication {
return new PreAuthenticatedAuthenticationToken(principal, credentials);
}
public void setControllerManagement(final ControllerManagement controllerManagement) {
this.controllerManagement = controllerManagement;
}
public void setSecruityProperties(final DdiSecurityProperties secruityProperties) {
this.ddiSecruityProperties = secruityProperties;
}
public void setTenantConfigurationManagement(final TenantConfigurationManagement tenantConfigurationManagement) {
this.tenantConfigurationManagement = tenantConfigurationManagement;
}
public void setTenantAware(final TenantAware tenantAware) {
this.tenantAware = tenantAware;
}
void setSystemSecurityContext(final SystemSecurityContext systemSecurityContext) {
this.systemSecurityContext = systemSecurityContext;
}
}

View File

@@ -31,7 +31,6 @@ import org.eclipse.hawkbit.util.IpUtil;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import com.google.common.eventbus.Subscribe;
@@ -46,21 +45,24 @@ import com.google.common.eventbus.Subscribe;
@EventSubscriber
public class AmqpMessageDispatcherService extends BaseAmqpService {
@Autowired
private ArtifactUrlHandler artifactUrlHandler;
@Autowired
private AmqpSenderService amqpSenderService;
private final ArtifactUrlHandler artifactUrlHandler;
private final AmqpSenderService amqpSenderService;
/**
* Constructor.
*
* @param rabbitTemplate
* the rabbitTemplate
* @param amqpSenderService
* so send AMQP message
* @param artifactUrlHandler
* for generating download URLs
*/
@Autowired
public AmqpMessageDispatcherService(final RabbitTemplate rabbitTemplate) {
public AmqpMessageDispatcherService(final RabbitTemplate rabbitTemplate, final AmqpSenderService amqpSenderService,
final ArtifactUrlHandler artifactUrlHandler) {
super(rabbitTemplate);
this.artifactUrlHandler = artifactUrlHandler;
this.amqpSenderService = amqpSenderService;
}
/**
@@ -178,12 +180,4 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
artifact.setSize(localArtifact.getSize());
return artifact;
}
public void setArtifactUrlHandler(final ArtifactUrlHandler artifactUrlHandler) {
this.artifactUrlHandler = artifactUrlHandler;
}
public void setAmqpSenderService(final AmqpSenderService amqpSenderService) {
this.amqpSenderService = amqpSenderService;
}
}

View File

@@ -90,7 +90,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
private ControllerManagement controllerManagement;
@Autowired
private AmqpControllerAuthentfication authenticationManager;
private AmqpControllerAuthentication authenticationManager;
@Autowired
private ArtifactManagement artifactManagement;
@@ -503,7 +503,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
this.hostnameResolver = hostnameResolver;
}
void setAuthenticationManager(final AmqpControllerAuthentfication authenticationManager) {
void setAuthenticationManager(final AmqpControllerAuthentication authenticationManager) {
this.authenticationManager = authenticationManager;
}

View File

@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.amqp;
import java.util.concurrent.TimeUnit;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
@@ -20,6 +19,12 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
*/
@ConfigurationProperties("hawkbit.dmf.rabbitmq")
public class AmqpProperties {
/**
* Enable DMF API based on AMQP 0.9
*/
private boolean enabled = true;
/**
* DMF API dead letter queue.
*/
@@ -76,17 +81,10 @@ public class AmqpProperties {
*/
private int declarationRetries = 50;
/**
* @return the declarationRetries
*/
public int getDeclarationRetries() {
return declarationRetries;
}
/**
* @param declarationRetries
* the declarationRetries to set
*/
public void setDeclarationRetries(final int declarationRetries) {
this.declarationRetries = declarationRetries;
}
@@ -123,59 +121,26 @@ public class AmqpProperties {
this.maxConcurrentConsumers = maxConcurrentConsumers;
}
/**
* Is missingQueuesFatal enabled
*
* @see SimpleMessageListenerContainer#setMissingQueuesFatal
* @return the missingQueuesFatal <true> enabled <false> disabled
*/
public boolean isMissingQueuesFatal() {
return missingQueuesFatal;
}
/**
* @param missingQueuesFatal
* the missingQueuesFatal to set.
* @see SimpleMessageListenerContainer#setMissingQueuesFatal
*/
public void setMissingQueuesFatal(final boolean missingQueuesFatal) {
this.missingQueuesFatal = missingQueuesFatal;
}
/**
* Returns the dead letter exchange.
*
* @return dead letter exchange
*/
public String getDeadLetterExchange() {
return deadLetterExchange;
}
/**
* Sets the dead letter exchange.
*
* @param deadLetterExchange
* the deadLetterExchange to be set
*/
public void setDeadLetterExchange(final String deadLetterExchange) {
this.deadLetterExchange = deadLetterExchange;
}
/**
* Returns the dead letter queue.
*
* @return the dead letter queue
*/
public String getDeadLetterQueue() {
return deadLetterQueue;
}
/**
* Sets the dead letter queue.
*
* @param deadLetterQueue
* the deadLetterQueue ro be set
*/
public void setDeadLetterQueue(final String deadLetterQueue) {
this.deadLetterQueue = deadLetterQueue;
}
@@ -196,4 +161,11 @@ public class AmqpProperties {
this.receiverQueue = receiverQueue;
}
public boolean isEnabled() {
return enabled;
}
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
}

View File

@@ -61,7 +61,7 @@ public class AmqpControllerAuthenticationTest {
private AmqpMessageHandlerService amqpMessageHandlerService;
private MessageConverter messageConverter;
private TenantConfigurationManagement tenantConfigurationManagement;
private AmqpControllerAuthentfication authenticationManager;
private AmqpControllerAuthentication authenticationManager;
private static final TenantConfigurationValue<Boolean> CONFIG_VALUE_FALSE = TenantConfigurationValue
.<Boolean> builder().value(Boolean.FALSE).build();
@@ -77,9 +77,6 @@ public class AmqpControllerAuthenticationTest {
amqpMessageHandlerService = new AmqpMessageHandlerService(rabbitTemplate,
mock(AmqpMessageDispatcherService.class));
authenticationManager = new AmqpControllerAuthentfication();
authenticationManager.setControllerManagement(mock(ControllerManagement.class));
final DdiSecurityProperties secruityProperties = mock(DdiSecurityProperties.class);
final Rp rp = mock(Rp.class);
final org.eclipse.hawkbit.security.DdiSecurityProperties.Authentication ddiAuthentication = mock(
@@ -90,23 +87,22 @@ public class AmqpControllerAuthenticationTest {
when(secruityProperties.getAuthentication()).thenReturn(ddiAuthentication);
when(ddiAuthentication.getAnonymous()).thenReturn(anonymous);
when(anonymous.isEnabled()).thenReturn(false);
authenticationManager.setSecruityProperties(secruityProperties);
tenantConfigurationManagement = mock(TenantConfigurationManagement.class);
authenticationManager.setTenantConfigurationManagement(tenantConfigurationManagement);
when(tenantConfigurationManagement.getConfigurationValue(any(), eq(Boolean.class)))
.thenReturn(CONFIG_VALUE_FALSE);
final ControllerManagement controllerManagement = mock(ControllerManagement.class);
when(controllerManagement.getSecurityTokenByControllerId(anyString())).thenReturn(CONTROLLLER_ID);
authenticationManager.setControllerManagement(controllerManagement);
amqpMessageHandlerService.setArtifactManagement(mock(ArtifactManagement.class));
final SecurityContextTenantAware tenantAware = new SecurityContextTenantAware();
authenticationManager.setTenantAware(tenantAware);
final SystemSecurityContext systemSecurityContext = new SystemSecurityContext(tenantAware);
authenticationManager.setSystemSecurityContext(systemSecurityContext);
authenticationManager = new AmqpControllerAuthentication(controllerManagement, tenantConfigurationManagement,
tenantAware, secruityProperties, systemSecurityContext);
authenticationManager.postConstruct();
amqpMessageHandlerService.setAuthenticationManager(authenticationManager);
}

View File

@@ -79,17 +79,16 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest {
super.before();
this.rabbitTemplate = Mockito.mock(RabbitTemplate.class);
when(rabbitTemplate.getMessageConverter()).thenReturn(new Jackson2JsonMessageConverter());
amqpMessageDispatcherService = new AmqpMessageDispatcherService(rabbitTemplate);
amqpMessageDispatcherService = spy(amqpMessageDispatcherService);
senderService = Mockito.mock(DefaultAmqpSenderService.class);
amqpMessageDispatcherService.setAmqpSenderService(senderService);
final ArtifactUrlHandler artifactUrlHandlerMock = Mockito.mock(ArtifactUrlHandler.class);
when(artifactUrlHandlerMock.getUrl(anyString(), anyLong(), anyString(), anyString(), anyObject()))
.thenReturn("http://mockurl");
amqpMessageDispatcherService.setArtifactUrlHandler(artifactUrlHandlerMock);
amqpMessageDispatcherService = new AmqpMessageDispatcherService(rabbitTemplate, senderService,
artifactUrlHandlerMock);
amqpMessageDispatcherService = spy(amqpMessageDispatcherService);
}

View File

@@ -98,7 +98,7 @@ public class AmqpMessageHandlerServiceTest {
private ArtifactManagement artifactManagementMock;
@Mock
private AmqpControllerAuthentfication authenticationManagerMock;
private AmqpControllerAuthentication authenticationManagerMock;
@Mock
private ArtifactRepository artifactRepositoryMock;

View File

@@ -25,6 +25,7 @@ import org.eclipse.hawkbit.repository.model.Rollout;
import org.eclipse.hawkbit.repository.model.RolloutGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import com.google.common.eventbus.AllowConcurrentEvents;
import com.google.common.eventbus.EventBus;
@@ -40,6 +41,7 @@ import com.google.common.eventbus.Subscribe;
*
*/
@EventSubscriber
@Service
public class EventMerger {
private static final Set<RolloutEventKey> rolloutEvents = ConcurrentHashMap.newKeySet();