diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/repository/event/EventPublisherAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/repository/event/EventPublisherAutoConfiguration.java
index cd228b81f..a76e5ff38 100644
--- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/repository/event/EventPublisherAutoConfiguration.java
+++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/repository/event/EventPublisherAutoConfiguration.java
@@ -11,12 +11,14 @@ package org.eclipse.hawkbit.autoconfigure.repository.event;
import java.util.concurrent.Executor;
import org.eclipse.hawkbit.event.BusProtoStuffMessageConverter;
+import org.eclipse.hawkbit.repository.event.ApplicationEventFilter;
import org.eclipse.hawkbit.repository.event.remote.RemoteTenantAwareEvent;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.hawkbit.tenancy.TenantAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.bus.ConditionalOnBusEnabled;
import org.springframework.cloud.bus.ServiceMatcher;
import org.springframework.cloud.bus.jackson.RemoteApplicationEventScan;
@@ -58,7 +60,7 @@ public class EventPublisherAutoConfiguration {
@Bean(name = AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME)
public ApplicationEventMulticaster applicationEventMulticaster() {
final SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new TenantAwareApplicationEventPublisher(
- tenantAware);
+ tenantAware, applicationEventFilter());
simpleApplicationEventMulticaster.setTaskExecutor(executor);
return simpleApplicationEventMulticaster;
}
@@ -74,10 +76,22 @@ public class EventPublisherAutoConfiguration {
return EventPublisherHolder.getInstance();
}
+ /**
+ * @return default {@link ApplicationEventFilter} that does not filter any
+ * events
+ */
+ @Bean
+ @ConditionalOnMissingBean
+ public ApplicationEventFilter applicationEventFilter() {
+ return e -> false;
+ }
+
private static class TenantAwareApplicationEventPublisher extends SimpleApplicationEventMulticaster {
private final TenantAware tenantAware;
+ private final ApplicationEventFilter applicationEventFilter;
+
@Autowired(required = false)
private ServiceMatcher serviceMatcher;
@@ -87,8 +101,10 @@ public class EventPublisherAutoConfiguration {
* @param tenantAware
* the tenant ware
*/
- protected TenantAwareApplicationEventPublisher(final TenantAware tenantAware) {
+ protected TenantAwareApplicationEventPublisher(final TenantAware tenantAware,
+ final ApplicationEventFilter applicationEventFilter) {
this.tenantAware = tenantAware;
+ this.applicationEventFilter = applicationEventFilter;
}
/**
@@ -97,6 +113,10 @@ public class EventPublisherAutoConfiguration {
*/
@Override
public void multicastEvent(final ApplicationEvent event, final ResolvableType eventType) {
+ if (applicationEventFilter.filter(event)) {
+ return;
+ }
+
if (serviceMatcher == null || !(event instanceof RemoteTenantAwareEvent)) {
super.multicastEvent(event, eventType);
return;
diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java
index c60089fb3..4cbe068ef 100644
--- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java
+++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/RepositoryProperties.java
@@ -8,6 +8,7 @@
*/
package org.eclipse.hawkbit.repository;
+import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
import org.eclipse.hawkbit.repository.model.ActionStatus;
import org.springframework.boot.context.properties.ConfigurationProperties;
@@ -24,7 +25,14 @@ public class RepositoryProperties {
* is enforced you have to make sure that the feedback channel from the
* devices i in order.
*/
- private boolean rejectActionStatusForClosedAction = false;
+ private boolean rejectActionStatusForClosedAction;
+
+ /**
+ * Set to true if the repository should publish
+ * {@link TargetPollEvent}s in case a target connects to the repository.
+ * Activated by default but may be worth to disable if not needed.
+ */
+ private boolean publishTargetPollEvent = true;
public boolean isRejectActionStatusForClosedAction() {
return rejectActionStatusForClosedAction;
@@ -34,4 +42,12 @@ public class RepositoryProperties {
this.rejectActionStatusForClosedAction = rejectActionStatusForClosedAction;
}
+ public boolean isPublishTargetPollEvent() {
+ return publishTargetPollEvent;
+ }
+
+ public void setPublishTargetPollEvent(final boolean publishTargetPollEvent) {
+ this.publishTargetPollEvent = publishTargetPollEvent;
+ }
+
}
diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/ApplicationEventFilter.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/ApplicationEventFilter.java
new file mode 100644
index 000000000..1d1c964e3
--- /dev/null
+++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/ApplicationEventFilter.java
@@ -0,0 +1,28 @@
+/**
+ * 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.repository.event;
+
+import org.springframework.context.ApplicationEvent;
+
+/**
+ * ApplicationEventFilter for hawkBit internal {@link ApplicationEvent}
+ * publishing.
+ *
+ */
+@FunctionalInterface
+public interface ApplicationEventFilter {
+
+ /**
+ *
+ * @param event
+ * to verify
+ * @return true if event should be filtered
+ */
+ boolean filter(final ApplicationEvent event);
+}
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java
index de0af20a9..702824861 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaControllerManagement.java
@@ -48,7 +48,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule;
import org.eclipse.hawkbit.repository.model.Target;
import org.eclipse.hawkbit.repository.model.TargetUpdateStatus;
import org.eclipse.hawkbit.security.SystemSecurityContext;
-import org.eclipse.hawkbit.tenancy.TenantAware;
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -101,9 +100,6 @@ public class JpaControllerManagement implements ControllerManagement {
@Autowired
private TenantConfigurationManagement tenantConfigurationManagement;
- @Autowired
- private TenantAware tenantAware;
-
@Autowired
private SystemSecurityContext systemSecurityContext;
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java
index e9017a310..b6684e39a 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/RepositoryApplicationConfiguration.java
@@ -23,6 +23,7 @@ import org.eclipse.hawkbit.repository.DistributionSetTypeManagement;
import org.eclipse.hawkbit.repository.EntityFactory;
import org.eclipse.hawkbit.repository.PropertiesQuotaManagement;
import org.eclipse.hawkbit.repository.RepositoryDefaultConfiguration;
+import org.eclipse.hawkbit.repository.RepositoryProperties;
import org.eclipse.hawkbit.repository.RolloutGroupManagement;
import org.eclipse.hawkbit.repository.RolloutManagement;
import org.eclipse.hawkbit.repository.RolloutStatusCache;
@@ -39,8 +40,10 @@ import org.eclipse.hawkbit.repository.builder.DistributionSetTypeBuilder;
import org.eclipse.hawkbit.repository.builder.RolloutBuilder;
import org.eclipse.hawkbit.repository.builder.SoftwareModuleBuilder;
import org.eclipse.hawkbit.repository.builder.TargetFilterQueryBuilder;
+import org.eclipse.hawkbit.repository.event.ApplicationEventFilter;
import org.eclipse.hawkbit.repository.event.remote.EventEntityManager;
import org.eclipse.hawkbit.repository.event.remote.EventEntityManagerHolder;
+import org.eclipse.hawkbit.repository.event.remote.TargetPollEvent;
import org.eclipse.hawkbit.repository.jpa.aspects.ExceptionMappingAspectHandler;
import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignChecker;
import org.eclipse.hawkbit.repository.jpa.autoassign.AutoAssignScheduler;
@@ -145,6 +148,12 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration {
return new RolloutStatusCache(tenantAware);
}
+ @Bean
+ @ConditionalOnMissingBean
+ ApplicationEventFilter applicationEventFilter(final RepositoryProperties repositoryProperties) {
+ return e -> (e instanceof TargetPollEvent) && !repositoryProperties.isPublishTargetPollEvent();
+ }
+
/**
* @param distributionSetTypeManagement
* to loading the {@link DistributionSetType}
diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java
index 425452ec2..fc2878e03 100644
--- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java
+++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/ControllerManagementTest.java
@@ -432,6 +432,16 @@ public class ControllerManagementTest extends AbstractJpaIntegrationTest {
.as("register target with empty controllerId should fail");
}
+ @Test
+ @Description("Verify that controller registration does not result in a TargetPollEvent if feature is disabled")
+ @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
+ @Expect(type = TargetPollEvent.class, count = 0) })
+ public void targetPollEventNotSendIfDisabled() {
+ repositoryProperties.setPublishTargetPollEvent(false);
+ controllerManagement.findOrRegisterTargetIfItDoesNotexist("AA", LOCALHOST);
+ repositoryProperties.setPublishTargetPollEvent(true);
+ }
+
@Test
@Description("Controller trys to finish an update process after it has been finished by an error action status.")
@ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1),
diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java
index 03f535661..853e6c62c 100644
--- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java
+++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/TestConfiguration.java
@@ -23,6 +23,7 @@ import org.eclipse.hawkbit.cache.DownloadIdCache;
import org.eclipse.hawkbit.cache.TenantAwareCacheManager;
import org.eclipse.hawkbit.event.BusProtoStuffMessageConverter;
import org.eclipse.hawkbit.repository.RolloutStatusCache;
+import org.eclipse.hawkbit.repository.event.ApplicationEventFilter;
import org.eclipse.hawkbit.repository.model.helper.EventPublisherHolder;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyReplacer;
import org.eclipse.hawkbit.repository.rsql.VirtualPropertyResolver;
@@ -44,6 +45,7 @@ import org.springframework.cache.guava.GuavaCacheManager;
import org.springframework.cloud.bus.ConditionalOnBusEnabled;
import org.springframework.cloud.bus.ServiceMatcher;
import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.AdviceMode;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -51,6 +53,7 @@ import org.springframework.context.annotation.Profile;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.support.AbstractApplicationContext;
+import org.springframework.core.ResolvableType;
import org.springframework.data.domain.AuditorAware;
import org.springframework.integration.support.locks.DefaultLockRegistry;
import org.springframework.integration.support.locks.LockRegistry;
@@ -82,43 +85,43 @@ public class TestConfiguration implements AsyncConfigurer {
}
@Bean
- public LockRegistry lockRegistry() {
+ LockRegistry lockRegistry() {
return new DefaultLockRegistry();
}
@Bean
- public SecurityTokenGenerator securityTokenGenerator() {
+ SecurityTokenGenerator securityTokenGenerator() {
return new SecurityTokenGenerator();
}
@Bean
- public SystemSecurityContext systemSecurityContext(final TenantAware tenantAware) {
+ SystemSecurityContext systemSecurityContext(final TenantAware tenantAware) {
return new SystemSecurityContext(tenantAware);
}
@Bean
- public ArtifactRepository artifactRepository(final ArtifactFilesystemProperties artifactFilesystemProperties) {
+ ArtifactRepository artifactRepository(final ArtifactFilesystemProperties artifactFilesystemProperties) {
return new ArtifactFilesystemRepository(artifactFilesystemProperties);
}
@Bean
- public TestdataFactory testdataFactory() {
+ TestdataFactory testdataFactory() {
return new TestdataFactory();
}
@Bean
- public PropertyBasedArtifactUrlHandler testPropertyBasedArtifactUrlHandler(
+ PropertyBasedArtifactUrlHandler testPropertyBasedArtifactUrlHandler(
final ArtifactUrlHandlerProperties urlHandlerProperties) {
return new PropertyBasedArtifactUrlHandler(urlHandlerProperties);
}
@Bean
- public TenantAware tenantAware() {
+ TenantAware tenantAware() {
return new SecurityContextTenantAware();
}
@Bean
- public TenantAwareCacheManager cacheManager() {
+ TenantAwareCacheManager cacheManager() {
return new TenantAwareCacheManager(new GuavaCacheManager(), tenantAware());
}
@@ -128,29 +131,48 @@ public class TestConfiguration implements AsyncConfigurer {
* @return the cache
*/
@Bean
- public DownloadIdCache downloadIdCache() {
+ DownloadIdCache downloadIdCache() {
return new DefaultDownloadIdCache(cacheManager());
}
@Bean(name = AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME)
- public SimpleApplicationEventMulticaster applicationEventMulticaster() {
- final SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new SimpleApplicationEventMulticaster();
+ SimpleApplicationEventMulticaster applicationEventMulticaster(final ApplicationEventFilter applicationEventFilter) {
+ final SimpleApplicationEventMulticaster simpleApplicationEventMulticaster = new FilterEnabledApplicationEventPublisher(
+ applicationEventFilter);
simpleApplicationEventMulticaster.setTaskExecutor(asyncExecutor());
return simpleApplicationEventMulticaster;
}
+ private static class FilterEnabledApplicationEventPublisher extends SimpleApplicationEventMulticaster {
+
+ private final ApplicationEventFilter applicationEventFilter;
+
+ FilterEnabledApplicationEventPublisher(final ApplicationEventFilter applicationEventFilter) {
+ this.applicationEventFilter = applicationEventFilter;
+ }
+
+ @Override
+ public void multicastEvent(final ApplicationEvent event, final ResolvableType eventType) {
+ if (applicationEventFilter.filter(event)) {
+ return;
+ }
+
+ super.multicastEvent(event, eventType);
+ }
+ }
+
@Bean
- public EventPublisherHolder eventBusHolder() {
+ EventPublisherHolder eventBusHolder() {
return EventPublisherHolder.getInstance();
}
@Bean
- public Executor asyncExecutor() {
+ Executor asyncExecutor() {
return new DelegatingSecurityContextExecutorService(Executors.newSingleThreadExecutor());
}
@Bean
- public AuditorAware auditorAware() {
+ AuditorAware auditorAware() {
return new SpringSecurityAuditorAware();
}
@@ -169,13 +191,13 @@ public class TestConfiguration implements AsyncConfigurer {
* @return returns a VirtualPropertyReplacer
*/
@Bean
- public VirtualPropertyReplacer virtualPropertyReplacer() {
+ VirtualPropertyReplacer virtualPropertyReplacer() {
return new VirtualPropertyResolver();
}
@Bean
@ConditionalOnMissingBean
- public ServiceMatcher serviceMatcher(final ApplicationContext applicationContext) {
+ ServiceMatcher serviceMatcher(final ApplicationContext applicationContext) {
final ServiceMatcher serviceMatcher = new ServiceMatcher();
serviceMatcher.setMatcher(new AntPathMatcher(":"));
serviceMatcher.setApplicationContext(applicationContext);
@@ -188,7 +210,7 @@ public class TestConfiguration implements AsyncConfigurer {
*/
@Bean
@ConditionalOnBusEnabled
- public MessageConverter busProtoBufConverter() {
+ MessageConverter busProtoBufConverter() {
return new BusProtoStuffMessageConverter();
}
}
diff --git a/hawkbit-runtime/hawkbit-update-server/cf/manifest.yml b/hawkbit-runtime/hawkbit-update-server/cf/manifest.yml
index a1401afbc..3bbfaf71e 100644
--- a/hawkbit-runtime/hawkbit-update-server/cf/manifest.yml
+++ b/hawkbit-runtime/hawkbit-update-server/cf/manifest.yml
@@ -10,7 +10,8 @@
---
applications:
- name: hawkbit
- memory: 1024M
+ memory: 2048M
+ disk_quota: 2048M
instances: 1
buildpack: https://github.com/cloudfoundry/java-buildpack
path: @project.build.finalName@.jar
@@ -20,3 +21,5 @@ applications:
SPRING_PROFILES_ACTIVE: cloudsandbox,amqp
CF_STAGING_TIMEOUT: 15
CF_STARTUP_TIMEOUT: 15
+ JBP_CONFIG_JAVA_MAIN: '{ arguments: "-XX:+UseG1GC -XX:+UseStringDeduplication -XX:+UseCompressedOops -XX:+ExitOnOutOfMemoryError" }'
+ timeout: 180
diff --git a/hawkbit-runtime/hawkbit-update-server/src/main/resources/application.properties b/hawkbit-runtime/hawkbit-update-server/src/main/resources/application.properties
index c0c129c82..63eb680f2 100644
--- a/hawkbit-runtime/hawkbit-update-server/src/main/resources/application.properties
+++ b/hawkbit-runtime/hawkbit-update-server/src/main/resources/application.properties
@@ -16,6 +16,9 @@ hawkbit.server.ddi.security.authentication.anonymous.enabled=true
hawkbit.server.ddi.security.authentication.targettoken.enabled=true
hawkbit.server.ddi.security.authentication.gatewaytoken.enabled=true
+# Optional events
+hawkbit.server.repository.publish-target-poll-event=false
+
## Configuration for DMF/RabbitMQ integration
spring.profiles.active=amqp
spring.rabbitmq.username=guest