Create dmf test module (#493)

* Add DMF parent module + submodules

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* Fix sonar issue

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* Refactor Test Module 

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* - Fix tenant is empty
- Small refactoring

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* Remove org.springframework.context.annotation.Description

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* Configure rabbit test template

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* Fix header

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* tenant should not be empty

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* Increase time out

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* Increase 3 to sec.

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* Fix comments

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* Add port 

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>

* Fix test config

Signed-off-by: SirWayne <dennis.melzer@bosch-si.com>
This commit is contained in:
Dennis Melzer
2017-04-26 10:36:21 +02:00
committed by GitHub
parent 574fda1101
commit f608f49db0
60 changed files with 472 additions and 288 deletions

View File

@@ -0,0 +1,62 @@
<!--
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
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-dmf-parent</artifactId>
<version>0.2.0-SNAPSHOT</version>
</parent>
<artifactId>hawkbit-dmf-rabbitmq-test</artifactId>
<name>hawkBit :: DMF RabbitMq Test module</name>
<dependencies>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-jpa</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-dmf-api</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-junit</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.hawkbit</groupId>
<artifactId>hawkbit-repository-test</artifactId>
<version>${project.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,101 @@
/**
* 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.rabbitmq.test;
import static java.util.concurrent.TimeUnit.SECONDS;
import java.util.concurrent.TimeUnit;
import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration;
import org.eclipse.hawkbit.repository.test.util.AbstractIntegrationTest;
import org.junit.Before;
import org.junit.Rule;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.junit.BrokerRunning;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import com.jayway.awaitility.Awaitility;
import com.jayway.awaitility.core.ConditionFactory;
@SpringApplicationConfiguration(classes = { RepositoryApplicationConfiguration.class, AmqpTestConfiguration.class })
// Dirty context is necessary to create a new vhost and recreate all necessary
// beans after every test class.
@DirtiesContext(classMode = ClassMode.AFTER_CLASS)
public abstract class AbstractAmqpIntegrationTest extends AbstractIntegrationTest {
@Rule
@Autowired
public BrokerRunning brokerRunning;
@Autowired
private ConnectionFactory connectionFactory;
@Autowired
private RabbitAdmin rabbitAdmin;
private RabbitTemplate dmfClient;
@Before
public void setup() {
dmfClient = createDmfClient();
}
protected abstract String getExchange();
protected RabbitTemplate getDmfClient() {
return dmfClient;
}
protected ConditionFactory createConditionFactory() {
return Awaitility.await().atMost(2, SECONDS);
}
protected Message createMessage(final Object payload, final MessageProperties messageProperties) {
if (payload == null) {
messageProperties.setContentType(MessageProperties.CONTENT_TYPE_JSON);
return new Message(null, messageProperties);
}
return getDmfClient().getMessageConverter().toMessage(payload, messageProperties);
}
protected int getQueueMessageCount(String queueName) {
return Integer
.parseInt(rabbitAdmin.getQueueProperties(queueName).get(RabbitAdmin.QUEUE_MESSAGE_COUNT).toString());
}
protected RabbitAdmin getRabbitAdmin() {
return rabbitAdmin;
}
private RabbitTemplate createDmfClient() {
final RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(new Jackson2JsonMessageConverter());
template.setReceiveTimeout(TimeUnit.SECONDS.toMillis(3));
template.setReplyTimeout(TimeUnit.SECONDS.toMillis(3));
template.setExchange(getExchange());
return template;
}
protected String getVirtualHost() {
return connectionFactory.getVirtualHost();
}
protected int getPort() {
return connectionFactory.getPort();
}
}

View File

@@ -0,0 +1,126 @@
/**
* 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.rabbitmq.test;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.eclipse.hawkbit.HawkbitServerProperties;
import org.eclipse.hawkbit.api.HostnameResolver;
import org.eclipse.hawkbit.rabbitmq.test.RabbitMqSetupService.AlivenessException;
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.junit.BrokerRunning;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.task.TaskExecutor;
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.security.concurrent.DelegatingSecurityContextExecutorService;
import com.google.common.base.Throwables;
/**
*
*/
@Configuration
public class AmqpTestConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(AmqpTestConfiguration.class);
@Bean
SystemSecurityContextHolder systemSecurityContextHolder() {
return SystemSecurityContextHolder.getInstance();
}
@Bean
Executor asyncExecutor() {
return new DelegatingSecurityContextExecutorService(Executors.newSingleThreadExecutor());
}
@Bean
TaskExecutor taskExecutor() {
return new ConcurrentTaskExecutor(asyncExecutor());
}
@Bean
ScheduledExecutorService scheduledExecutorService() {
return threadPoolTaskScheduler().getScheduledExecutor();
}
@Bean
ThreadPoolTaskScheduler threadPoolTaskScheduler() {
return new ThreadPoolTaskScheduler();
}
@Bean
HostnameResolver hostnameResolver(final HawkbitServerProperties serverProperties) {
return () -> {
try {
return new URL(serverProperties.getUrl());
} catch (final MalformedURLException e) {
throw Throwables.propagate(e);
}
};
}
@Bean
ConnectionFactory rabbitConnectionFactory(final RabbitMqSetupService rabbitmqSetupService) {
final CachingConnectionFactory factory = new CachingConnectionFactory();
factory.setHost(rabbitmqSetupService.getHostname());
factory.setPort(5672);
factory.setUsername(rabbitmqSetupService.getUsername());
factory.setPassword(rabbitmqSetupService.getPassword());
try {
factory.setVirtualHost(rabbitmqSetupService.createVirtualHost());
// All exception are catched. The BrokerRunning decide if the
// test should break or not
} catch (@SuppressWarnings("squid:S2221") final Exception e) {
Throwables.propagateIfInstanceOf(e, AlivenessException.class);
LOG.error("Cannot create virtual host {}", e.getMessage());
}
return factory;
}
@Bean
RabbitMqSetupService rabbitmqSetupService(RabbitProperties properties) {
return new RabbitMqSetupService(properties);
}
@Bean
@Primary
public RabbitTemplate rabbitTemplateForTest(ConnectionFactory connectionFactory) {
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
rabbitTemplate.setReplyTimeout(TimeUnit.SECONDS.toMillis(3));
rabbitTemplate.setReceiveTimeout(TimeUnit.SECONDS.toMillis(3));
return rabbitTemplate;
}
@Bean
BrokerRunning brokerRunning(RabbitMqSetupService rabbitmqSetupService) {
final BrokerRunning brokerRunning = BrokerRunning.isRunning();
brokerRunning.setHostName(rabbitmqSetupService.getHostname());
brokerRunning.getConnectionFactory().setUsername(rabbitmqSetupService.getUsername());
brokerRunning.getConnectionFactory().setPassword(rabbitmqSetupService.getPassword());
return brokerRunning;
}
}

View File

@@ -0,0 +1,127 @@
/**
* 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.rabbitmq.test;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.util.UUID;
import javax.annotation.PreDestroy;
import org.springframework.boot.autoconfigure.amqp.RabbitProperties;
import org.springframework.util.StringUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.base.Throwables;
import com.rabbitmq.http.client.Client;
import com.rabbitmq.http.client.domain.UserPermissions;
/**
* Creates and deletes a new virtual host if the rabbit mq management api is
* available.
*
*
*/
public class RabbitMqSetupService {
private static final String GUEST = "guest";
private static final String DEFAULT_USER = GUEST;
private static final String DEFAULT_PASSWORD = GUEST;
private Client rabbitmqHttpClient;
private String virtualHost;
private final String hostname;
private String username;
private String password;
public RabbitMqSetupService(RabbitProperties properties) {
hostname = properties.getHost();
username = properties.getUsername();
if (StringUtils.isEmpty(username)) {
username = DEFAULT_USER;
}
password = properties.getPassword();
if (StringUtils.isEmpty(password)) {
password = DEFAULT_PASSWORD;
}
}
private synchronized Client getRabbitmqHttpClient() {
if (rabbitmqHttpClient == null) {
try {
rabbitmqHttpClient = new Client(getHttpApiUrl(), getUsername(), getPassword());
} catch (MalformedURLException | URISyntaxException e) {
throw Throwables.propagate(e);
}
}
return rabbitmqHttpClient;
}
public String getHttpApiUrl() {
return "http://" + getHostname() + ":15672/api/";
}
@SuppressWarnings("squid:S1162")
public String createVirtualHost() throws JsonProcessingException {
if (!getRabbitmqHttpClient().alivenessTest("/")) {
throw new AlivenessException(getHostname());
}
virtualHost = UUID.randomUUID().toString();
getRabbitmqHttpClient().createVhost(virtualHost);
getRabbitmqHttpClient().updatePermissions(virtualHost, getUsername(), createUserPermissionsFullAccess());
return virtualHost;
}
@PreDestroy
public void deleteVirtualHost() {
if (StringUtils.isEmpty(virtualHost)) {
return;
}
getRabbitmqHttpClient().deleteVhost(virtualHost);
}
public String getHostname() {
return hostname;
}
public String getPassword() {
return password;
}
public String getUsername() {
return username;
}
private UserPermissions createUserPermissionsFullAccess() {
final UserPermissions permissions = new UserPermissions();
permissions.setVhost(virtualHost);
permissions.setRead(".*");
permissions.setConfigure(".*");
permissions.setWrite(".*");
return permissions;
}
static class AlivenessException extends RuntimeException {
private static final long serialVersionUID = 1L;
public AlivenessException(String hostname) {
super("Aliveness test failed for " + hostname
+ ":15672 guest/quest; rabbit mq management api not available");
}
}
}

View File

@@ -0,0 +1,23 @@
/**
* 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.rabbitmq.test.listener;
import org.springframework.amqp.core.Message;
@FunctionalInterface
public interface TestRabbitListener {
/**
* handle incoming message
*
* @param message
* the message
*/
void handleMessage(Message message);
}