Merge remote-tracking branch 'origin/master' into
fix_Consitent_table_muliselect Signed-off-by: Melanie Retter <melanie.retter@bosch-si.com>
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.simulator.amqp;
|
package org.eclipse.hawkbit.simulator.amqp;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -15,6 +16,7 @@ import org.springframework.amqp.core.Binding;
|
|||||||
import org.springframework.amqp.core.BindingBuilder;
|
import org.springframework.amqp.core.BindingBuilder;
|
||||||
import org.springframework.amqp.core.FanoutExchange;
|
import org.springframework.amqp.core.FanoutExchange;
|
||||||
import org.springframework.amqp.core.Queue;
|
import org.springframework.amqp.core.Queue;
|
||||||
|
import org.springframework.amqp.core.QueueBuilder;
|
||||||
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
||||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
@@ -65,9 +67,12 @@ public class AmqpConfiguration {
|
|||||||
* @return the queue
|
* @return the queue
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public Queue receiverConnectorQueueFromSp() {
|
public Queue receiverConnectorQueueFromHawkBit() {
|
||||||
return new Queue(amqpProperties.getReceiverConnectorQueueFromSp(), true, false, false,
|
final Map<String, Object> arguments = getDeadLetterExchangeArgs();
|
||||||
getDeadLetterExchangeArgs());
|
arguments.putAll(getTTLMaxArgs());
|
||||||
|
|
||||||
|
return QueueBuilder.nonDurable(amqpProperties.getReceiverConnectorQueueFromSp()).withArguments(arguments)
|
||||||
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,7 +94,7 @@ public class AmqpConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public Binding bindReceiverQueueToSpExchange() {
|
public Binding bindReceiverQueueToSpExchange() {
|
||||||
return BindingBuilder.bind(receiverConnectorQueueFromSp()).to(exchangeQueueToConnector());
|
return BindingBuilder.bind(receiverConnectorQueueFromHawkBit()).to(exchangeQueueToConnector());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,7 +104,7 @@ public class AmqpConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public Queue deadLetterQueue() {
|
public Queue deadLetterQueue() {
|
||||||
return new Queue(amqpProperties.getDeadLetterQueue(), true, false, true);
|
return QueueBuilder.nonDurable(amqpProperties.getDeadLetterQueue()).withArguments(getTTLMaxArgs()).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -145,4 +150,11 @@ public class AmqpConfiguration {
|
|||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> getTTLMaxArgs() {
|
||||||
|
final Map<String, Object> args = new HashMap<>();
|
||||||
|
args.put("x-message-ttl", Duration.ofDays(1).toMillis());
|
||||||
|
args.put("x-max-length", 100_000);
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,21 +82,4 @@ public class MessageService {
|
|||||||
clazz.getTypeName());
|
clazz.getTypeName());
|
||||||
return (T) rabbitTemplate.getMessageConverter().fromMessage(message);
|
return (T) rabbitTemplate.getMessageConverter().fromMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to verify if lwm2m header is set.
|
|
||||||
*
|
|
||||||
* @param message
|
|
||||||
* the message with the header
|
|
||||||
* @param header
|
|
||||||
* the header to verify
|
|
||||||
*/
|
|
||||||
public void checkIfLwm2mHeaderEmpty(final Message message, final String header) {
|
|
||||||
final Object headerObject = message.getMessageProperties().getHeaders().get(header);
|
|
||||||
if (null == headerObject) {
|
|
||||||
logAndThrowMessageError(message, "Header of " + header + "empty.");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
<Logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN" />
|
<Logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN" />
|
||||||
<Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN" />
|
<Logger name="org.apache.tomcat.util.net.NioSelectorPool" level="WARN" />
|
||||||
<Logger name="org.apache.tomcat.jdbc.pool.ConnectionPool" level="DEBUG" />
|
|
||||||
<Logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR" />
|
<Logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR" />
|
||||||
|
|
||||||
<!-- Security Log with hints on potential attacks -->
|
<!-- Security Log with hints on potential attacks -->
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ import org.springframework.scheduling.annotation.EnableAsync;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableAsync
|
@EnableAsync
|
||||||
@ConditionalOnMissingBean(AsyncConfigurer.class)
|
@ConditionalOnMissingBean(AsyncConfigurer.class)
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public class AsyncConfigurerThreadpoolProperties {
|
|||||||
/**
|
/**
|
||||||
* Max queue size for central event executor.
|
* Max queue size for central event executor.
|
||||||
*/
|
*/
|
||||||
private Integer queuesize = 250;
|
private Integer queuesize = 5_000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core processing threads for central event executor.
|
* Core processing threads for central event executor.
|
||||||
@@ -30,7 +30,7 @@ public class AsyncConfigurerThreadpoolProperties {
|
|||||||
/**
|
/**
|
||||||
* Maximum thread pool size for central event executor.
|
* Maximum thread pool size for central event executor.
|
||||||
*/
|
*/
|
||||||
private Integer maxthreads = 50;
|
private Integer maxthreads = 20;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When the number of threads is greater than the core, this is the maximum
|
* When the number of threads is greater than the core, this is the maximum
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ package org.eclipse.hawkbit.autoconfigure.scheduling;
|
|||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@@ -21,6 +22,9 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
|
|||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.task.TaskExecutor;
|
||||||
|
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||||
import org.springframework.security.concurrent.DelegatingSecurityContextExecutor;
|
import org.springframework.security.concurrent.DelegatingSecurityContextExecutor;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
@@ -39,11 +43,21 @@ public class ExecutorAutoConfiguration {
|
|||||||
private AsyncConfigurerThreadpoolProperties asyncConfigurerProperties;
|
private AsyncConfigurerThreadpoolProperties asyncConfigurerProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ExecutorService for general purpose multi threaded operations
|
* @return ExecutorService with security context availability in thread
|
||||||
|
* execution..
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean
|
@ConditionalOnMissingBean
|
||||||
public Executor asyncExecutor() {
|
public Executor asyncExecutor() {
|
||||||
|
return new DelegatingSecurityContextExecutor(threadPoolExecutor());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return central ThreadPoolExecutor for general purpose multi threaded
|
||||||
|
* operations. Tries an orderly shutdown when destroyed.
|
||||||
|
*/
|
||||||
|
@Bean(destroyMethod = "shutdown")
|
||||||
|
public ThreadPoolExecutor threadPoolExecutor() {
|
||||||
final BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<>(
|
final BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<>(
|
||||||
asyncConfigurerProperties.getQueuesize());
|
asyncConfigurerProperties.getQueuesize());
|
||||||
final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(asyncConfigurerProperties.getCorethreads(),
|
final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(asyncConfigurerProperties.getCorethreads(),
|
||||||
@@ -53,7 +67,8 @@ public class ExecutorAutoConfiguration {
|
|||||||
threadPoolExecutor.setRejectedExecutionHandler((r, executor) -> LOGGER.warn(
|
threadPoolExecutor.setRejectedExecutionHandler((r, executor) -> LOGGER.warn(
|
||||||
"Reject runnable for centralExecutorService, reached limit of queue size {}",
|
"Reject runnable for centralExecutorService, reached limit of queue size {}",
|
||||||
executor.getQueue().size()));
|
executor.getQueue().size()));
|
||||||
return new DelegatingSecurityContextExecutor(threadPoolExecutor);
|
|
||||||
|
return threadPoolExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -69,4 +84,32 @@ public class ExecutorAutoConfiguration {
|
|||||||
return new DelegatingSecurityContextExecutor(threadPoolExecutor);
|
return new DelegatingSecurityContextExecutor(threadPoolExecutor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link TaskExecutor} for task execution
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public TaskExecutor taskExecutor() {
|
||||||
|
return new ConcurrentTaskExecutor(asyncExecutor());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link ScheduledExecutorService} based on
|
||||||
|
* {@link #threadPoolTaskScheduler()}.
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public ScheduledExecutorService scheduledExecutorService() {
|
||||||
|
return threadPoolTaskScheduler().getScheduledExecutor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link ThreadPoolTaskScheduler} for scheduled operations.
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
|
||||||
|
return new ThreadPoolTaskScheduler();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,12 +27,6 @@ vaadin.servlet.urlMapping=/UI/*
|
|||||||
vaadin.servlet.heartbeatInterval=60
|
vaadin.servlet.heartbeatInterval=60
|
||||||
vaadin.servlet.closeIdleSessions=false
|
vaadin.servlet.closeIdleSessions=false
|
||||||
|
|
||||||
# Defines the thread pool executor
|
|
||||||
hawkbit.threadpool.corethreads=5
|
|
||||||
hawkbit.threadpool.maxthreads=20
|
|
||||||
hawkbit.threadpool.idletimeout=10000
|
|
||||||
hawkbit.threadpool.queuesize=20000
|
|
||||||
|
|
||||||
# Defines the polling time for the controllers in HH:MM:SS notation
|
# Defines the polling time for the controllers in HH:MM:SS notation
|
||||||
hawkbit.controller.pollingTime=00:05:00
|
hawkbit.controller.pollingTime=00:05:00
|
||||||
hawkbit.controller.pollingOverdueTime=00:05:00
|
hawkbit.controller.pollingOverdueTime=00:05:00
|
||||||
|
|||||||
@@ -8,21 +8,32 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.amqp;
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings;
|
import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.amqp.core.Binding;
|
import org.springframework.amqp.core.Binding;
|
||||||
import org.springframework.amqp.core.BindingBuilder;
|
import org.springframework.amqp.core.BindingBuilder;
|
||||||
import org.springframework.amqp.core.FanoutExchange;
|
import org.springframework.amqp.core.FanoutExchange;
|
||||||
import org.springframework.amqp.core.Queue;
|
import org.springframework.amqp.core.Queue;
|
||||||
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
|
||||||
|
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
|
||||||
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
import org.springframework.amqp.rabbit.core.RabbitAdmin;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
||||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
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.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
|
||||||
|
import org.springframework.retry.support.RetryTemplate;;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The spring AMQP configuration which is enabled by using the profile
|
* The spring AMQP configuration which is enabled by using the profile
|
||||||
@@ -32,14 +43,68 @@ import org.springframework.context.annotation.Bean;
|
|||||||
@EnableConfigurationProperties({ AmqpProperties.class, AmqpDeadletterProperties.class })
|
@EnableConfigurationProperties({ AmqpProperties.class, AmqpDeadletterProperties.class })
|
||||||
public class AmqpConfiguration {
|
public class AmqpConfiguration {
|
||||||
|
|
||||||
@Autowired
|
private static final Logger LOGGER = LoggerFactory.getLogger(AmqpConfiguration.class);
|
||||||
protected AmqpProperties amqpProperties;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
protected AmqpDeadletterProperties amqpDeadletterProperties;
|
private AmqpProperties amqpProperties;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ConnectionFactory connectionFactory;
|
private AmqpDeadletterProperties amqpDeadletterProperties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("threadPoolExecutor")
|
||||||
|
private ThreadPoolExecutor threadPoolExecutor;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ConnectionFactory rabbitConnectionFactory;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
protected static class RabbitConnectionFactoryCreator {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private AmqpProperties amqpProperties;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
@Qualifier("threadPoolExecutor")
|
||||||
|
private ThreadPoolExecutor threadPoolExecutor;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ScheduledExecutorService scheduledExecutorService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link ConnectionFactory} with enabled publisher confirms and
|
||||||
|
* heartbeat.
|
||||||
|
*
|
||||||
|
* @param config
|
||||||
|
* with standard {@link RabbitProperties}
|
||||||
|
* @return {@link ConnectionFactory}
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public ConnectionFactory rabbitConnectionFactory(final RabbitProperties config) {
|
||||||
|
final CachingConnectionFactory factory = new CachingConnectionFactory();
|
||||||
|
factory.setRequestedHeartBeat(amqpProperties.getRequestedHeartBeat());
|
||||||
|
factory.setExecutor(threadPoolExecutor);
|
||||||
|
factory.getRabbitConnectionFactory().setHeartbeatExecutor(scheduledExecutorService);
|
||||||
|
factory.setPublisherConfirms(true);
|
||||||
|
|
||||||
|
final String addresses = config.getAddresses();
|
||||||
|
factory.setAddresses(addresses);
|
||||||
|
if (config.getHost() != null) {
|
||||||
|
factory.setHost(config.getHost());
|
||||||
|
factory.setPort(config.getPort());
|
||||||
|
}
|
||||||
|
if (config.getUsername() != null) {
|
||||||
|
factory.setUsername(config.getUsername());
|
||||||
|
}
|
||||||
|
if (config.getPassword() != null) {
|
||||||
|
factory.setPassword(config.getPassword());
|
||||||
|
}
|
||||||
|
if (config.getVirtualHost() != null) {
|
||||||
|
factory.setVirtualHost(config.getVirtualHost());
|
||||||
|
}
|
||||||
|
return factory;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link RabbitAdmin} and ignore declaration exceptions.
|
* Create a {@link RabbitAdmin} and ignore declaration exceptions.
|
||||||
@@ -49,20 +114,34 @@ public class AmqpConfiguration {
|
|||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public RabbitAdmin rabbitAdmin() {
|
public RabbitAdmin rabbitAdmin() {
|
||||||
final RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
|
final RabbitAdmin rabbitAdmin = new RabbitAdmin(rabbitConnectionFactory);
|
||||||
rabbitAdmin.setIgnoreDeclarationExceptions(true);
|
rabbitAdmin.setIgnoreDeclarationExceptions(true);
|
||||||
return rabbitAdmin;
|
return rabbitAdmin;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to set the Jackson2JsonMessageConverter.
|
* @return {@link RabbitTemplate} with automatic retry, published confirms
|
||||||
*
|
* and {@link Jackson2JsonMessageConverter}.
|
||||||
* @return the Jackson2JsonMessageConverter
|
|
||||||
*/
|
*/
|
||||||
@Bean
|
@Bean
|
||||||
public RabbitTemplate rabbitTemplate() {
|
public RabbitTemplate rabbitTemplate() {
|
||||||
final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
|
final RabbitTemplate rabbitTemplate = new RabbitTemplate(rabbitConnectionFactory);
|
||||||
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
|
rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
|
||||||
|
|
||||||
|
final RetryTemplate retryTemplate = new RetryTemplate();
|
||||||
|
retryTemplate.setBackOffPolicy(new ExponentialBackOffPolicy());
|
||||||
|
rabbitTemplate.setRetryTemplate(retryTemplate);
|
||||||
|
|
||||||
|
rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> {
|
||||||
|
if (ack) {
|
||||||
|
LOGGER.debug("Message with correlation ID {} confirmed by broker.", correlationData.getId());
|
||||||
|
} else {
|
||||||
|
LOGGER.error("Broker is unable to handle message with correlation ID {} : {}", correlationData.getId(),
|
||||||
|
cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
return rabbitTemplate;
|
return rabbitTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,7 +238,7 @@ public class AmqpConfiguration {
|
|||||||
public SimpleRabbitListenerContainerFactory listenerContainerFactory() {
|
public SimpleRabbitListenerContainerFactory listenerContainerFactory() {
|
||||||
final SimpleRabbitListenerContainerFactory containerFactory = new SimpleRabbitListenerContainerFactory();
|
final SimpleRabbitListenerContainerFactory containerFactory = new SimpleRabbitListenerContainerFactory();
|
||||||
containerFactory.setDefaultRequeueRejected(false);
|
containerFactory.setDefaultRequeueRejected(false);
|
||||||
containerFactory.setConnectionFactory(connectionFactory);
|
containerFactory.setConnectionFactory(rabbitConnectionFactory);
|
||||||
containerFactory.setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal());
|
containerFactory.setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal());
|
||||||
return containerFactory;
|
return containerFactory;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.amqp;
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
@@ -38,6 +40,11 @@ public class AmqpProperties {
|
|||||||
*/
|
*/
|
||||||
private boolean missingQueuesFatal = false;
|
private boolean missingQueuesFatal = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Requested heartbeat interval from broker in {@link TimeUnit#SECONDS}.
|
||||||
|
*/
|
||||||
|
private int requestedHeartBeat = (int) TimeUnit.SECONDS.toSeconds(60);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is missingQueuesFatal enabled
|
* Is missingQueuesFatal enabled
|
||||||
*
|
*
|
||||||
@@ -102,4 +109,13 @@ public class AmqpProperties {
|
|||||||
public void setReceiverQueue(final String receiverQueue) {
|
public void setReceiverQueue(final String receiverQueue) {
|
||||||
this.receiverQueue = receiverQueue;
|
this.receiverQueue = receiverQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getRequestedHeartBeat() {
|
||||||
|
return requestedHeartBeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRequestedHeartBeat(final int requestedHeartBeat) {
|
||||||
|
this.requestedHeartBeat = requestedHeartBeat;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ public class BaseAmqpService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final void logAndThrowMessageError(final Message message, final String error) {
|
protected final void logAndThrowMessageError(final Message message, final String error) {
|
||||||
LOGGER.warn("Error \"{}\" reported by message: {}", error, message);
|
LOGGER.warn("Warning! \"{}\" reported by message: {}", error, message);
|
||||||
throw new IllegalArgumentException(error);
|
throw new IllegalArgumentException(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,14 @@
|
|||||||
package org.eclipse.hawkbit.amqp;
|
package org.eclipse.hawkbit.amqp;
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.util.IpUtil;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.amqp.core.Message;
|
import org.springframework.amqp.core.Message;
|
||||||
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
||||||
|
import org.springframework.amqp.rabbit.support.CorrelationData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A default implementation for the sender service. The service sends all amqp
|
* A default implementation for the sender service. The service sends all amqp
|
||||||
@@ -20,6 +24,7 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
|||||||
* extracted from the uri.
|
* extracted from the uri.
|
||||||
*/
|
*/
|
||||||
public class DefaultAmqpSenderService implements AmqpSenderService {
|
public class DefaultAmqpSenderService implements AmqpSenderService {
|
||||||
|
private static final Logger LOGGER = LoggerFactory.getLogger(DefaultAmqpSenderService.class);
|
||||||
|
|
||||||
private final RabbitTemplate internalAmqpTemplate;
|
private final RabbitTemplate internalAmqpTemplate;
|
||||||
|
|
||||||
@@ -39,7 +44,16 @@ public class DefaultAmqpSenderService implements AmqpSenderService {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
internalAmqpTemplate.send(extractExchange(replyTo), null, message);
|
final String correlationId = UUID.randomUUID().toString();
|
||||||
|
final String exchange = extractExchange(replyTo);
|
||||||
|
|
||||||
|
if (LOGGER.isTraceEnabled()) {
|
||||||
|
LOGGER.trace("Sending message {} to exchange {} with correlationId {}", message, exchange, correlationId);
|
||||||
|
} else {
|
||||||
|
LOGGER.debug("Sending message to exchange {} with correlationId {}", exchange, correlationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
internalAmqpTemplate.send(exchange, null, message, new CorrelationData(correlationId));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,14 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit;
|
package org.eclipse.hawkbit;
|
||||||
|
|
||||||
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.ScheduledExecutorService;
|
||||||
|
import java.util.concurrent.ThreadPoolExecutor;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.amqp.AmqpProperties;
|
||||||
import org.eclipse.hawkbit.amqp.AmqpSenderService;
|
import org.eclipse.hawkbit.amqp.AmqpSenderService;
|
||||||
import org.eclipse.hawkbit.amqp.DefaultAmqpSenderService;
|
import org.eclipse.hawkbit.amqp.DefaultAmqpSenderService;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
|
import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder;
|
||||||
@@ -16,13 +24,22 @@ import org.springframework.amqp.rabbit.core.RabbitTemplate;
|
|||||||
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
|
||||||
import org.springframework.amqp.support.converter.MessageConverter;
|
import org.springframework.amqp.support.converter.MessageConverter;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.task.TaskExecutor;
|
||||||
|
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
|
||||||
|
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||||
|
import org.springframework.security.concurrent.DelegatingSecurityContextExecutor;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
|
@EnableConfigurationProperties({ AmqpProperties.class })
|
||||||
public class AmqpTestConfiguration {
|
public class AmqpTestConfiguration {
|
||||||
/**
|
/**
|
||||||
* @return the {@link SystemSecurityContext} singleton bean which make it
|
* @return the {@link SystemSecurityContext} singleton bean which make it
|
||||||
@@ -56,4 +73,55 @@ public class AmqpTestConfiguration {
|
|||||||
public AmqpSenderService amqpSenderServiceBean(final RabbitTemplate rabbitTemplate) {
|
public AmqpSenderService amqpSenderServiceBean(final RabbitTemplate rabbitTemplate) {
|
||||||
return new DefaultAmqpSenderService(rabbitTemplate);
|
return new DefaultAmqpSenderService(rabbitTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ExecutorService with security context availability in thread
|
||||||
|
* execution..
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public Executor asyncExecutor() {
|
||||||
|
return new DelegatingSecurityContextExecutor(threadPoolExecutor());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return central ThreadPoolExecutor for general purpose multi threaded
|
||||||
|
* operations. Tries an orderly shutdown when destroyed.
|
||||||
|
*/
|
||||||
|
@Bean(destroyMethod = "shutdown")
|
||||||
|
public ThreadPoolExecutor threadPoolExecutor() {
|
||||||
|
final BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<>(10);
|
||||||
|
final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 10, 1000, TimeUnit.MILLISECONDS,
|
||||||
|
blockingQueue, new ThreadFactoryBuilder().setNameFormat("central-executor-pool-%d").build());
|
||||||
|
|
||||||
|
return threadPoolExecutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link TaskExecutor} for task execution
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public TaskExecutor taskExecutor() {
|
||||||
|
return new ConcurrentTaskExecutor(asyncExecutor());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link ScheduledExecutorService} based on
|
||||||
|
* {@link #threadPoolTaskScheduler()}.
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public ScheduledExecutorService scheduledExecutorService() {
|
||||||
|
return threadPoolTaskScheduler().getScheduledExecutor();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return {@link ThreadPoolTaskScheduler} for scheduled operations.
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean
|
||||||
|
public ThreadPoolTaskScheduler threadPoolTaskScheduler() {
|
||||||
|
return new ThreadPoolTaskScheduler();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import ru.yandex.qatools.allure.annotations.Stories;
|
|||||||
@Stories("Test to generate the artifact download URL")
|
@Stories("Test to generate the artifact download URL")
|
||||||
@SpringApplicationConfiguration(classes = { AmqpTestConfiguration.class,
|
@SpringApplicationConfiguration(classes = { AmqpTestConfiguration.class,
|
||||||
org.eclipse.hawkbit.RepositoryApplicationConfiguration.class })
|
org.eclipse.hawkbit.RepositoryApplicationConfiguration.class })
|
||||||
|
|
||||||
public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTestWithMongoDB {
|
public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTestWithMongoDB {
|
||||||
|
|
||||||
private static final String HTTPS_LOCALHOST = "https://localhost:8080/";
|
private static final String HTTPS_LOCALHOST = "https://localhost:8080/";
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public final class Constants {
|
|||||||
* generated by repository for every new account for "Firmware/Operating
|
* generated by repository for every new account for "Firmware/Operating
|
||||||
* System" .
|
* System" .
|
||||||
*/
|
*/
|
||||||
public static final String SMT_DEFAULT_OS_NAME = "Firmware";
|
public static final String SMT_DEFAULT_OS_NAME = "OS";
|
||||||
/**
|
/**
|
||||||
* {@link SoftwareModuleType#getName()} of a {@link SoftwareModuleType}
|
* {@link SoftwareModuleType#getName()} of a {@link SoftwareModuleType}
|
||||||
* generated by repository for every new account for "applications/apps".
|
* generated by repository for every new account for "applications/apps".
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
|
||||||
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.Tag;
|
import org.eclipse.hawkbit.repository.model.Tag;
|
||||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
|
||||||
@@ -82,15 +84,26 @@ public interface DistributionSetRepository
|
|||||||
List<DistributionSet> findByModules(JpaSoftwareModule module);
|
List<DistributionSet> findByModules(JpaSoftwareModule module);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds {@link DistributionSet}s based on given ID if they are not assigned
|
* Finds {@link DistributionSet}s based on given ID that are assigned yet to
|
||||||
* yet to an {@link UpdateAction}, i.e. unused.
|
* an {@link Action}, i.e. in use.
|
||||||
*
|
*
|
||||||
* @param ids
|
* @param ids
|
||||||
* to search for
|
* to search for
|
||||||
* @return
|
* @return list of {@link DistributionSet#getId()}
|
||||||
*/
|
*/
|
||||||
@Query("select ac.distributionSet.id from JpaAction ac where ac.distributionSet.id in :ids")
|
@Query("select ac.distributionSet.id from JpaAction ac where ac.distributionSet.id in :ids")
|
||||||
List<Long> findAssignedDistributionSetsById(@Param("ids") Long... ids);
|
List<Long> findAssignedToTargetDistributionSetsById(@Param("ids") Long... ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds {@link DistributionSet}s based on given ID that are assigned yet to
|
||||||
|
* an {@link Rollout}, i.e. in use.
|
||||||
|
*
|
||||||
|
* @param ids
|
||||||
|
* to search for
|
||||||
|
* @return list of {@link DistributionSet#getId()}
|
||||||
|
*/
|
||||||
|
@Query("select ra.distributionSet.id from JpaRollout ra where ra.distributionSet.id in :ids")
|
||||||
|
List<Long> findAssignedToRolloutDistributionSetsById(@Param("ids") Long... ids);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves all given {@link DistributionSet}s.
|
* Saves all given {@link DistributionSet}s.
|
||||||
|
|||||||
@@ -173,7 +173,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement {
|
|||||||
public void deleteDistributionSet(final Long... distributionSetIDs) {
|
public void deleteDistributionSet(final Long... distributionSetIDs) {
|
||||||
final List<Long> toHardDelete = new ArrayList<>();
|
final List<Long> toHardDelete = new ArrayList<>();
|
||||||
|
|
||||||
final List<Long> assigned = distributionSetRepository.findAssignedDistributionSetsById(distributionSetIDs);
|
final List<Long> assigned = distributionSetRepository
|
||||||
|
.findAssignedToTargetDistributionSetsById(distributionSetIDs);
|
||||||
|
assigned.addAll(distributionSetRepository.findAssignedToRolloutDistributionSetsById(distributionSetIDs));
|
||||||
|
|
||||||
// soft delete assigned
|
// soft delete assigned
|
||||||
if (!assigned.isEmpty()) {
|
if (!assigned.isEmpty()) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet;
|
|||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetMetadata;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetTag;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSetType;
|
||||||
|
import org.eclipse.hawkbit.repository.jpa.model.JpaRollout;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
import org.eclipse.hawkbit.repository.jpa.model.JpaTarget;
|
||||||
import org.eclipse.hawkbit.repository.model.Action;
|
import org.eclipse.hawkbit.repository.model.Action;
|
||||||
@@ -34,12 +35,18 @@ import org.eclipse.hawkbit.repository.model.Action.Status;
|
|||||||
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
import org.eclipse.hawkbit.repository.model.ActionStatus;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
|
import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder;
|
||||||
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
import org.eclipse.hawkbit.repository.model.DistributionSetMetadata;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
import org.eclipse.hawkbit.repository.model.DistributionSetTag;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
import org.eclipse.hawkbit.repository.model.DistributionSetType;
|
||||||
|
import org.eclipse.hawkbit.repository.model.Rollout;
|
||||||
|
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorAction;
|
||||||
|
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupErrorCondition;
|
||||||
|
import org.eclipse.hawkbit.repository.model.RolloutGroup.RolloutGroupSuccessCondition;
|
||||||
|
import org.eclipse.hawkbit.repository.model.RolloutGroupConditionBuilder;
|
||||||
|
import org.eclipse.hawkbit.repository.model.RolloutGroupConditions;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
|
import org.eclipse.hawkbit.repository.test.util.WithUser;
|
||||||
import org.fest.assertions.core.Condition;
|
import org.fest.assertions.core.Condition;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.data.domain.Page;
|
import org.springframework.data.domain.Page;
|
||||||
@@ -777,36 +784,55 @@ public class DistributionSetManagementTest extends AbstractJpaIntegrationTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Deltes a DS that is no in use. Expected behaviour is a soft delete on the database, i.e. only marked as "
|
@Description("Deletes a DS that is in use by either target assignment or rollout. Expected behaviour is a soft delete on the database, i.e. only marked as "
|
||||||
+ "deleted, kept eas refernce and unavailable for future use..")
|
+ "deleted, kept as reference but unavailable for future use..")
|
||||||
public void deleteAssignedDistributionSet() {
|
public void deleteAssignedDistributionSet() {
|
||||||
DistributionSet ds1 = testdataFactory.createDistributionSet("ds-1");
|
DistributionSet ds1 = testdataFactory.createDistributionSet("ds-1");
|
||||||
DistributionSet ds2 = testdataFactory.createDistributionSet("ds-2");
|
DistributionSet ds2 = testdataFactory.createDistributionSet("ds-2");
|
||||||
DistributionSet dsAssigned = testdataFactory.createDistributionSet("ds-3");
|
DistributionSet dsToTargetAssigned = testdataFactory.createDistributionSet("ds-3");
|
||||||
|
final DistributionSet dsToRolloutAssigned = testdataFactory.createDistributionSet("ds-4");
|
||||||
|
|
||||||
ds1 = distributionSetManagement.findDistributionSetByNameAndVersion(ds1.getName(), ds1.getVersion());
|
ds1 = distributionSetManagement.findDistributionSetByNameAndVersion(ds1.getName(), ds1.getVersion());
|
||||||
ds2 = distributionSetManagement.findDistributionSetByNameAndVersion(ds2.getName(), ds2.getVersion());
|
ds2 = distributionSetManagement.findDistributionSetByNameAndVersion(ds2.getName(), ds2.getVersion());
|
||||||
|
|
||||||
// create assigned DS
|
// create assigned DS
|
||||||
dsAssigned = distributionSetManagement.findDistributionSetByNameAndVersion(dsAssigned.getName(),
|
dsToTargetAssigned = distributionSetManagement.findDistributionSetByNameAndVersion(dsToTargetAssigned.getName(),
|
||||||
dsAssigned.getVersion());
|
dsToTargetAssigned.getVersion());
|
||||||
final Target target = new JpaTarget("4712");
|
final Target target = new JpaTarget("4712");
|
||||||
final Target savedTarget = targetManagement.createTarget(target);
|
final Target savedTarget = targetManagement.createTarget(target);
|
||||||
final List<Target> toAssign = new ArrayList<>();
|
final List<Target> toAssign = new ArrayList<>();
|
||||||
toAssign.add(savedTarget);
|
toAssign.add(savedTarget);
|
||||||
deploymentManagement.assignDistributionSet(dsAssigned, toAssign);
|
deploymentManagement.assignDistributionSet(dsToTargetAssigned, toAssign);
|
||||||
|
|
||||||
// delete a ds
|
// create assigned rollout
|
||||||
assertThat(distributionSetRepository.findAll()).hasSize(3);
|
createRolloutByVariables("test", "test", 5, "name==*", dsToRolloutAssigned, "50", "5");
|
||||||
distributionSetManagement.deleteDistributionSet(dsAssigned.getId());
|
|
||||||
|
// delete assigned ds
|
||||||
|
assertThat(distributionSetRepository.findAll()).hasSize(4);
|
||||||
|
distributionSetManagement.deleteDistributionSet(dsToTargetAssigned.getId(), dsToRolloutAssigned.getId());
|
||||||
|
|
||||||
// not assigned so not marked as deleted
|
// not assigned so not marked as deleted
|
||||||
assertThat(distributionSetRepository.findAll()).hasSize(3);
|
assertThat(distributionSetRepository.findAll()).hasSize(4);
|
||||||
assertThat(distributionSetManagement
|
assertThat(distributionSetManagement
|
||||||
.findDistributionSetsByDeletedAndOrCompleted(pageReq, Boolean.FALSE, Boolean.TRUE).getTotalElements())
|
.findDistributionSetsByDeletedAndOrCompleted(pageReq, Boolean.FALSE, Boolean.TRUE).getTotalElements())
|
||||||
.isEqualTo(2);
|
.isEqualTo(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Rollout createRolloutByVariables(final String rolloutName, final String rolloutDescription,
|
||||||
|
final int groupSize, final String filterQuery, final DistributionSet distributionSet,
|
||||||
|
final String successCondition, final String errorCondition) {
|
||||||
|
final RolloutGroupConditions conditions = new RolloutGroupConditionBuilder()
|
||||||
|
.successCondition(RolloutGroupSuccessCondition.THRESHOLD, successCondition)
|
||||||
|
.errorCondition(RolloutGroupErrorCondition.THRESHOLD, errorCondition)
|
||||||
|
.errorAction(RolloutGroupErrorAction.PAUSE, null).build();
|
||||||
|
final Rollout rolloutToCreate = new JpaRollout();
|
||||||
|
rolloutToCreate.setName(rolloutName);
|
||||||
|
rolloutToCreate.setDescription(rolloutDescription);
|
||||||
|
rolloutToCreate.setTargetFilterQuery(filterQuery);
|
||||||
|
rolloutToCreate.setDistributionSet(distributionSet);
|
||||||
|
return rolloutManagement.createRollout(rolloutToCreate, groupSize, conditions);
|
||||||
|
}
|
||||||
|
|
||||||
private Target sendUpdateActionStatusToTarget(final Status status, final Action updActA, final Target t,
|
private Target sendUpdateActionStatusToTarget(final Status status, final Action updActA, final Target t,
|
||||||
final String... msgs) {
|
final String... msgs) {
|
||||||
updActA.setStatus(status);
|
updActA.setStatus(status);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ package org.eclipse.hawkbit.repository.jpa.rsql;
|
|||||||
|
|
||||||
import static org.fest.assertions.api.Assertions.assertThat;
|
import static org.fest.assertions.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.Constants;
|
||||||
import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields;
|
import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields;
|
||||||
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
import org.eclipse.hawkbit.repository.model.SoftwareModuleType;
|
||||||
@@ -34,7 +35,7 @@ public class RSQLSoftwareModuleTypeFieldsTest extends AbstractJpaIntegrationTest
|
|||||||
@Test
|
@Test
|
||||||
@Description("Test filter software module test type by name")
|
@Description("Test filter software module test type by name")
|
||||||
public void testFilterByParameterName() {
|
public void testFilterByParameterName() {
|
||||||
assertRSQLQuery(SoftwareModuleTypeFields.NAME.name() + "==Firmware", 1);
|
assertRSQLQuery(SoftwareModuleTypeFields.NAME.name() + "==" + Constants.SMT_DEFAULT_OS_NAME, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -26,11 +26,16 @@ public class DistributionSetTypeEvent {
|
|||||||
|
|
||||||
private final DistributionSetTypeEnum distributionSetTypeEnum;
|
private final DistributionSetTypeEnum distributionSetTypeEnum;
|
||||||
|
|
||||||
|
private String distributionSetTypeName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param distributionSetTypeEnum
|
* @param distributionSetTypeEnum
|
||||||
|
* @param distributionSetTypeName
|
||||||
*/
|
*/
|
||||||
public DistributionSetTypeEvent(final DistributionSetTypeEnum distributionSetTypeEnum) {
|
public DistributionSetTypeEvent(final DistributionSetTypeEnum distributionSetTypeEnum,
|
||||||
|
final String distributionSetTypeName) {
|
||||||
this.distributionSetTypeEnum = distributionSetTypeEnum;
|
this.distributionSetTypeEnum = distributionSetTypeEnum;
|
||||||
|
this.distributionSetTypeName = distributionSetTypeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -43,6 +48,14 @@ public class DistributionSetTypeEvent {
|
|||||||
this.distributionSetType = distributionSetType;
|
this.distributionSetType = distributionSetType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getDistributionSetTypeName() {
|
||||||
|
return distributionSetTypeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDistributionSetTypeName(final String distributionSetTypeName) {
|
||||||
|
this.distributionSetTypeName = distributionSetTypeName;
|
||||||
|
}
|
||||||
|
|
||||||
public DistributionSetType getDistributionSetType() {
|
public DistributionSetType getDistributionSetType() {
|
||||||
return distributionSetType;
|
return distributionSetType;
|
||||||
}
|
}
|
||||||
|
|||||||
1
pom.xml
1
pom.xml
@@ -69,6 +69,7 @@
|
|||||||
<jackson.version>2.5.5</jackson.version>
|
<jackson.version>2.5.5</jackson.version>
|
||||||
<hibernate-validator.version>5.2.4.Final</hibernate-validator.version>
|
<hibernate-validator.version>5.2.4.Final</hibernate-validator.version>
|
||||||
<spring-cloud-connectors.version>1.2.0.RELEASE</spring-cloud-connectors.version>
|
<spring-cloud-connectors.version>1.2.0.RELEASE</spring-cloud-connectors.version>
|
||||||
|
<spring-amqp.version>1.6.0.RELEASE</spring-amqp.version>
|
||||||
<spring-hateoas.version>0.18.0.RELEASE</spring-hateoas.version>
|
<spring-hateoas.version>0.18.0.RELEASE</spring-hateoas.version>
|
||||||
<!-- Support for MongoDB 3 -->
|
<!-- Support for MongoDB 3 -->
|
||||||
<spring-data-releasetrain.version>Fowler-SR1</spring-data-releasetrain.version>
|
<spring-data-releasetrain.version>Fowler-SR1</spring-data-releasetrain.version>
|
||||||
|
|||||||
Reference in New Issue
Block a user