From 0f75c63878e6b919dd1dab38662bce158d43acd4 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Thu, 19 May 2016 14:20:32 +0200 Subject: [PATCH 001/118] Some clean code refactorings Signed-off-by: SirWayne --- 3rd-dependencies/listDeps.sh | 0 .../api/ArtifactUrlHandlerProperties.java | 214 ++---------------- .../api/DefaultProtocolProperties.java | 79 +++++++ .../api/PropertyBasedArtifactUrlHandler.java | 3 +- .../hawkbit/api/ProtocolProperties.java | 40 ++++ .../hawkbit/cache/TenancyCacheManager.java | 2 +- .../cache/TenantAwareCacheManager.java | 2 +- .../tenancy/configuration/DurationHelper.java | 2 +- .../amqp/AmqpMessageDispatcherService.java | 4 +- .../amqp/AmqpMessageHandlerService.java | 4 +- .../eclipse/hawkbit/amqp/BaseAmqpService.java | 12 +- 11 files changed, 144 insertions(+), 218 deletions(-) mode change 100644 => 100755 3rd-dependencies/listDeps.sh create mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/api/DefaultProtocolProperties.java create mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ProtocolProperties.java diff --git a/3rd-dependencies/listDeps.sh b/3rd-dependencies/listDeps.sh old mode 100644 new mode 100755 diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandlerProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandlerProperties.java index 50f3f4cad..490b2d102 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandlerProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ArtifactUrlHandlerProperties.java @@ -16,8 +16,6 @@ import org.springframework.boot.context.properties.ConfigurationProperties; */ @ConfigurationProperties("hawkbit.artifact.url") public class ArtifactUrlHandlerProperties { - private static final String DEFAULT_IP_LOCALHOST = "127.0.0.1"; - private static final String LOCALHOST = "localhost"; private final Http http = new Http(); private final Https https = new Https(); @@ -54,227 +52,45 @@ public class ArtifactUrlHandlerProperties { } } - /** - * Interface for declaring common properties through all supported protocols - * pattern. - */ - public interface ProtocolProperties { - /** - * @return the hostname value to resolve in the pattern. - */ - String getHostname(); - - /** - * @return the IP address value to resolve in the pattern. - */ - String getIp(); - - /** - * @return the port value to resolve in the pattern. - */ - String getPort(); - - /** - * @return the pattern to build the URL. - */ - String getPattern(); - - /** - * @return true if the {@link ProtocolProperties} is - * enabled. - */ - boolean isEnabled(); - } - /** * Object to hold the properties for the HTTP protocol. */ - public static class Http implements ProtocolProperties { - private String hostname = LOCALHOST; - private String ip = DEFAULT_IP_LOCALHOST; - private String port = ""; - /** - * An ant-URL pattern with placeholder to build the URL on. The URL can - * have specific artifact placeholder. - */ - private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}"; + public static class Http extends DefaultProtocolProperties { /** - * Enables HTTP URI generation in DDI and DMF. + * Constructor. */ - private boolean enabled = true; - - @Override - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(final boolean enabled) { - this.enabled = enabled; - } - - @Override - public String getHostname() { - return hostname; - } - - public void setHostname(final String hostname) { - this.hostname = hostname; - } - - @Override - public String getIp() { - return ip; - } - - public void setIp(final String ip) { - this.ip = ip; - } - - @Override - public String getPattern() { - return pattern; - } - - public void setPattern(final String urlPattern) { - this.pattern = urlPattern; - } - - @Override - public String getPort() { - return port; - } - - public void setPort(final String port) { - this.port = port; + public Http() { + setPattern( + "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}"); } } /** * Object to hold the properties for the HTTP protocol. */ - public static class Https implements ProtocolProperties { - private String hostname = LOCALHOST; - private String ip = DEFAULT_IP_LOCALHOST; - private String port = ""; - /** - * An ant-URL pattern with placeholder to build the URL on. The URL can - * have specific artifact placeholder. - */ - private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}"; + public static class Https extends DefaultProtocolProperties { /** - * Enables HTTPS URI generation in DDI and DMF. + * Constructor. */ - private boolean enabled = true; - - @Override - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(final boolean enabled) { - this.enabled = enabled; - } - - @Override - public String getHostname() { - return hostname; - } - - public void setHostname(final String hostname) { - this.hostname = hostname; - } - - @Override - public String getIp() { - return ip; - } - - public void setIp(final String ip) { - this.ip = ip; - } - - @Override - public String getPattern() { - return pattern; - } - - public void setPattern(final String urlPattern) { - this.pattern = urlPattern; - } - - @Override - public String getPort() { - return port; - } - - public void setPort(final String port) { - this.port = port; + public Https() { + setPattern( + "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}"); } } /** * Object to hold the properties for the HTTP protocol. */ - public static class Coap implements ProtocolProperties { - private String hostname = LOCALHOST; - private String ip = DEFAULT_IP_LOCALHOST; - private String port = "5683"; - /** - * An ant-URL pattern with placeholder to build the URL on. The URL can - * have specific artifact placeholder. - */ - private String pattern = "{protocol}://{ip}:{port}/fw/{tenant}/{targetId}/sha1/{artifactSHA1}"; + public static class Coap extends DefaultProtocolProperties { /** - * Enables CoAP URI generation in DMF. + * Constructor. */ - private boolean enabled = true; - - @Override - public boolean isEnabled() { - return enabled; - } - - public void setEnabled(final boolean enabled) { - this.enabled = enabled; - } - - @Override - public String getHostname() { - return hostname; - } - - public void setHostname(final String hostname) { - this.hostname = hostname; - } - - @Override - public String getIp() { - return ip; - } - - public void setIp(final String ip) { - this.ip = ip; - } - - @Override - public String getPattern() { - return pattern; - } - - public void setPattern(final String urlPattern) { - this.pattern = urlPattern; - } - - @Override - public String getPort() { - return port; - } - - public void setPort(final String port) { - this.port = port; + public Coap() { + setPattern("{protocol}://{ip}:{port}/fw/{tenant}/{targetId}/sha1/{artifactSHA1}"); + setPort("5683"); } } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/DefaultProtocolProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/DefaultProtocolProperties.java new file mode 100644 index 000000000..9d053104c --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/DefaultProtocolProperties.java @@ -0,0 +1,79 @@ +/** + * 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.api; + +/** + * Object to hold the properties for the base protocols. + */ +public class DefaultProtocolProperties implements ProtocolProperties { + // The IP address is not hardcoded. It's the default value, if the IP + // address is not configured. + @SuppressWarnings("squid:S1313") + private static final String DEFAULT_IP_LOCALHOST = "127.0.0.1"; + private static final String LOCALHOST = "localhost"; + + private String hostname = LOCALHOST; + private String ip = DEFAULT_IP_LOCALHOST; + private String port = ""; + /** + * An ant-URL pattern with placeholder to build the URL on. The URL can have + * specific artifact placeholder. + */ + private String pattern; + + /** + * Enables protocol. + */ + private boolean enabled = true; + + @Override + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + } + + @Override + public String getHostname() { + return hostname; + } + + public void setHostname(final String hostname) { + this.hostname = hostname; + } + + @Override + public String getIp() { + return ip; + } + + public void setIp(final String ip) { + this.ip = ip; + } + + @Override + public String getPattern() { + return pattern; + } + + public void setPattern(final String urlPattern) { + this.pattern = urlPattern; + } + + @Override + public String getPort() { + return port; + } + + public void setPort(final String port) { + this.port = port; + } +} \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/PropertyBasedArtifactUrlHandler.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/PropertyBasedArtifactUrlHandler.java index 0072f2fbd..53f6492d1 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/PropertyBasedArtifactUrlHandler.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/PropertyBasedArtifactUrlHandler.java @@ -13,7 +13,6 @@ import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import org.eclipse.hawkbit.api.ArtifactUrlHandlerProperties.ProtocolProperties; import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -61,7 +60,7 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler { for (final Entry entry : entrySet) { if (entry.getKey().equals(PORT_PLACEHOLDER)) { urlPattern = urlPattern.replace(":{" + entry.getKey() + "}", - Strings.isNullOrEmpty(entry.getValue()) ? "" : ":" + entry.getValue()); + Strings.isNullOrEmpty(entry.getValue()) ? "" : (":" + entry.getValue())); } else { urlPattern = urlPattern.replace("{" + entry.getKey() + "}", entry.getValue()); } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ProtocolProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ProtocolProperties.java new file mode 100644 index 000000000..c4a9556b7 --- /dev/null +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ProtocolProperties.java @@ -0,0 +1,40 @@ +/** + * 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.api; + +/** + * Interface for declaring common properties through all supported protocols + * pattern. + */ +public interface ProtocolProperties { + /** + * @return the hostname value to resolve in the pattern. + */ + String getHostname(); + + /** + * @return the IP address value to resolve in the pattern. + */ + String getIp(); + + /** + * @return the port value to resolve in the pattern. + */ + String getPort(); + + /** + * @return the pattern to build the URL. + */ + String getPattern(); + + /** + * @return true if the {@link ProtocolProperties} is enabled. + */ + boolean isEnabled(); +} \ No newline at end of file diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/cache/TenancyCacheManager.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/cache/TenancyCacheManager.java index 5b58ea53e..9338bcbe7 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/cache/TenancyCacheManager.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/cache/TenancyCacheManager.java @@ -13,7 +13,7 @@ import org.springframework.cache.CacheManager; /** * - * + * A cache interface which handles multi tenancy. */ public interface TenancyCacheManager extends CacheManager { diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/cache/TenantAwareCacheManager.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/cache/TenantAwareCacheManager.java index 435f1b2e1..055d9bf6c 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/cache/TenantAwareCacheManager.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/cache/TenantAwareCacheManager.java @@ -67,7 +67,7 @@ public class TenantAwareCacheManager implements TenancyCacheManager { public Collection getCacheNames() { String currentTenant = tenantAware.getCurrentTenant(); if (currentTenant == null) { - return null; + return Collections.emptyList(); } currentTenant = currentTenant.toUpperCase(); diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/DurationHelper.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/DurationHelper.java index 5968f4420..befd00c5d 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/DurationHelper.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/DurationHelper.java @@ -27,7 +27,7 @@ public final class DurationHelper { * the defined min/max range. * */ - public static class DurationRangeValidator { + public static final class DurationRangeValidator { final Duration min; final Duration max; diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java index dae5772e6..bbd7b6b48 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java @@ -55,8 +55,8 @@ public class AmqpMessageDispatcherService extends BaseAmqpService { /** * Constructor. * - * @param messageConverter - * message converter + * @param rabbitTemplate + * the rabbitTemplate */ @Autowired public AmqpMessageDispatcherService(final RabbitTemplate rabbitTemplate) { diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index f26d7f3f7..7a452c603 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -107,6 +107,8 @@ public class AmqpMessageHandlerService extends BaseAmqpService { super(defaultTemplate); } + // Method is not unused. It is called by the spring rabbit listener. + @SuppressWarnings("squid:UnusedPrivateMethod") @RabbitListener(queues = "${hawkbit.dmf.rabbitmq.receiverQueue}", containerFactory = "listenerContainerFactory") private Message onMessage(final Message message, @Header(MessageHeaderKey.TYPE) final String type, @Header(MessageHeaderKey.TENANT) final String tenant) { @@ -417,7 +419,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { } } - private void checkContentTypeJson(final Message message) { + private static void checkContentTypeJson(final Message message) { final MessageProperties messageProperties = message.getMessageProperties(); if (messageProperties.getContentType() != null && messageProperties.getContentType().contains("json")) { return; diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java index 76870ac93..3c5b78e01 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java @@ -38,16 +38,6 @@ public class BaseAmqpService { this.rabbitTemplate = rabbitTemplate; } - /** - * Clean message properties before sending a message. - * - * @param message - * the message to cleaned up - */ - protected void cleanMessageHeaderProperties(final Message message) { - message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME); - } - /** * Is needed to convert a incoming message to is originally object type. * @@ -67,7 +57,7 @@ public class BaseAmqpService { return (T) rabbitTemplate.getMessageConverter().fromMessage(message); } - private boolean isMessageBodyEmpty(final Message message) { + private static boolean isMessageBodyEmpty(final Message message) { return message == null || message.getBody() == null || message.getBody().length == 0; } From 79d604ca0b795ee967f3e0491f00af704fd7abb7 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Thu, 19 May 2016 17:28:45 +0200 Subject: [PATCH 002/118] Some clean code refactorings Signed-off-by: SirWayne --- .../AmqpControllerAuthenticationTest.java | 12 +-- .../amqp/AmqpMessageHandlerServiceTest.java | 6 +- .../dmf/json/model/TenantSecurityToken.java | 4 +- ...actHttpControllerAuthenticationFilter.java | 27 ++++--- ...enantAwareAuthenticationDetailsSource.java | 15 +--- .../HttpDownloadAuthenticationFilter.java | 4 +- .../eventbus/CacheFieldEntityListener.java | 81 +++++++++---------- .../org/eclipse/hawkbit/ui/HawkbitUI.java | 30 ++++--- .../ui/artifacts/UploadArtifactView.java | 22 ++--- .../artifacts/details/ArtifactBeanQuery.java | 6 +- 10 files changed, 102 insertions(+), 105 deletions(-) diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java index 881260579..898647bc6 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java @@ -114,7 +114,7 @@ public class AmqpControllerAuthenticationTest { @Description("Tests authentication manager without principal") public void testAuthenticationeBadCredantialsWithoutPricipal() { final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID, - FileResource.sha1("12345")); + FileResource.createFileResourceBySha1("12345")); try { authenticationManager.doAuthenticate(securityToken); fail("BadCredentialsException was excepeted since principal was missing"); @@ -128,7 +128,7 @@ public class AmqpControllerAuthenticationTest { @Description("Tests authentication manager without wrong credential") public void testAuthenticationBadCredantialsWithWrongCredential() { final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID, - FileResource.sha1("12345")); + FileResource.createFileResourceBySha1("12345")); when(tenantConfigurationManagement.getConfigurationValue( eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) .thenReturn(CONFIG_VALUE_TRUE); @@ -146,7 +146,7 @@ public class AmqpControllerAuthenticationTest { @Description("Tests authentication successfull") public void testSuccessfullAuthentication() { final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID, - FileResource.sha1("12345")); + FileResource.createFileResourceBySha1("12345")); when(tenantConfigurationManagement.getConfigurationValue( eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) .thenReturn(CONFIG_VALUE_TRUE); @@ -161,7 +161,7 @@ public class AmqpControllerAuthenticationTest { final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID, - FileResource.sha1("12345")); + FileResource.createFileResourceBySha1("12345")); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken, messageProperties); @@ -180,7 +180,7 @@ public class AmqpControllerAuthenticationTest { public void testAuthenticationMessageBadCredantialsWithWrongCredential() { final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID, - FileResource.sha1("12345")); + FileResource.createFileResourceBySha1("12345")); when(tenantConfigurationManagement.getConfigurationValue( eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) .thenReturn(CONFIG_VALUE_TRUE); @@ -203,7 +203,7 @@ public class AmqpControllerAuthenticationTest { public void testSuccessfullMessageAuthentication() { final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID, - FileResource.sha1("12345")); + FileResource.createFileResourceBySha1("12345")); when(tenantConfigurationManagement.getConfigurationValue( eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class))) .thenReturn(CONFIG_VALUE_TRUE); diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index 3051e4e22..bfa47455b 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -264,7 +264,7 @@ public class AmqpMessageHandlerServiceTest { @Description("Tests that an download request is denied for an artifact which does not exists") public void authenticationRequestDeniedForArtifactWhichDoesNotExists() { final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); - final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345")); + final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.createFileResourceBySha1("12345")); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken, messageProperties); @@ -283,7 +283,7 @@ public class AmqpMessageHandlerServiceTest { @Description("Tests that an download request is denied for an artifact which is not assigned to the requested target") public void authenticationRequestDeniedForArtifactWhichIsNotAssignedToTarget() { final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); - final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345")); + final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.createFileResourceBySha1("12345")); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken, messageProperties); @@ -307,7 +307,7 @@ public class AmqpMessageHandlerServiceTest { @Description("Tests that an download request is allowed for an artifact which exists and assigned to the requested target") public void authenticationRequestAllowedForArtifactWhichExistsAndAssignedToTarget() throws MalformedURLException { final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION); - final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345")); + final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.createFileResourceBySha1("12345")); final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken, messageProperties); diff --git a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecurityToken.java b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecurityToken.java index e4f41bc46..19293f3eb 100644 --- a/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecurityToken.java +++ b/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/TenantSecurityToken.java @@ -135,7 +135,7 @@ public class TenantSecurityToken { * the SHA1 key of the file to obtain * @return the {@link FileResource} with SHA1 key set */ - public static FileResource sha1(final String sha1) { + public static FileResource createFileResourceBySha1(final String sha1) { final FileResource resource = new FileResource(); resource.sha1 = sha1; return resource; @@ -148,7 +148,7 @@ public class TenantSecurityToken { * the filename of the file to obtain * @return the {@link FileResource} with filename set */ - public static FileResource filename(final String filename) { + public static FileResource createFileResourceByFilename(final String filename) { final FileResource resource = new FileResource(); resource.filename = filename; return resource; diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java index 0e67489ea..0a4ad0b72 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/AbstractHttpControllerAuthenticationFilter.java @@ -47,7 +47,7 @@ import com.google.common.collect.UnmodifiableIterator; */ public abstract class AbstractHttpControllerAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter { - private static final Logger LOGGER = LoggerFactory.getLogger(AbstractHttpControllerAuthenticationFilter.class); + private static final Logger LOG = LoggerFactory.getLogger(AbstractHttpControllerAuthenticationFilter.class); private static final String TENANT_PLACE_HOLDER = "tenant"; private static final String CONTROLLER_ID_PLACE_HOLDER = "controllerId"; @@ -73,10 +73,12 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac /** * Constructor for sub-classes. * - * @param systemManagement - * the system management service + * @param tenantConfigurationManagement + * the tenant configuration service * @param tenantAware * the tenant aware service + * @param systemSecurityContext + * the system secruity context */ public AbstractHttpControllerAuthenticationFilter(final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware, final SystemSecurityContext systemSecurityContext) { @@ -136,28 +138,28 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac final String requestURI = request.getRequestURI(); if (pathExtractor.match(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI)) { - LOGGER.debug("retrieving principal from URI request {}", requestURI); + LOG.debug("retrieving principal from URI request {}", requestURI); final Map extractUriTemplateVariables = pathExtractor .extractUriTemplateVariables(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI); final String controllerId = extractUriTemplateVariables.get(CONTROLLER_ID_PLACE_HOLDER); final String tenant = extractUriTemplateVariables.get(TENANT_PLACE_HOLDER); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Parsed tenant {} and controllerId {} from path request {}", tenant, controllerId, + if (LOG.isTraceEnabled()) { + LOG.trace("Parsed tenant {} and controllerId {} from path request {}", tenant, controllerId, requestURI); } return createTenantSecruityTokenVariables(request, tenant, controllerId); } else if (pathExtractor.match(request.getContextPath() + CONTROLLER_DL_REQUEST_ANT_PATTERN, requestURI)) { - LOGGER.debug("retrieving path variables from URI request {}", requestURI); + LOG.debug("retrieving path variables from URI request {}", requestURI); final Map extractUriTemplateVariables = pathExtractor.extractUriTemplateVariables( request.getContextPath() + CONTROLLER_DL_REQUEST_ANT_PATTERN, requestURI); final String tenant = extractUriTemplateVariables.get(TENANT_PLACE_HOLDER); - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("Parsed tenant {} from path request {}", tenant, requestURI); + if (LOG.isTraceEnabled()) { + LOG.trace("Parsed tenant {} from path request {}", tenant, requestURI); } return createTenantSecruityTokenVariables(request, tenant, "anonymous"); } else { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace("request {} does not match the path pattern {}, request gets ignored", requestURI, + if (LOG.isTraceEnabled()) { + LOG.trace("request {} does not match the path pattern {}, request gets ignored", requestURI, CONTROLLER_REQUEST_ANT_PATTERN); } return null; @@ -166,7 +168,8 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac private TenantSecurityToken createTenantSecruityTokenVariables(final HttpServletRequest request, final String tenant, final String controllerId) { - final TenantSecurityToken secruityToken = new TenantSecurityToken(tenant, controllerId, FileResource.sha1("")); + final TenantSecurityToken secruityToken = new TenantSecurityToken(tenant, controllerId, + FileResource.createFileResourceBySha1("")); final UnmodifiableIterator forEnumeration = Iterators.forEnumeration(request.getHeaderNames()); forEnumeration.forEachRemaining(header -> secruityToken.getHeaders().put(header, request.getHeader(header))); return secruityToken; diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/ControllerTenantAwareAuthenticationDetailsSource.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/ControllerTenantAwareAuthenticationDetailsSource.java index 80d50112f..ae514c07b 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/ControllerTenantAwareAuthenticationDetailsSource.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/ControllerTenantAwareAuthenticationDetailsSource.java @@ -22,15 +22,11 @@ import org.springframework.util.AntPathMatcher; * An {@link AuthenticationDetailsSource} implementation which retrieves the * tenant from a request pattern {@link #TENANT_AWARE_CONTROLLER_PATTERN} and * stores the retrieved tenant in the {@link TenantAwareAuthenticationDetails}. - * * */ public class ControllerTenantAwareAuthenticationDetailsSource implements AuthenticationDetailsSource { - /** - * - */ private static final String TENANT_AWARE_CONTROLLER_PATTERN = "/{tenant}/controller/**"; private static final Logger LOGGER = LoggerFactory .getLogger(ControllerTenantAwareAuthenticationDetailsSource.class); @@ -38,19 +34,12 @@ public class ControllerTenantAwareAuthenticationDetailsSource private final AntPathMatcher pathExtractor; /** - * - */ + * Constructor. + */ public ControllerTenantAwareAuthenticationDetailsSource() { pathExtractor = new AntPathMatcher(); } - /* - * (non-Javadoc) - * - * @see - * org.springframework.security.authentication.AuthenticationDetailsSource# - * buildDetails(java. lang.Object) - */ @Override public TenantAwareAuthenticationDetails buildDetails(final HttpServletRequest request) { return new TenantAwareWebAuthenticationDetails(getTenantFromRequestUri(request), request.getRemoteAddr(), true); diff --git a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpDownloadAuthenticationFilter.java b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpDownloadAuthenticationFilter.java index 4a4bf2f5c..4185c9b83 100644 --- a/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpDownloadAuthenticationFilter.java +++ b/hawkbit-http-security/src/main/java/org/eclipse/hawkbit/security/HttpDownloadAuthenticationFilter.java @@ -28,7 +28,7 @@ import org.springframework.security.web.authentication.preauth.AbstractPreAuthen public class HttpDownloadAuthenticationFilter extends AbstractPreAuthenticatedProcessingFilter { public static final String REQUEST_ID_REGEX_PATTERN = ".*\\/downloadId\\/.*"; - private static final Logger LOGGER = LoggerFactory.getLogger(HttpDownloadAuthenticationFilter.class); + private static final Logger LOG = LoggerFactory.getLogger(HttpDownloadAuthenticationFilter.class); private final Pattern pattern; private final Cache cache; @@ -50,7 +50,7 @@ public class HttpDownloadAuthenticationFilter extends AbstractPreAuthenticatedPr if (!matcher.matches()) { return null; } - LOGGER.debug("retrieving id from URI request {}", requestURI); + LOG.debug("retrieving id from URI request {}", requestURI); final String[] groups = requestURI.split("\\/"); final String id = groups[groups.length - 1]; if (id == null) { diff --git a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/CacheFieldEntityListener.java b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/CacheFieldEntityListener.java index 7275cb4ec..902462028 100644 --- a/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/CacheFieldEntityListener.java +++ b/hawkbit-repository/src/main/java/org/eclipse/hawkbit/eventbus/CacheFieldEntityListener.java @@ -32,9 +32,6 @@ import org.springframework.hateoas.Identifiable; * by this entity listener cause the cache keys are calculated with the ID of * the entity. * - * - * - * */ public class CacheFieldEntityListener { @@ -48,24 +45,21 @@ public class CacheFieldEntityListener { */ @PostLoad public void postLoad(final Object target) { - if (target instanceof Identifiable) { - final CacheManager cacheManager = CacheManagerHolder.getInstance().getCacheManager(); - @SuppressWarnings("rawtypes") - final String id = ((Identifiable) target).getId().toString(); - final Class type = target.getClass(); - findCacheFields(type, id, new CacheFieldCallback() { - @Override - public void fromCache(final Field field, final String cacheKey, final Serializable id) - throws IllegalAccessException { - final Cache cache = cacheManager.getCache(type.getName()); - final ValueWrapper valueWrapper = cache - .get(CacheKeys.entitySpecificCacheKey(id.toString(), cacheKey)); - if (valueWrapper != null && valueWrapper.get() != null) { - FieldUtils.writeField(field, target, valueWrapper.get(), true); - } - } - }); + if (!isIdentifiable(target)) { + return; } + + final CacheFieldCallback cacheFieldCallback = (type, field, cacheKey, entityId) -> { + final CacheManager cacheManager = CacheManagerHolder.getInstance().getCacheManager(); + final Cache cache = cacheManager.getCache(type.getName()); + final ValueWrapper valueWrapper = cache + .get(CacheKeys.entitySpecificCacheKey(entityId.toString(), cacheKey)); + if (valueWrapper != null && valueWrapper.get() != null) { + FieldUtils.writeField(field, target, valueWrapper.get(), true); + } + }; + + findCacheFields((Identifiable) target, cacheFieldCallback); } /** @@ -77,30 +71,32 @@ public class CacheFieldEntityListener { */ @PostRemove public void postDelete(final Object target) { - if (target instanceof Identifiable) { - final CacheManager cacheManager = CacheManagerHolder.getInstance().getCacheManager(); - @SuppressWarnings("rawtypes") - final String id = ((Identifiable) target).getId().toString(); - final Class type = target.getClass(); - findCacheFields(type, id, new CacheFieldCallback() { - @Override - public void fromCache(final Field field, final String cacheKey, final Serializable id) - throws IllegalAccessException { - final Cache cache = cacheManager.getCache(type.getName()); - cache.evict(CacheKeys.entitySpecificCacheKey(id.toString(), cacheKey)); - } - }); + if (!isIdentifiable(target)) { + return; } + final CacheFieldCallback cacheFieldCallback = (type, field, cacheKey, entityId) -> { + final CacheManager cacheManager = CacheManagerHolder.getInstance().getCacheManager(); + final Cache cache = cacheManager.getCache(type.getName()); + cache.evict(CacheKeys.entitySpecificCacheKey(entityId.toString(), cacheKey)); + }; + + findCacheFields((Identifiable) target, cacheFieldCallback); } - private void findCacheFields(final Class type, final Serializable id, - final CacheFieldCallback callback) { + private boolean isIdentifiable(final Object target) { + return target instanceof Identifiable; + } + + private void findCacheFields(final Identifiable target, final CacheFieldCallback callback) { + final String id = target.getId().toString(); + final Class type = target.getClass(); + final Field[] declaredFields = type.getDeclaredFields(); for (final Field field : declaredFields) { if (field.getAnnotation(CacheField.class) != null) { try { final CacheField annotation = field.getAnnotation(CacheField.class); - callback.fromCache(field, annotation.key(), id); + callback.fromCache(type, field, annotation.key(), id); } catch (final IllegalAccessException e) { LOGGER.error("cannot access the field {} for the entity {}, ignoring the cacheable field", field, type, e); @@ -109,23 +105,26 @@ public class CacheFieldEntityListener { } } + @FunctionalInterface private interface CacheFieldCallback { /** - * callback methods which is called by the - * {@link CacheFieldEntityListener#findCacheFields(Class, Serializable, CacheFieldCallback)} - * in case a field is annotated with {@link CacheField}. + * callback methods which is called when a field is annotated with + * {@link CacheField}. * + * @param type + * the type of the target. * @param field * the field which is annotaed with {@link CacheField} * @param cacheKey * the configured cache key in the annotation * {@link CacheField#key()} - * @param id + * @param entityId * the ID of the entity * @throws IllegalAccessException * in case the field cannot be accessed */ - void fromCache(final Field field, final String cacheKey, Serializable id) throws IllegalAccessException; + void fromCache(Class type, final Field field, final String cacheKey, Serializable entityId) + throws IllegalAccessException; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java index f4c26a960..de750173e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java @@ -50,13 +50,11 @@ import com.vaadin.ui.themes.ValoTheme; /** * Vaadin management UI. * - * - * - * */ -@SuppressWarnings("serial") @Title("hawkBit Update Server") public class HawkbitUI extends DefaultHawkbitUI implements DetachListener { + private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(HawkbitUI.class); private static final String EMPTY_VIEW = ""; @@ -139,7 +137,7 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener { contentVerticalLayout.addComponent(content); content.setStyleName("view-content"); content.setSizeFull(); - rootLayout.setExpandRatio(contentVerticalLayout, 1.0f); + rootLayout.setExpandRatio(contentVerticalLayout, 1.0F); contentVerticalLayout.setStyleName("main-content"); contentVerticalLayout.setExpandRatio(content, 1.0F); setContent(rootLayout); @@ -154,6 +152,8 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener { } final Navigator navigator = new Navigator(this, content); navigator.addViewChangeListener(new ViewChangeListener() { + private static final long serialVersionUID = 1L; + @Override public boolean beforeViewChange(final ViewChangeEvent event) { return true; @@ -197,7 +197,7 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener { * as set * @return String as preferred locale */ - private String getLocaleId(final Set availableLocalesInApp) { + private static String getLocaleId(final Set availableLocalesInApp) { final String[] localeChain = getLocaleChain(); String spLocale = SPUIDefinitions.DEFAULT_LOCALE; if (null != localeChain) { @@ -217,16 +217,18 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener { * * @return String as locales */ - private String[] getLocaleChain() { + private static String[] getLocaleChain() { String[] localeChain = null; // Fetch all cookies from the request final Cookie[] cookies = VaadinService.getCurrentRequest().getCookies(); - if (cookies != null) { - for (final Cookie c : cookies) { - if (c.getName().equals(SPUIDefinitions.COOKIE_NAME) && !c.getValue().isEmpty()) { - localeChain = c.getValue().split("#"); - break; - } + if (cookies == null) { + return localeChain; + } + + for (final Cookie c : cookies) { + if (c.getName().equals(SPUIDefinitions.COOKIE_NAME) && !c.getValue().isEmpty()) { + localeChain = c.getValue().split("#"); + break; } } return localeChain; @@ -234,6 +236,8 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener { private class ManagementViewProvider implements ViewProvider { + private static final long serialVersionUID = 1L; + @Override public String getViewName(final String viewAndParameters) { return viewProvider.getViewName(getStartView(viewAndParameters)); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java index b07aa0276..ffbb3b7bd 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/UploadArtifactView.java @@ -158,7 +158,7 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW detailAndUploadLayout.setComponentAlignment(dadw, Alignment.MIDDLE_CENTER); } - detailAndUploadLayout.setExpandRatio(artifactDetailsLayout, 1.0f); + detailAndUploadLayout.setExpandRatio(artifactDetailsLayout, 1.0F); detailAndUploadLayout.setSizeFull(); detailAndUploadLayout.addStyleName("group"); detailAndUploadLayout.setSpacing(true); @@ -177,9 +177,9 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW mainLayout.addComponent(detailAndUploadLayout, 2, 0); mainLayout.addComponent(deleteActionsLayout, 1, 1); mainLayout.addComponent(uplaodButtonsLayout, 2, 1); - mainLayout.setRowExpandRatio(0, 1.0f); - mainLayout.setColumnExpandRatio(1, 0.5f); - mainLayout.setColumnExpandRatio(2, 0.5f); + mainLayout.setRowExpandRatio(0, 1.0F); + mainLayout.setColumnExpandRatio(1, 0.5F); + mainLayout.setColumnExpandRatio(2, 0.5F); mainLayout.setComponentAlignment(deleteActionsLayout, Alignment.BOTTOM_CENTER); mainLayout.setComponentAlignment(uplaodButtonsLayout, Alignment.BOTTOM_CENTER); return mainLayout; @@ -201,8 +201,8 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW private void maximizeSwTable() { mainLayout.removeComponent(detailAndUploadLayout); removeOtherComponents(); - mainLayout.setColumnExpandRatio(1, 1f); - mainLayout.setColumnExpandRatio(2, 0f); + mainLayout.setColumnExpandRatio(1, 1F); + mainLayout.setColumnExpandRatio(2, 0F); } private void minimizeArtifactoryDetails() { @@ -219,15 +219,15 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW mainLayout.removeComponent(smTableLayout); detailAndUploadLayout.removeComponent(dadw); removeOtherComponents(); - mainLayout.setColumnExpandRatio(1, 0f); - mainLayout.setColumnExpandRatio(2, 1f); + mainLayout.setColumnExpandRatio(1, 0F); + mainLayout.setColumnExpandRatio(2, 1F); } private void addOtherComponents() { mainLayout.addComponent(deleteActionsLayout, 1, 1); mainLayout.addComponent(uplaodButtonsLayout, 2, 1); - mainLayout.setColumnExpandRatio(1, 0.5f); - mainLayout.setColumnExpandRatio(2, 0.5f); + mainLayout.setColumnExpandRatio(1, 0.5F); + mainLayout.setColumnExpandRatio(2, 0.5F); mainLayout.setComponentAlignment(deleteActionsLayout, Alignment.BOTTOM_CENTER); mainLayout.setComponentAlignment(uplaodButtonsLayout, Alignment.BOTTOM_CENTER); } @@ -240,6 +240,8 @@ public class UploadArtifactView extends VerticalLayout implements View, BrowserW private void hideDropHints() { UI.getCurrent().addClickListener(new ClickListener() { + private static final long serialVersionUID = 1L; + @Override public void click(final com.vaadin.event.MouseEvents.ClickEvent event) { eventBus.publish(this, DragEvent.HIDE_DROP_HINT); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java index 2fa3763fd..017bda863 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java @@ -36,9 +36,9 @@ import org.vaadin.addons.lazyquerycontainer.QueryDefinition; public class ArtifactBeanQuery extends AbstractBeanQuery { private static final long serialVersionUID = -333786310371208962L; private Sort sort = new Sort(Direction.DESC, "filename"); - private transient ArtifactManagement artifactManagement = null; - private transient Page firstPagetArtifacts = null; - private Long baseSwModuleId = null; + private transient ArtifactManagement artifactManagement; + private transient Page firstPagetArtifacts; + private Long baseSwModuleId; /** * Parametric Constructor. From 27ae06775881e7e8deaaa135ab2cd103dd3efe99 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Fri, 20 May 2016 08:41:47 +0200 Subject: [PATCH 003/118] Some clean code refactorings Signed-off-by: SirWayne --- .../hawkbit/api/DefaultProtocolProperties.java | 2 +- .../hawkbit/security/SystemSecurityContext.java | 14 +++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/DefaultProtocolProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/DefaultProtocolProperties.java index 9d053104c..07eac8db1 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/DefaultProtocolProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/DefaultProtocolProperties.java @@ -76,4 +76,4 @@ public class DefaultProtocolProperties implements ProtocolProperties { public void setPort(final String port) { this.port = port; } -} \ No newline at end of file +} diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java index f849eb541..abe921473 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java @@ -29,12 +29,12 @@ import org.springframework.stereotype.Service; import com.google.common.base.Throwables; /** - * + * A Service which provide to run system code. */ @Service public class SystemSecurityContext { - private static final Logger logger = LoggerFactory.getLogger(SystemSecurityContext.class); + private static final Logger LOGGER = LoggerFactory.getLogger(SystemSecurityContext.class); private final TenantAware tenantAware; @@ -67,19 +67,20 @@ public class SystemSecurityContext { public T runAsSystem(final Callable callable) { final SecurityContext oldContext = SecurityContextHolder.getContext(); try { - logger.debug("entering system code execution"); + LOGGER.debug("entering system code execution"); return tenantAware.runAsTenant(tenantAware.getCurrentTenant(), () -> { try { setSystemContext(); return callable.call(); - } catch (final Exception e) { + // The callable API throws a Exception ant to specific + } catch (@SuppressWarnings("squid:S2221") final Exception e) { throw Throwables.propagate(e); } }); } finally { SecurityContextHolder.setContext(oldContext); - logger.debug("leaving system code execution"); + LOGGER.debug("leaving system code execution"); } } @@ -97,6 +98,9 @@ public class SystemSecurityContext { SecurityContextHolder.setContext(securityContextImpl); } + /** + * Authentication with the system role. + */ public static class SystemCodeAuthentication implements Authentication { private static final long serialVersionUID = 1L; From d2826a21c20f5512031e0acb9ca36a87556e73a4 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Fri, 20 May 2016 08:52:29 +0200 Subject: [PATCH 004/118] Some clean code refactorings Signed-off-by: SirWayne --- .../org/eclipse/hawkbit/security/SystemSecurityContext.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java index abe921473..e0f3ca8c7 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java @@ -72,7 +72,7 @@ public class SystemSecurityContext { try { setSystemContext(); return callable.call(); - // The callable API throws a Exception ant to specific + // The callable API throws a Exception and not a specific } catch (@SuppressWarnings("squid:S2221") final Exception e) { throw Throwables.propagate(e); } From 4f7bb98587972182977d81b894e80aa76edcb9b5 Mon Sep 17 00:00:00 2001 From: Asharani Date: Tue, 28 Jun 2016 12:07:26 +0530 Subject: [PATCH 005/118] Enable push for update target, create/update/delete ds Renamed constant MAX_TARGET_TABLE_ENTRIES Signed-off-by: Asharani --- .../eventbus/event/TargetDeletedEvent.java | 39 ---- .../event/DistributionCreatedEvent.java | 28 +++ .../event/DistributionDeletedEvent.java | 37 ++++ .../event/DistributionSetUpdateEvent.java | 30 +++ .../eventbus/event/TargetDeletedEvent.java | 41 ++++ .../eventbus/event/TargetUpdatedEvent.java | 25 +++ .../jpa/JpaDistributionSetManagement.java | 56 ++++-- .../repository/jpa/JpaTargetManagement.java | 22 +- .../eventbus/EntityChangeEventListener.java | 154 -------------- .../model/AbstractDescriptorEventVisitor.java | 19 ++ .../AbstractDescriptorEventVisitorImpl.java | 189 ++++++++++++++++++ .../jpa/model/AbstractJpaBaseEntity.java | 7 +- .../repository/jpa/model/AcceptVisitor.java | 18 ++ .../jpa/model/DescriptorEventDetails.java | 42 ++++ .../model/EntityPropertyChangeListener.java | 78 ++------ .../hawkbit/ui/HawkbitEventProvider.java | 14 +- .../dstable/DistributionSetTable.java | 108 +++++++++- .../dstable/ManageDistBeanQuery.java | 2 +- .../CustomTargetBeanQuery.java | 6 +- .../footer/TargetFilterCountMessageLabel.java | 6 +- .../DistributionAddUpdateWindowLayout.java | 17 +- .../dstable/DistributionBeanQuery.java | 2 +- .../management/dstable/DistributionTable.java | 97 +++++++++ .../management/footer/CountMessageLabel.java | 6 +- .../ManangementConfirmationWindowLayout.java | 1 - .../targettable/TargetBeanQuery.java | 6 +- .../management/targettable/TargetTable.java | 48 ++++- .../RolloutGroupTargetsBeanQuery.java | 6 +- .../RolloutGroupTargetsCountLabelMessage.java | 6 +- .../hawkbit/ui/utils/SPUIDefinitions.java | 15 +- 30 files changed, 788 insertions(+), 337 deletions(-) delete mode 100644 hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionCreatedEvent.java create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionSetUpdateEvent.java create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetDeletedEvent.java create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java delete mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/eventbus/EntityChangeEventListener.java create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java deleted file mode 100644 index e6fcac135..000000000 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java +++ /dev/null @@ -1,39 +0,0 @@ -/** - * 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.eventbus.event; - -/** - * - * - * - */ -public class TargetDeletedEvent extends AbstractDistributedEvent { - - private static final long serialVersionUID = 1L; - private final long targetId; - - /** - * @param tenant - * the tenant for this event - * @param targetId - * the ID of the target which has been deleted - */ - public TargetDeletedEvent(final String tenant, final long targetId) { - super(-1, tenant); - this.targetId = targetId; - } - - /** - * @return the targetId - */ - public long getTargetId() { - return targetId; - } - -} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionCreatedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionCreatedEvent.java new file mode 100644 index 000000000..20515521d --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionCreatedEvent.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.eventbus.event; + +import org.eclipse.hawkbit.repository.model.DistributionSet; + +/** + * Defines the {@link AbstractBaseEntityEvent} of creating a new {@link DistributionSet}. + * + */ +public class DistributionCreatedEvent extends AbstractBaseEntityEvent { + + private static final long serialVersionUID = 1L; + + /** + * @param distributionSet + * the distributionSet which has been created + */ + public DistributionCreatedEvent(final DistributionSet distributionSet) { + super(distributionSet); + } +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java new file mode 100644 index 000000000..1edfb47ac --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java @@ -0,0 +1,37 @@ +/** + * 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.eventbus.event; + +import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent; +import org.eclipse.hawkbit.repository.model.DistributionSet; + + +/** + * * Defines the {@link AbstractDistributedEvent} for deletion of {@link DistributionSet}. + + * + */ +public class DistributionDeletedEvent extends AbstractDistributedEvent{ + private static final long serialVersionUID = -3308850381757843098L; + final Long[] distributionSetIDs; + /** + * @param tenant + * the tenant for this event + * @param distributionSetId + * the ID of the target which has been deleted + */ + public DistributionDeletedEvent(final String tenant, final Long...distributionIds) { + super(-1, tenant); + this.distributionSetIDs = distributionIds; + } + + public Long[] getDistributionSetIDs() { + return distributionSetIDs; + } +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionSetUpdateEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionSetUpdateEvent.java new file mode 100644 index 000000000..8d91d27f7 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionSetUpdateEvent.java @@ -0,0 +1,30 @@ +/** + * 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.eventbus.event; + +import org.eclipse.hawkbit.repository.model.DistributionSet; + +/** + * Defines the {@link AbstractBaseEntityEvent} for update a {@link DistributionSet}. + * + */ +public class DistributionSetUpdateEvent extends AbstractBaseEntityEvent { + + private static final long serialVersionUID = 1L; + + /** + * Constructor. + * + * @param tag + * the tag which is updated + */ + public DistributionSetUpdateEvent(final DistributionSet ds) { + super(ds); + } +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetDeletedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetDeletedEvent.java new file mode 100644 index 000000000..637a0dcc5 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetDeletedEvent.java @@ -0,0 +1,41 @@ +/** + * 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.eventbus.event; + +import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent; +import org.eclipse.hawkbit.repository.model.Target; + +/** + * + * Defines the {@link AbstractBaseEntityEvent} of deleting a {@link Target}. + */ +public class TargetDeletedEvent extends AbstractDistributedEvent { + + private static final long serialVersionUID = 1L; + private final long targetId; + + /** + * @param tenant + * the tenant for this event + * @param targetId + * the ID of the target which has been deleted + */ + public TargetDeletedEvent(final String tenant, final long targetId) { + super(-1, tenant); + this.targetId = targetId; + } + + /** + * @return the targetId + */ + public long getTargetId() { + return targetId; + } + +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java new file mode 100644 index 000000000..a30d96c69 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java @@ -0,0 +1,25 @@ +/** + * 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.eventbus.event; + +import org.eclipse.hawkbit.repository.model.Target; + +/** + * Defines the {@link AbstractBaseEntityEvent} of updating a {@link Target}. + * + */ +public class TargetUpdatedEvent extends AbstractBaseEntityEvent { + + private static final long serialVersionUID = 5665118668865832477L; + + public TargetUpdatedEvent(Target baseEntity) { + super(baseEntity); + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index 0e97d6ff5..b94677fb9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -28,6 +28,7 @@ import org.eclipse.hawkbit.repository.DistributionSetMetadataFields; import org.eclipse.hawkbit.repository.DistributionSetTypeFields; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TagManagement; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityLockedException; @@ -54,6 +55,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -102,6 +104,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; + @Autowired + private TenantAware tenantAware; + @Override public DistributionSet findDistributionSetByIdWithDetails(final Long distid) { return distributionSetRepository.findOne(DistributionSetSpecification.byId(distid)); @@ -168,32 +173,39 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteDistributionSet(final Long... distributionSetIDs) { - final List toHardDelete = new ArrayList<>(); + public void deleteDistributionSet(final Long... distributionSetIDs) { + final List toHardDelete = new ArrayList<>(); - final List assigned = distributionSetRepository - .findAssignedToTargetDistributionSetsById(distributionSetIDs); - assigned.addAll(distributionSetRepository.findAssignedToRolloutDistributionSetsById(distributionSetIDs)); + final List assigned = distributionSetRepository + .findAssignedToTargetDistributionSetsById(distributionSetIDs); + assigned.addAll(distributionSetRepository + .findAssignedToRolloutDistributionSetsById(distributionSetIDs)); - // soft delete assigned - if (!assigned.isEmpty()) { - distributionSetRepository.deleteDistributionSet(assigned.toArray(new Long[assigned.size()])); - } + // soft delete assigned + if (!assigned.isEmpty()) { + distributionSetRepository.deleteDistributionSet(assigned + .toArray(new Long[assigned.size()])); + } - // mark the rest as hard delete - for (final Long setId : distributionSetIDs) { - if (!assigned.contains(setId)) { - toHardDelete.add(setId); - } - } + // mark the rest as hard delete + for (final Long setId : distributionSetIDs) { + if (!assigned.contains(setId)) { + toHardDelete.add(setId); + } + } - // hard delete the rest if exixts - if (!toHardDelete.isEmpty()) { - // don't give the delete statement an empty list, JPA/Oracle cannot - // handle the empty list - distributionSetRepository.deleteByIdIn(toHardDelete); - } - } + // hard delete the rest if exixts + if (!toHardDelete.isEmpty()) { + // don't give the delete statement an empty list, JPA/Oracle cannot + // handle the empty list + distributionSetRepository.deleteByIdIn(toHardDelete); + } + + afterCommit.afterCommit(() -> eventBus + .post(new DistributionDeletedEvent(tenantAware + .getCurrentTenant(), distributionSetIDs))); + + } @Override @Modifying diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 1cd2ffc3c..30a5dd5d9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -29,6 +29,7 @@ import javax.persistence.criteria.Root; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.jpa.configuration.Constants; @@ -48,6 +49,7 @@ import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.domain.Page; @@ -96,6 +98,10 @@ public class JpaTargetManagement implements TargetManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; + + + @Autowired + private TenantAware tenantAware; @Override public Target findTargetByControllerID(final String controllerId) { @@ -202,12 +208,14 @@ public class JpaTargetManagement implements TargetManagement { // hibernate session. final List targetsForCurrentTenant = targetRepository.findAll(Lists.newArrayList(targetIDs)).stream() .map(Target::getId).collect(Collectors.toList()); - if (!targetsForCurrentTenant.isEmpty()) { - targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant); - targetRepository.deleteByIdIn(targetsForCurrentTenant); - } + if (!targetsForCurrentTenant.isEmpty()) { + targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant); + targetRepository.deleteByIdIn(targetsForCurrentTenant); + targetsForCurrentTenant.forEach(targetId -> notifyTargetDeleted( + tenantAware.getCurrentTenant(), targetId)); + } } - + @Override public Page findTargetByAssignedDistributionSet(final Long distributionSetID, final Pageable pageReq) { return targetRepository.findByAssignedDistributionSetId(pageReq, distributionSetID); @@ -651,5 +659,9 @@ public class JpaTargetManagement implements TargetManagement { } return resultList; } + + private void notifyTargetDeleted(final String tenant, final Long targetId) { + afterCommit.afterCommit(() -> eventBus.post(new TargetDeletedEvent(tenant, targetId))); + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/eventbus/EntityChangeEventListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/eventbus/EntityChangeEventListener.java deleted file mode 100644 index 5f41063d2..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/eventbus/EntityChangeEventListener.java +++ /dev/null @@ -1,154 +0,0 @@ -/** - * 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.jpa.eventbus; - -import java.util.Collection; - -import javax.persistence.EntityManager; - -import org.aspectj.lang.ProceedingJoinPoint; -import org.aspectj.lang.annotation.Around; -import org.aspectj.lang.annotation.Aspect; -import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; -import org.eclipse.hawkbit.repository.jpa.TargetRepository; -import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; -import org.eclipse.hawkbit.repository.jpa.model.JpaTargetInfo; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; -import org.eclipse.hawkbit.tenancy.TenantAware; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -import com.google.common.eventbus.EventBus; - -/** - * An aspect implementation which wraps the necessary repository services for - * saving {@link TenantAwareBaseEntity}s to publish create or update events. - * - * - * - * - */ -@Service -@Aspect -public class EntityChangeEventListener { - - @Autowired - private EventBus eventBus; - - @Autowired - private TenantAware tenantAware; - - @Autowired - private EntityManager entityManager; - - @Autowired - private AfterTransactionCommitExecutor afterCommit; - - /** - * In case the a {@link Target} is created a corresponding - * {@link TargetInfo} is created as well. We need the {@link TargetInfo} - * information in the target created event. So we are listening to the - * {@link TargetInfo} creation to indicate if an Target has been created. - * - * @param joinpoint - * the aspect join point - * @return the object of the {@link ProceedingJoinPoint#proceed()} - * @throws Throwable - * in case exception happens in the - * {@link ProceedingJoinPoint#proceed()} - */ - @Around("execution(* org.eclipse.hawkbit.repository.jpa.TargetInfoRepository.save(..))") - // Exception squid:S00112 - Is aspectJ proxy - @SuppressWarnings({ "squid:S00112" }) - public Object targetCreated(final ProceedingJoinPoint joinpoint) throws Throwable { - final boolean isNew = isTargetInfoNew(joinpoint.getArgs()[0]); - final Object result = joinpoint.proceed(); - if (result instanceof TargetInfo) { - if (isNew) { - notifyTargetCreated(entityManager.merge(entityManager.merge(((TargetInfo) result).getTarget()))); - } else { - notifyTargetInfoChanged((TargetInfo) result); - } - } - return result; - } - - /** - * Proxy method around the delete method of the {@link TargetRepository} to - * notify the {@link TargetDeletedEvent} in case targets has been deleted. - * - * @param joinpoint - * the aspect join point - * @return the object of the {@link ProceedingJoinPoint#proceed()} - * @throws Throwable - * in case exception happens in the - * {@link ProceedingJoinPoint#proceed()} - */ - @Around("execution(* org.eclipse.hawkbit.repository.jpa.TargetRepository.deleteByIdIn(..))") - // Exception squid:S00112 - Is aspectJ proxy - @SuppressWarnings({ "squid:S00112" }) - public Object targetDeletedById(final ProceedingJoinPoint joinpoint) throws Throwable { - final String currentTenant = tenantAware.getCurrentTenant(); - final Object result = joinpoint.proceed(); - final Collection targetIds = (Collection) joinpoint.getArgs()[0]; - targetIds.forEach(targetId -> notifyTargetDeleted(currentTenant, targetId)); - return result; - } - - /** - * Proxy method around the delete method of the {@link TargetRepository} to - * notify the {@link TargetDeletedEvent} in case targets has been deleted. - * - * @param joinpoint - * the aspect join point - * @return the object of the {@link ProceedingJoinPoint#proceed()} - * @throws Throwable - * in case exception happens in the - * {@link ProceedingJoinPoint#proceed()} - */ - @Around("execution(* org.eclipse.hawkbit.repository.jpa.TargetRepository.delete(..))") - // Exception squid:S00112 - Is aspectJ proxy - @SuppressWarnings({ "squid:S00112", "unchecked" }) - public Object targetDeleted(final ProceedingJoinPoint joinpoint) throws Throwable { - final String currentTenant = tenantAware.getCurrentTenant(); - final Object result = joinpoint.proceed(); - final Object param = joinpoint.getArgs()[0]; - // delete by id - if (param instanceof Long) { - notifyTargetDeleted(currentTenant, (Long) param); - } else if (param instanceof Target) { - notifyTargetDeleted(currentTenant, ((Target) param).getId()); - } else if (param instanceof Iterable) { - ((Iterable) param).forEach(target -> notifyTargetDeleted(currentTenant, target.getId())); - } - return result; - } - - private void notifyTargetCreated(final Target t) { - afterCommit.afterCommit(() -> eventBus.post(new TargetCreatedEvent(t))); - - } - - private void notifyTargetInfoChanged(final TargetInfo targetInfo) { - afterCommit.afterCommit(() -> eventBus.post(new TargetInfoUpdateEvent(targetInfo))); - } - - private void notifyTargetDeleted(final String tenant, final Long targetId) { - afterCommit.afterCommit(() -> eventBus.post(new TargetDeletedEvent(tenant, targetId))); - } - - private static boolean isTargetInfoNew(final Object targetInfo) { - return ((JpaTargetInfo) targetInfo).isNew(); - } - -} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java new file mode 100644 index 000000000..ce32b025f --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java @@ -0,0 +1,19 @@ +/** + * 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.jpa.model; + +/** + * + * Interface defining the action to be performed after entity is + * created/updated. + * + */ +public interface AbstractDescriptorEventVisitor { + void publishEventPostAction(DescriptorEventDetails eventDetails); +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java new file mode 100644 index 000000000..8755f8051 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java @@ -0,0 +1,189 @@ +/** + * 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.jpa.model; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Map; +import java.util.stream.Collectors; + +import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; +import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; +import org.eclipse.hawkbit.repository.jpa.model.DescriptorEventDetails.ActionType; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.eclipse.persistence.internal.sessions.ObjectChangeSet; +import org.eclipse.persistence.queries.UpdateObjectQuery; +import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.eventbus.EventBus; + +/** + * Implementation of @link{AbstractDescriptorEventVisitor} .Publishes the + * appropriate event after any action on entity like create/update. + * + */ +public class AbstractDescriptorEventVisitorImpl implements + AbstractDescriptorEventVisitor { + + private static final String COMPLETE = "complete"; + private static final Logger LOG = LoggerFactory + .getLogger(AbstractDescriptorEventVisitorImpl.class); + + @Override + public void publishEventPostAction(final DescriptorEventDetails event) { + Method method = null; + DescriptorEvent descriptorEvent = event.getDescriptorEvent(); + ActionType actiontype = event.getActiontype(); + try { + method = getMethod(descriptorEvent, actiontype); + if (method != null) { + method.invoke(this, descriptorEvent.getObject(), + descriptorEvent); + } + } catch (NoSuchMethodException | SecurityException + | IllegalAccessException | IllegalArgumentException + | InvocationTargetException e) { + LOG.info( + "Exception when invoking approriate method to publis event {}", + e); + } + } + + private Method getMethod(DescriptorEvent descriptorEvent, + ActionType actiontype) throws NoSuchMethodException { + if (actiontype == ActionType.UPDATE) { + return this.getClass().getMethod("publishEventAfterUpdate", + descriptorEvent.getObject().getClass(), + DescriptorEvent.class); + } else if (actiontype == ActionType.CREATE) { + return this.getClass().getMethod("publishEventAfterCreate", + descriptorEvent.getObject().getClass(), + DescriptorEvent.class); + } + return null; + } + + public void publishEventAfterCreate(JpaAction action, DescriptorEvent event) { + if (action.getRollout() != null) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post(new ActionCreatedEvent(action))); + } + } + + public void publishEventAfterCreate(JpaTarget target, DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post(new TargetCreatedEvent(target))); + } + + public void publishEventAfterCreate(JpaDistributionSet ds, + DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post(new DistributionCreatedEvent(ds))); + + } + + public void publishEventAfterUpdate(JpaAction action, DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post( + new ActionPropertyChangeEvent(action, getChangeSet( + Action.class, event)))); + } + + public void publishEventAfterUpdate(JpaTarget target, DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post(new TargetUpdatedEvent(target))); + } + + public void publishEventAfterUpdate(JpaTargetInfo targetInfo, + DescriptorEvent event) { + getAfterTransactionCommmitExecutor() + .afterCommit( + () -> getEventBus().post( + new TargetInfoUpdateEvent(targetInfo))); + } + + public void publishEventAfterUpdate(JpaRollout entity, DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post( + new RolloutPropertyChangeEvent(entity, getChangeSet( + Rollout.class, event)))); + } + + public void publishEventAfterUpdate(JpaRolloutGroup entity, + DescriptorEvent event) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post( + new RolloutGroupPropertyChangeEvent(entity, + getChangeSet(RolloutGroup.class, event)))); + + } + + public void publishEventAfterUpdate(JpaDistributionSet entity, + DescriptorEvent event) { + Map.Values> changeSet = getChangeSet( + JpaDistributionSet.class, event); + if (changeSet.containsKey(COMPLETE) + && changeSet.get(COMPLETE).getOldValue().equals(false) + && changeSet.get(COMPLETE).getNewValue().equals(true)) { + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus().post( + new DistributionCreatedEvent(entity))); + } + + getAfterTransactionCommmitExecutor().afterCommit( + () -> getEventBus() + .post(new DistributionSetUpdateEvent(entity))); + + } + + private Map.Values> getChangeSet( + final Class clazz, final DescriptorEvent event) { + final T rolloutGroup = clazz.cast(event.getObject()); + final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()) + .getObjectChangeSet(); + return changeSet + .getChanges() + .stream() + .filter(record -> record instanceof DirectToFieldChangeRecord) + .map(record -> (DirectToFieldChangeRecord) record) + .collect( + Collectors.toMap( + record -> record.getAttribute(), + record -> new AbstractPropertyChangeEvent( + rolloutGroup, null).new Values(record + .getOldValue(), record.getNewValue()))); + } + + private AfterTransactionCommitExecutor getAfterTransactionCommmitExecutor() { + return AfterTransactionCommitExecutorHolder.getInstance() + .getAfterCommit(); + } + + private EventBus getEventBus() { + return EventBusHolder.getInstance().getEventBus(); + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index 257828c6f..2785676fb 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -32,7 +32,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @MappedSuperclass @Access(AccessType.FIELD) @EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class }) -public abstract class AbstractJpaBaseEntity implements BaseEntity { +public abstract class AbstractJpaBaseEntity implements BaseEntity,AcceptVisitor { private static final long serialVersionUID = 1L; @Id @@ -178,4 +178,9 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity { return true; } + + @Override + public void postActionOnEntity(AbstractDescriptorEventVisitor visitor, DescriptorEventDetails eventDetails){ + visitor.publishEventPostAction(eventDetails); + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java new file mode 100644 index 000000000..78d89219b --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java @@ -0,0 +1,18 @@ +/** + * 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.jpa.model; + +/** + * Interface to accept visitor @link{AbstractDescriptorEventVisitor}. + * + */ +public interface AcceptVisitor { + public void postActionOnEntity(AbstractDescriptorEventVisitor visitor, + DescriptorEventDetails eventDetails); +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java new file mode 100644 index 000000000..a13d0700c --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java @@ -0,0 +1,42 @@ +/** + * 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.jpa.model; + +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * + * Holds details of action(Create/Update) and @link{DescriptorEvent}. + * + */ +public class DescriptorEventDetails { + + enum ActionType { + CREATE, UPDATE; + } + + private DescriptorEvent descriptorEvent; + + private ActionType actiontype; + + public DescriptorEventDetails(ActionType actionType, + DescriptorEvent descriptorEvent) { + this.descriptorEvent = descriptorEvent; + this.actiontype = actionType; + } + + public DescriptorEvent getDescriptorEvent() { + return descriptorEvent; + } + + public ActionType getActiontype() { + return actiontype; + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java index 2dd0fdb40..bdb366edb 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java @@ -8,28 +8,9 @@ */ package org.eclipse.hawkbit.repository.jpa.model; -import java.util.Map; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; +import org.eclipse.hawkbit.repository.jpa.model.DescriptorEventDetails.ActionType; import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.descriptors.DescriptorEventAdapter; -import org.eclipse.persistence.internal.sessions.ObjectChangeSet; -import org.eclipse.persistence.queries.UpdateObjectQuery; -import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord; - -import com.google.common.eventbus.EventBus; /** * Listens to change in property values of an entity. @@ -37,50 +18,19 @@ import com.google.common.eventbus.EventBus; */ public class EntityPropertyChangeListener extends DescriptorEventAdapter { - @Override - public void postInsert(final DescriptorEvent event) { - if (event.getObject().getClass().equals(Action.class)) { - final Action action = (Action) event.getObject(); - if (action.getRollout() != null) { - final EventBus eventBus = getEventBus(); - final AfterTransactionCommitExecutor afterCommit = getAfterTransactionCommmitExecutor(); - afterCommit.afterCommit(() -> eventBus.post(new ActionCreatedEvent(action))); - } - } + @Override + public void postInsert(final DescriptorEvent event) { + AbstractDescriptorEventVisitor visitor = new AbstractDescriptorEventVisitorImpl(); + ((AbstractJpaBaseEntity) event.getObject()).postActionOnEntity(visitor, + new DescriptorEventDetails(ActionType.CREATE, event)); - } + } - @Override - public void postUpdate(final DescriptorEvent event) { - if (event.getObject().getClass().equals(JpaAction.class)) { - getAfterTransactionCommmitExecutor().afterCommit(() -> getEventBus().post( - new ActionPropertyChangeEvent((Action) event.getObject(), getChangeSet(Action.class, event)))); - } else if (event.getObject().getClass().equals(JpaRollout.class)) { - getAfterTransactionCommmitExecutor().afterCommit(() -> getEventBus().post( - new RolloutPropertyChangeEvent((Rollout) event.getObject(), getChangeSet(Rollout.class, event)))); - } else if (event.getObject().getClass().equals(JpaRolloutGroup.class)) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post(new RolloutGroupPropertyChangeEvent((RolloutGroup) event.getObject(), - getChangeSet(RolloutGroup.class, event)))); - } - } - - private Map.Values> getChangeSet( - final Class clazz, final DescriptorEvent event) { - final T rolloutGroup = clazz.cast(event.getObject()); - final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet(); - return changeSet.getChanges().stream().filter(record -> record instanceof DirectToFieldChangeRecord) - .map(record -> (DirectToFieldChangeRecord) record) - .collect(Collectors.toMap(record -> record.getAttribute(), - record -> new AbstractPropertyChangeEvent(rolloutGroup, null).new Values( - record.getOldValue(), record.getNewValue()))); - } - - private AfterTransactionCommitExecutor getAfterTransactionCommmitExecutor() { - return AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit(); - } - - private EventBus getEventBus() { - return EventBusHolder.getInstance().getEventBus(); - } + @Override + public void postUpdate(final DescriptorEvent event) { + AbstractDescriptorEventVisitor visitor = new AbstractDescriptorEventVisitorImpl(); + ((AbstractJpaBaseEntity) event.getObject()).postActionOnEntity(visitor, + new DescriptorEventDetails(ActionType.UPDATE, event)); + } + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEventProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEventProvider.java index cca4bdd4c..f064a76a1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEventProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitEventProvider.java @@ -12,25 +12,29 @@ import java.util.HashSet; import java.util.Set; import org.eclipse.hawkbit.eventbus.event.Event; -import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagCreatedBulkEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.eventbus.event.RolloutChangeEvent; import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupChangeEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagCreatedBulkEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; /** * The default hawkbit event provider. */ public class HawkbitEventProvider implements UIEventProvider { - private static final Set> SINGLE_EVENTS = new HashSet<>(6); - private static final Set> BULK_EVENTS = new HashSet<>(3); + private static final Set> SINGLE_EVENTS = new HashSet<>(9); + private static final Set> BULK_EVENTS = new HashSet<>(5); static { SINGLE_EVENTS.add(TargetTagCreatedBulkEvent.class); @@ -41,10 +45,14 @@ public class HawkbitEventProvider implements UIEventProvider { SINGLE_EVENTS.add(RolloutGroupChangeEvent.class); SINGLE_EVENTS.add(RolloutChangeEvent.class); SINGLE_EVENTS.add(TargetTagUpdateEvent.class); + SINGLE_EVENTS.add(DistributionSetUpdateEvent.class); BULK_EVENTS.add(TargetCreatedEvent.class); BULK_EVENTS.add(TargetInfoUpdateEvent.class); BULK_EVENTS.add(TargetDeletedEvent.class); + BULK_EVENTS.add(DistributionDeletedEvent.class); + BULK_EVENTS.add(DistributionCreatedEvent.class); + BULK_EVENTS.add(TargetUpdatedEvent.class); } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index a52c0b683..9430dc135 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -21,6 +21,9 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleIdName; @@ -116,6 +119,33 @@ public class DistributionSetTable extends AbstractNamedVersionTable visibleItemIds = (List) getVisibleItemIds(); + + // refresh the details tabs only if selected ds is updated + if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) { + // update table row+details layout + eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, ds)); + } else if (visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent()) { + // update the name/version details visible in table + UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); + } + } + + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvents(final List events) { + final Object firstEvent = events.get(0); + if (DistributionCreatedEvent.class.isInstance(firstEvent)) { + refreshDistributions(); + } else if (DistributionDeletedEvent.class.isInstance(firstEvent)) { + onDistributionDeleteEvent((List) events); + } + } + @Override protected String getTableId() { return SPUIComponentIdProvider.DIST_TABLE_ID; @@ -422,11 +452,15 @@ public class DistributionSetTable extends AbstractNamedVersionTable updateDistributionInTable(event.getEntity())); } @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final SaveActionWindowEvent event) { - if (event == SaveActionWindowEvent.DELETED_DISTRIBUTIONS || event == SaveActionWindowEvent.SAVED_ASSIGNMENTS) { + if (event == SaveActionWindowEvent.SAVED_ASSIGNMENTS) { UI.getCurrent().access(() -> refreshFilter()); } } @@ -467,6 +501,78 @@ public class DistributionSetTable extends AbstractNamedVersionTable events) { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + final List visibleItemIds = (List) getVisibleItemIds(); + boolean shouldRefreshDs = false; + for (final DistributionDeletedEvent deletedEvent : events) { + Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); + for (Long dsId : distributionSetIDs) { + final DistributionSetIdName targetIdName = new DistributionSetIdName(dsId, null, null); + if (visibleItemIds.contains(targetIdName)) { + dsContainer.removeItem(targetIdName); + } else { + shouldRefreshDs = true; + } + } + } + + if (shouldRefreshDs) { + refreshOnDelete(); + } else { + dsContainer.commit(); + } + reSelectItemsAfterDeletionEvent(); + } + + private void refreshOnDelete() { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + final int size = dsContainer.size(); + refreshTablecontainer(); + if (size != 0) { + setData(SPUIDefinitions.DATA_AVAILABLE); + } + } + + private void reSelectItemsAfterDeletionEvent() { + Set values = new HashSet<>(); + if (isMultiSelect()) { + values = new HashSet<>((Set) getValue()); + } else { + values.add(getValue()); + } + setValue(null); + + for (final Object value : values) { + if (getVisibleItemIds().contains(value)) { + select(value); + } + } + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java index a262f0d20..efe28beb5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/ManageDistBeanQuery.java @@ -42,7 +42,7 @@ import com.google.common.base.Strings; public class ManageDistBeanQuery extends AbstractBeanQuery { private static final long serialVersionUID = 5176481314404662215L; - private Sort sort = new Sort(Direction.ASC, "name", "version"); + private Sort sort = new Sort(Direction.ASC, "createdAt"); private String searchText = null; private transient DistributionSetManagement distributionSetManagement; private transient Page firstPageDistributionSets = null; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java index 35f88f5a1..80c9b0497 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CustomTargetBeanQuery.java @@ -155,9 +155,9 @@ public class CustomTargetBeanQuery extends AbstractBeanQuery { size = getTargetManagement().countTargetByTargetFilterQuery(filterQuery); } getFilterManagementUIState().setTargetsCountAll(size); - if (size > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { - getFilterManagementUIState().setTargetsTruncated(size - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); - size = SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES; + if (size > SPUIDefinitions.MAX_TABLE_ENTRIES) { + getFilterManagementUIState().setTargetsTruncated(size - SPUIDefinitions.MAX_TABLE_ENTRIES); + size = SPUIDefinitions.MAX_TABLE_ENTRIES; } else { getFilterManagementUIState().setTargetsTruncated(null); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java index 4700b48eb..c82467425 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/footer/TargetFilterCountMessageLabel.java @@ -93,7 +93,7 @@ public class TargetFilterCountMessageLabel extends Label { // set the icon setIcon(FontAwesome.INFO_CIRCLE); setDescription(i18n.get("label.target.filter.truncated", filterManagementUIState.getTargetsTruncated(), - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES)); + SPUIDefinitions.MAX_TABLE_ENTRIES)); } else { setIcon(null); @@ -102,8 +102,8 @@ public class TargetFilterCountMessageLabel extends Label { targetMessage.append(totalTargets); targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE); targetMessage.append(i18n.get("label.filter.shown")); - if (totalTargets > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { - targetMessage.append(SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); + if (totalTargets > SPUIDefinitions.MAX_TABLE_ENTRIES) { + targetMessage.append(SPUIDefinitions.MAX_TABLE_ENTRIES); } else { targetMessage.append(HawkbitCommonUtil.SP_STRING_SPACE); targetMessage.append(totalTargets); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index 5b5d53524..6c79f3b3d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -10,8 +10,10 @@ package org.eclipse.hawkbit.ui.management.dstable; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import javax.annotation.PostConstruct; @@ -23,10 +25,10 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.ui.common.CommonDialogWindow; +import org.eclipse.hawkbit.ui.common.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.DistributionSetTypeBeanQuery; -import org.eclipse.hawkbit.ui.common.table.BaseEntityEventType; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; -import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; +import org.eclipse.hawkbit.ui.distributions.dstable.DistributionSetTable; import org.eclipse.hawkbit.ui.management.event.DragEvent; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; @@ -89,6 +91,9 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { @Autowired private transient EntityFactory entityFactory; + + @Autowired + private transient DistributionSetTable distributionSetTable; private TextField distNameTextField; private TextField distVersionTextField; @@ -243,8 +248,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { distributionSetManagement.updateDistributionSet(currentDS); notificationMessage.displaySuccess(i18n.get("message.new.dist.save.success", new Object[] { currentDS.getName(), currentDS.getVersion() })); - // update table row+details layout - eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, currentDS)); } catch (final EntityAlreadyExistsException entityAlreadyExistsException) { LOG.error("Update distribution failed {}", entityAlreadyExistsException); notificationMessage.displayValidationError( @@ -289,8 +292,10 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { new Object[] { newDist.getName(), newDist.getVersion() })); /* close the window */ closeThisWindow(); - - eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.NEW_ENTITY, newDist)); + + final Set s = new HashSet<>(); + s.add(new DistributionSetIdName(newDist.getId(),newDist.getName(),newDist.getVersion())); + distributionSetTable.setValue(s); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java index 63ed91250..672cc0a1c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionBeanQuery.java @@ -41,7 +41,7 @@ import com.google.common.base.Strings; public class DistributionBeanQuery extends AbstractBeanQuery { private static final long serialVersionUID = 5862679853949173536L; - private Sort sort = new Sort(Direction.ASC, "name", "version"); + private Sort sort = new Sort(Direction.ASC, "createdAt"); private Collection distributionTags; private String searchText; private String pinnedControllerId; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index 5b265fc14..056abf12e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -20,6 +20,9 @@ import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.Target; @@ -105,6 +108,35 @@ public class DistributionTable extends AbstractNamedVersionTable events) { + final Object firstEvent = events.get(0); + if (DistributionDeletedEvent.class.isInstance(firstEvent)) { + onDistributionDeleteEvent((List) events); + } else if (DistributionCreatedEvent.class.isInstance(firstEvent) + && ((DistributionCreatedEvent) firstEvent).getEntity().isComplete()) { + refreshDistributions(); + } + + } + + @EventBusListenerMethod(scope = EventScope.SESSION) + void onEvents(final DistributionSetUpdateEvent event) { + final DistributionSet ds = event.getEntity(); + final DistributionSetIdName lastSelectedDsIdName = managementUIState.getLastSelectedDsIdName(); + final List visibleItemIds = (List) getVisibleItemIds(); + + // refresh the details tabs only if selected ds is updated + // refresh the details tabs only if selected ds is updated + if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) { + // update table row+details layout + eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, ds)); + } else if (visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent()) { + //update the name/version details visible in table + UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); + } + } + /** * DistributionTableFilterEvent. * @@ -658,4 +690,69 @@ public class DistributionTable extends AbstractNamedVersionTable events) { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + final List visibleItemIds = (List) getVisibleItemIds(); + boolean shouldRefreshDs = false; + for (final DistributionDeletedEvent deletedEvent : events) { + Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); + for (Long dsId : distributionSetIDs) { + final DistributionSetIdName targetIdName = new DistributionSetIdName(dsId, null, null); + if (visibleItemIds.contains(targetIdName)) { + dsContainer.removeItem(targetIdName); + } else { + shouldRefreshDs = true; + } + } + } + + if (shouldRefreshDs) { + refreshOnDelete(); + } else { + dsContainer.commit(); + } + reSelectItemsAfterDeletionEvent(); + } + + private void reSelectItemsAfterDeletionEvent() { + Set values = new HashSet<>(); + if (isMultiSelect()) { + values = new HashSet<>((Set) getValue()); + } else { + values.add(getValue()); + } + setValue(null); + + for (final Object value : values) { + if (getVisibleItemIds().contains(value)) { + select(value); + } + } + } + + private void refreshDistributions() { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + final int size = dsContainer.size(); + if (size < SPUIDefinitions.MAX_TABLE_ENTRIES) { + refreshTablecontainer(); + } + if (size != 0) { + setData(SPUIDefinitions.DATA_AVAILABLE); + } + } + + private void refreshOnDelete() { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + final int size = dsContainer.size(); + refreshTablecontainer(); + if (size != 0) { + setData(SPUIDefinitions.DATA_AVAILABLE); + } + } + + private void refreshTablecontainer() { + final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); + dsContainer.refresh(); + selectRow(); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java index fccee7cb5..6cf01410d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/CountMessageLabel.java @@ -174,7 +174,7 @@ public class CountMessageLabel extends Label { // set the icon setIcon(FontAwesome.INFO_CIRCLE); setDescription(i18n.get("label.target.filter.truncated", managementUIState.getTargetsTruncated(), - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES)); + SPUIDefinitions.MAX_TABLE_ENTRIES)); totalTargetTableEnteries += managementUIState.getTargetsTruncated(); } else { setIcon(null); @@ -184,9 +184,9 @@ public class CountMessageLabel extends Label { final StringBuilder message = new StringBuilder(i18n.get("label.target.filter.count")); message.append(managementUIState.getTargetsCountAll()); message.append(HawkbitCommonUtil.SP_STRING_SPACE); - if (totalTargetTableEnteries > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { + if (totalTargetTableEnteries > SPUIDefinitions.MAX_TABLE_ENTRIES) { message.append(i18n.get("label.filter.shown")); - message.append(SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); + message.append(SPUIDefinitions.MAX_TABLE_ENTRIES); } else { if (!targFilParams.hasFilter()) { message.append(i18n.get("label.filter.shown")); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java index 1a9d3572f..e4c56b165 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/footer/ManangementConfirmationWindowLayout.java @@ -387,7 +387,6 @@ public class ManangementConfirmationWindowLayout extends AbstractConfirmationWin managementUIState.getTargetTableFilters().getPinnedDistId() .ifPresent(distId -> unPinDeletedDS(deletedIds, distId)); - eventBus.publish(this, SaveActionWindowEvent.DELETED_DISTRIBUTIONS); managementUIState.getDeletedDistributionList().clear(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java index e96a9af8e..6ce3c5cb6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBeanQuery.java @@ -190,9 +190,9 @@ public class TargetBeanQuery extends AbstractBeanQuery { final ManagementUIState tmpManagementUIState = getManagementUIState(); tmpManagementUIState.setTargetsCountAll(totSize); - if (size > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { - tmpManagementUIState.setTargetsTruncated(size - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); - size = SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES; + if (size > SPUIDefinitions.MAX_TABLE_ENTRIES) { + tmpManagementUIState.setTargetsTruncated(size - SPUIDefinitions.MAX_TABLE_ENTRIES); + size = SPUIDefinitions.MAX_TABLE_ENTRIES; } else { tmpManagementUIState.setTargetsTruncated(null); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java index 0a70f60d5..0a0eaaa7e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java @@ -17,11 +17,12 @@ import java.util.Map; import java.util.Set; import java.util.stream.Collectors; -import org.eclipse.hawkbit.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.repository.model.TargetInfo; @@ -142,6 +143,8 @@ public class TargetTable extends AbstractTable { onTargetInfoUpdateEvents((List) events); } else if (TargetDeletedEvent.class.isInstance(firstEvent)) { onTargetDeletedEvent((List) events); + } else if(TargetUpdatedEvent.class.isInstance(firstEvent)){ + onTargetUpdateEvents((List) events); } } @@ -809,7 +812,7 @@ public class TargetTable extends AbstractTable { private void refreshTargets() { final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource(); final int size = targetContainer.size(); - if (size < SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { + if (size < SPUIDefinitions.MAX_TABLE_ENTRIES) { refreshTablecontainer(); } else { // If table is not refreshed , explicitly target total count and @@ -829,10 +832,12 @@ public class TargetTable extends AbstractTable { final TargetIdName targetIdName) { final LazyQueryContainer targetContainer = (LazyQueryContainer) getContainerDataSource(); final Item item = targetContainer.getItem(targetIdName); - item.getItemProperty(SPUILabelDefinitions.VAR_TARGET_STATUS).setValue(targetInfo.getUpdateStatus()); item.getItemProperty(SPUILabelDefinitions.VAR_NAME).setValue(target.getName()); - item.getItemProperty(SPUILabelDefinitions.VAR_POLL_STATUS_TOOL_TIP) - .setValue(HawkbitCommonUtil.getPollStatusToolTip(targetInfo.getPollStatus(), i18n)); + if (targetInfo != null) { + item.getItemProperty(SPUILabelDefinitions.VAR_POLL_STATUS_TOOL_TIP).setValue( + HawkbitCommonUtil.getPollStatusToolTip(targetInfo.getPollStatus(), i18n)); + item.getItemProperty(SPUILabelDefinitions.VAR_TARGET_STATUS).setValue(targetInfo.getUpdateStatus()); + } } private boolean isLastSelectedTarget(final TargetIdName targetIdName) { @@ -879,6 +884,35 @@ public class TargetTable extends AbstractTable { } } + + private void onTargetUpdateEvents(List events) { + final List visibleItemIds = (List) getVisibleItemIds(); + boolean shoulTargetsUpdated = false; + Target lastSelectedTarget = null; + for (final TargetUpdatedEvent targetUpdatedEvent : events) { + Target target = targetUpdatedEvent.getEntity(); + final TargetIdName targetIdName = target.getTargetIdName(); + if (Filters.or(getTargetTableFilters(target)).doFilter()) { + shoulTargetsUpdated = true; + } else { + if (visibleItemIds.contains(targetIdName)) { + updateVisibleItemOnEvent(null, target, targetIdName); + } + } + if (isLastSelectedTarget(targetIdName)) { + lastSelectedTarget = target; + } + } + if (shoulTargetsUpdated) { + refreshTargets(); + } + if (lastSelectedTarget != null) { + eventBus.publish(this, new TargetTableEvent(BaseEntityEventType.SELECTED_ENTITY, lastSelectedTarget)); + } + } + + + private void onTargetCreatedEvents() { refreshTargets(); } @@ -953,8 +987,8 @@ public class TargetTable extends AbstractTable { size = getTargetsCountWithFilter(totalTargetsCount, status, targetTags, distributionId, searchText, noTagClicked, pinnedDistId); - if (size > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { - managementUIState.setTargetsTruncated(size - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); + if (size > SPUIDefinitions.MAX_TABLE_ENTRIES) { + managementUIState.setTargetsTruncated(size - SPUIDefinitions.MAX_TABLE_ENTRIES); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsBeanQuery.java index 685be685e..487f05ae5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsBeanQuery.java @@ -140,9 +140,9 @@ public class RolloutGroupTargetsBeanQuery extends AbstractBeanQuery size = firstPageTargetSets.getTotalElements(); } getRolloutUIState().setRolloutGroupTargetsTotalCount(size); - if (size > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { - getRolloutUIState().setRolloutGroupTargetsTruncated(size - SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); - return SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES; + if (size > SPUIDefinitions.MAX_TABLE_ENTRIES) { + getRolloutUIState().setRolloutGroupTargetsTruncated(size - SPUIDefinitions.MAX_TABLE_ENTRIES); + return SPUIDefinitions.MAX_TABLE_ENTRIES; } return (int) size; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java index c791a0eb2..e5c716e83 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rolloutgrouptargets/RolloutGroupTargetsCountLabelMessage.java @@ -94,7 +94,7 @@ public class RolloutGroupTargetsCountLabelMessage extends Label { // set the icon setIcon(FontAwesome.INFO_CIRCLE); setDescription(i18n.get("rollout.group.label.target.truncated", - rolloutUIState.getRolloutGroupTargetsTruncated(), SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES)); + rolloutUIState.getRolloutGroupTargetsTruncated(), SPUIDefinitions.MAX_TABLE_ENTRIES)); totalTargetTableEnteries += rolloutUIState.getRolloutGroupTargetsTruncated(); } else { setIcon(null); @@ -104,9 +104,9 @@ public class RolloutGroupTargetsCountLabelMessage extends Label { final StringBuilder message = new StringBuilder(i18n.get("label.target.filter.count")); message.append(rolloutUIState.getRolloutGroupTargetsTotalCount()); message.append(HawkbitCommonUtil.SP_STRING_SPACE); - if (totalTargetTableEnteries > SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES) { + if (totalTargetTableEnteries > SPUIDefinitions.MAX_TABLE_ENTRIES) { message.append(i18n.get("label.filter.shown")); - message.append(SPUIDefinitions.MAX_TARGET_TABLE_ENTRIES); + message.append(SPUIDefinitions.MAX_TABLE_ENTRIES); } else { message.append(i18n.get("label.filter.shown")); message.append(rolloutGroupTargetsListGrid.getContainerDataSource().size()); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java index 1a6e8c163..1766485f6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java @@ -268,10 +268,6 @@ public final class SPUIDefinitions { * New Target save icon id. */ public static final String NEW_TARGET_SAVE = "target.add.save"; - /** - * New Target discard icon id. - */ - // public static final String NEW_TARGET_DISCARD = "target.add.discard"; /** * New Target add icon id. */ @@ -344,15 +340,6 @@ public final class SPUIDefinitions { * New Target tag color lable id. */ public static final String NEW_TARGET_TAG_COLOR = "target.tag.add.color"; - /** - * New Target tag save icon id. - */ - // public static final String NEW_TARGET_TAG_SAVE = "target.tag.add.save"; - /** - * New Target tag discard icon id. - */ - // public static final String NEW_TARGET_TAG_DISRACD = - // "target.tag.add.discard"; /** * New Target tag add icon id. */ @@ -860,7 +847,7 @@ public final class SPUIDefinitions { * truncates it. This protects to endless scroll to very high page numbers * which is very in performant. */ - public static final int MAX_TARGET_TABLE_ENTRIES = 5000; + public static final int MAX_TABLE_ENTRIES = 5000; /** * New software module set type add icon id. From e67a466b2c5917d853a43badb1d912b85f74588c Mon Sep 17 00:00:00 2001 From: gah6kor Date: Thu, 14 Jul 2016 13:27:45 +0200 Subject: [PATCH 006/118] Addded multi unassign buttons for the software modules. --- .../CreateUpdateSoftwareTypeLayout.java | 8 ++ .../SoftwareModuleDetailsTable.java | 84 ++++++++----------- .../dstable/DistributionSetDetails.java | 36 +++++--- .../hawkbit/ui/utils/SPUIDefinitions.java | 10 +++ 4 files changed, 79 insertions(+), 59 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index d6ecd70dd..db525dd31 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -193,6 +193,7 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout assignOptiongroup.setStyleName(ValoTheme.OPTIONGROUP_SMALL); assignOptiongroup.addStyleName("custom-option-group"); assignOptiongroup.setNullSelectionAllowed(false); + assignOptiongroup.setId(SPUIDefinitions.ASSIGN_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID); assignOptiongroup.select(tagOptions.get(0)); } @@ -327,5 +328,12 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout new BeanQueryFactory(SoftwareModuleTypeBeanQuery.class))); tagNameComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); } + + @Override + protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) { + + super.createOptionGroup(hasCreatePermission, hasUpdatePermission); + optiongroup.setId(SPUIDefinitions.CREATE_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java index 6e4c7dddd..a24ea3a8a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java @@ -37,8 +37,10 @@ import com.vaadin.data.util.IndexedContainer; import com.vaadin.server.FontAwesome; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Table; +import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; /** @@ -60,8 +62,6 @@ public class SoftwareModuleDetailsTable extends Table { private static final String SOFT_TYPE_MANDATORY = "mandatory"; - private static final String UNASSIGN_SOFT_MODULE = "unassignSoftModule"; - private boolean isTargetAssigned; private boolean isUnassignSoftModAllowed; @@ -109,7 +109,6 @@ public class SoftwareModuleDetailsTable extends Table { private void createSwModuleTable() { addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES); - addStyleName(ValoTheme.TABLE_NO_STRIPES); setSelectable(false); setImmediate(true); setContainerDataSource(getSwModuleContainer()); @@ -123,22 +122,13 @@ public class SoftwareModuleDetailsTable extends Table { final IndexedContainer container = new IndexedContainer(); container.addContainerProperty(SOFT_TYPE_MANDATORY, Label.class, ""); container.addContainerProperty(SOFT_TYPE_NAME, Label.class, ""); - container.addContainerProperty(SOFT_MODULE, Label.class, ""); - if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission()) { - container.addContainerProperty(UNASSIGN_SOFT_MODULE, Button.class, ""); - } + container.addContainerProperty(SOFT_MODULE, VerticalLayout.class, ""); setColumnExpandRatio(SOFT_TYPE_MANDATORY, 0.1f); setColumnExpandRatio(SOFT_TYPE_NAME, 0.4f); setColumnExpandRatio(SOFT_MODULE, 0.3f); - if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission()) { - setColumnExpandRatio(UNASSIGN_SOFT_MODULE, 0.2F); - } setColumnAlignment(SOFT_TYPE_MANDATORY, Align.RIGHT); setColumnAlignment(SOFT_TYPE_NAME, Align.LEFT); setColumnAlignment(SOFT_MODULE, Align.LEFT); - if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission()) { - setColumnAlignment(UNASSIGN_SOFT_MODULE, Align.RIGHT); - } return container; } @@ -146,10 +136,6 @@ public class SoftwareModuleDetailsTable extends Table { setColumnHeader(SOFT_TYPE_MANDATORY, ""); setColumnHeader(SOFT_TYPE_NAME, i18n.get("header.caption.typename")); setColumnHeader(SOFT_MODULE, i18n.get("header.caption.softwaremodule")); - if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission()) { - setColumnHeader(UNASSIGN_SOFT_MODULE, i18n.get("header.caption.unassign")); - } - } /** @@ -188,31 +174,17 @@ public class SoftwareModuleDetailsTable extends Table { final Item saveTblitem = getContainerDataSource().addItem(swModType.getName()); final Label mandatoryLabel = createMandatoryLabel(isMandatory); final Label typeName = HawkbitCommonUtil.getFormatedLabel(swModType.getName()); + final VerticalLayout verticalLayout = createSoftModuleLayout(swModType,distributionSet, alreadyAssignedSwModules); - final Label softwareModule = HawkbitCommonUtil.getFormatedLabel(HawkbitCommonUtil.SP_STRING_EMPTY); - final Button reassignSoftModule = SPUIComponentProvider.getButton(swModType.getName(), "", "", "", true, - FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class); - - reassignSoftModule.addClickListener(event -> unassignSW(event, distributionSet, alreadyAssignedSwModules)); - if (null != alreadyAssignedSwModules && !alreadyAssignedSwModules.isEmpty()) { - final String swModuleName = getSwModuleName(alreadyAssignedSwModules, swModType); - softwareModule.setValue(swModuleName); - softwareModule.setDescription(swModuleName); - } saveTblitem.getItemProperty(SOFT_TYPE_MANDATORY).setValue(mandatoryLabel); saveTblitem.getItemProperty(SOFT_TYPE_NAME).setValue(typeName); - saveTblitem.getItemProperty(SOFT_MODULE).setValue(softwareModule); - if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission() && !isTargetAssigned - && (isSoftModAvaiableForSoftType(alreadyAssignedSwModules, swModType))) { - saveTblitem.getItemProperty(UNASSIGN_SOFT_MODULE).setValue(reassignSoftModule); - } + saveTblitem.getItemProperty(SOFT_MODULE).setValue(verticalLayout); } private void unassignSW(final ClickEvent event, final DistributionSet distributionSet, final Set alreadyAssignedSwModules) { - final SoftwareModule unAssignedSw = getSoftwareModule((Label) getContainerDataSource() - .getItem(event.getButton().getId()).getItemProperty(SOFT_MODULE).getValue(), alreadyAssignedSwModules); + final SoftwareModule unAssignedSw = getSoftwareModule(event.getButton().getId(),alreadyAssignedSwModules); final DistributionSet newDistributionSet = distributionSetManagement.unassignSoftwareModule(distributionSet, unAssignedSw); manageDistUIState.setLastSelectedEntity(DistributionSetIdName.generate(newDistributionSet)); @@ -232,16 +204,45 @@ public class SoftwareModuleDetailsTable extends Table { return false; } + + + private VerticalLayout createSoftModuleLayout(final SoftwareModuleType swModType,DistributionSet distributionSet, Set alreadyAssignedSwModules){ + VerticalLayout verticalLayout = new VerticalLayout(); + for (final SoftwareModule sw : alreadyAssignedSwModules) { + if (swModType.getKey().equals(sw.getType().getKey())) { + HorizontalLayout horizontalLayout = new HorizontalLayout(); + horizontalLayout.setSizeFull(); + final Label softwareModule = HawkbitCommonUtil.getFormatedLabel(HawkbitCommonUtil.SP_STRING_EMPTY); + final Button reassignSoftModule = SPUIComponentProvider.getButton(sw.getName(), "", "", "", true, + FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class); + reassignSoftModule.addClickListener(event -> unassignSW(event, distributionSet, alreadyAssignedSwModules)); + String softwareModNameVersion = HawkbitCommonUtil.getFormattedNameVersion(sw.getName(), sw.getVersion()); + softwareModule.setValue(softwareModNameVersion); + softwareModule.setDescription(softwareModNameVersion); + softwareModule.setId(sw.getName()+"-label"); + horizontalLayout.addComponent(softwareModule); + horizontalLayout.setExpandRatio(softwareModule, 1f); + if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission() && !isTargetAssigned + && (isSoftModAvaiableForSoftType(alreadyAssignedSwModules, swModType))) { + horizontalLayout.addComponent(reassignSoftModule); + } + verticalLayout.addComponent(horizontalLayout); + } + + } + + return verticalLayout; + } /** * @param value * @param alreadyAssignedSwModules * @return */ - protected SoftwareModule getSoftwareModule(final Label softwareModule, + protected SoftwareModule getSoftwareModule(final String softwareModule, final Set alreadyAssignedSwModules) { for (final SoftwareModule sw : alreadyAssignedSwModules) { - if (softwareModule.getValue().contains(sw.getName())) { + if (softwareModule.equals(sw.getName())) { return sw; } } @@ -256,15 +257,4 @@ public class SoftwareModuleDetailsTable extends Table { } return mandatoryLable; } - - private String getSwModuleName(final Set swModulesSet, final SoftwareModuleType swModType) { - final StringBuilder assignedSWModules = new StringBuilder(); - for (final SoftwareModule sw : swModulesSet) { - if (swModType.getKey().equals(sw.getType().getKey())) { - assignedSWModules.append(HawkbitCommonUtil.getFormattedNameVersion(sw.getName(), sw.getVersion())) - .append("
"); - } - } - return assignedSWModules.toString(); - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java index 75f7071ea..7392688b0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java @@ -43,6 +43,7 @@ import com.vaadin.spring.annotation.SpringComponent; import com.vaadin.spring.annotation.ViewScope; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; +import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.TabSheet; import com.vaadin.ui.UI; @@ -63,8 +64,6 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet private static final String SOFT_MODULE = "softwareModule"; - private static final String UNASSIGN_SOFT_MODULE = "unassignSoftModule"; - @Autowired private ManageDistUIState manageDistUIState; @@ -150,23 +149,22 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet item = softwareModuleTable.getContainerDataSource().getItem(entry.getKey()); if (item != null) { item.getItemProperty(SOFT_MODULE) - .setValue(HawkbitCommonUtil.getFormatedLabel(entry.getValue().toString())); - assignSoftModuleButton(item, entry); - + .setValue(createSoftModuleLayout(entry.getValue().toString())); } } } } - private void assignSoftModuleButton(final Item item, final Map.Entry entry) { + private Button assignSoftModuleButton(final String softwareModuleName) { if (getPermissionChecker().hasUpdateDistributionPermission() && distributionSetManagement .findDistributionSetById(manageDistUIState.getLastSelectedDistribution().get().getId()) .getAssignedTargets().isEmpty()) { - final Button reassignSoftModule = SPUIComponentProvider.getButton(entry.getKey(), "", "", "", true, + final Button reassignSoftModule = SPUIComponentProvider.getButton(softwareModuleName, "", "", "", true, FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class); reassignSoftModule.setEnabled(false); - item.getItemProperty(UNASSIGN_SOFT_MODULE).setValue(reassignSoftModule); + return reassignSoftModule; } + return null; } private String getUnsavedAssigedSwModule(final String name, final String version) { @@ -208,12 +206,26 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet final Item item = softwareModuleTable.getContainerDataSource().getItem(entry.getKey()); if (item != null) { item.getItemProperty(SOFT_MODULE) - .setValue(HawkbitCommonUtil.getFormatedLabel(entry.getValue().toString())); - assignSoftModuleButton(item, entry); - + .setValue(createSoftModuleLayout(entry.getValue().toString())); } } } + + private VerticalLayout createSoftModuleLayout(String softwareModuleName){ + VerticalLayout verticalLayout = new VerticalLayout(); + HorizontalLayout horizontalLayout = new HorizontalLayout(); + horizontalLayout.setSizeFull(); + final Label softwareModule = HawkbitCommonUtil.getFormatedLabel(HawkbitCommonUtil.SP_STRING_EMPTY); + final Button reassignSoftModule = assignSoftModuleButton(softwareModuleName); + softwareModule.setValue(softwareModuleName); + softwareModule.setDescription(softwareModuleName); + softwareModule.setId(softwareModuleName+"-label"); + horizontalLayout.addComponent(softwareModule); + horizontalLayout.setExpandRatio(softwareModule, 1f); + horizontalLayout.addComponent(reassignSoftModule); + verticalLayout.addComponent(horizontalLayout); + return verticalLayout; + } private VerticalLayout createSoftwareModuleTab() { final VerticalLayout softwareLayout = getTabLayout(); @@ -353,7 +365,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet @Override protected String getTabSheetId() { - return null; + return SPUIComponentIdProvider.DISTRIBUTION_DETAILS_TABSHEET; } @Override diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java index 1a6e8c163..bef07d7f0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java @@ -304,6 +304,16 @@ public final class SPUIDefinitions { * New Create Update option group id. */ public static final String CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID = "create.option.group.dist.set.type.id"; + + /** + * New Create Update option group id. + */ + public static final String CREATE_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID = "create.option.group.soft.module.type.id"; + + /** + * Assign option group id(Firmware/Software). + */ + public static final String ASSIGN_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID = "assign.option.group.soft.module.type.id"; /** * SW Module Source Table ID. */ From b117fb06572e5f0240834989783d1e92a1dde85b Mon Sep 17 00:00:00 2001 From: gah6kor Date: Thu, 14 Jul 2016 17:44:43 +0200 Subject: [PATCH 007/118] Fix for jenkins build failure --- .../artifacts/smtype/CreateUpdateSoftwareTypeLayout.java | 7 ------- .../java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java | 5 ----- 2 files changed, 12 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java index cdba56e00..6355701c9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/CreateUpdateSoftwareTypeLayout.java @@ -271,12 +271,5 @@ public class CreateUpdateSoftwareTypeLayout extends CreateUpdateTypeLayout { new BeanQueryFactory(SoftwareModuleTypeBeanQuery.class))); tagNameComboBox.setItemCaptionPropertyId(SPUILabelDefinitions.VAR_NAME); } - - @Override - protected void createOptionGroup(final boolean hasCreatePermission, final boolean hasUpdatePermission) { - - super.createOptionGroup(hasCreatePermission, hasUpdatePermission); - optiongroup.setId(SPUIDefinitions.CREATE_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID); - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java index d2675cd9e..1f9ef040e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java @@ -305,11 +305,6 @@ public final class SPUIDefinitions { */ public static final String CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID = "create.option.group.dist.set.type.id"; - /** - * New Create Update option group id. - */ - public static final String CREATE_OPTION_GROUP_SOFTWARE_MODULE_TYPE_ID = "create.option.group.soft.module.type.id"; - /** * Assign option group id(Firmware/Software). */ From ed830dd728fbf51358178c0c9de88a76846e5ead Mon Sep 17 00:00:00 2001 From: gah6kor Date: Mon, 18 Jul 2016 11:16:56 +0200 Subject: [PATCH 008/118] Formatted the code --- .../SoftwareModuleDetailsTable.java | 37 ++++++++++--------- .../dstable/DistributionSetDetails.java | 24 ++++++------ .../hawkbit/ui/utils/SPUIDefinitions.java | 2 +- 3 files changed, 32 insertions(+), 31 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java index a24ea3a8a..08ec45582 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java @@ -174,7 +174,8 @@ public class SoftwareModuleDetailsTable extends Table { final Item saveTblitem = getContainerDataSource().addItem(swModType.getName()); final Label mandatoryLabel = createMandatoryLabel(isMandatory); final Label typeName = HawkbitCommonUtil.getFormatedLabel(swModType.getName()); - final VerticalLayout verticalLayout = createSoftModuleLayout(swModType,distributionSet, alreadyAssignedSwModules); + final VerticalLayout verticalLayout = createSoftModuleLayout(swModType, distributionSet, + alreadyAssignedSwModules); saveTblitem.getItemProperty(SOFT_TYPE_MANDATORY).setValue(mandatoryLabel); saveTblitem.getItemProperty(SOFT_TYPE_NAME).setValue(typeName); @@ -184,7 +185,7 @@ public class SoftwareModuleDetailsTable extends Table { private void unassignSW(final ClickEvent event, final DistributionSet distributionSet, final Set alreadyAssignedSwModules) { - final SoftwareModule unAssignedSw = getSoftwareModule(event.getButton().getId(),alreadyAssignedSwModules); + final SoftwareModule unAssignedSw = getSoftwareModule(event.getButton().getId(), alreadyAssignedSwModules); final DistributionSet newDistributionSet = distributionSetManagement.unassignSoftwareModule(distributionSet, unAssignedSw); manageDistUIState.setLastSelectedEntity(DistributionSetIdName.generate(newDistributionSet)); @@ -204,34 +205,36 @@ public class SoftwareModuleDetailsTable extends Table { return false; } - - - private VerticalLayout createSoftModuleLayout(final SoftwareModuleType swModType,DistributionSet distributionSet, Set alreadyAssignedSwModules){ - VerticalLayout verticalLayout = new VerticalLayout(); - for (final SoftwareModule sw : alreadyAssignedSwModules) { + + private VerticalLayout createSoftModuleLayout(final SoftwareModuleType swModType, + final DistributionSet distributionSet, final Set alreadyAssignedSwModules) { + final VerticalLayout verticalLayout = new VerticalLayout(); + for (final SoftwareModule sw : alreadyAssignedSwModules) { if (swModType.getKey().equals(sw.getType().getKey())) { - HorizontalLayout horizontalLayout = new HorizontalLayout(); - horizontalLayout.setSizeFull(); - final Label softwareModule = HawkbitCommonUtil.getFormatedLabel(HawkbitCommonUtil.SP_STRING_EMPTY); + final HorizontalLayout horizontalLayout = new HorizontalLayout(); + horizontalLayout.setSizeFull(); + final Label softwareModule = HawkbitCommonUtil.getFormatedLabel(HawkbitCommonUtil.SP_STRING_EMPTY); final Button reassignSoftModule = SPUIComponentProvider.getButton(sw.getName(), "", "", "", true, FontAwesome.TIMES, SPUIButtonStyleSmallNoBorder.class); - reassignSoftModule.addClickListener(event -> unassignSW(event, distributionSet, alreadyAssignedSwModules)); - String softwareModNameVersion = HawkbitCommonUtil.getFormattedNameVersion(sw.getName(), sw.getVersion()); + reassignSoftModule + .addClickListener(event -> unassignSW(event, distributionSet, alreadyAssignedSwModules)); + final String softwareModNameVersion = HawkbitCommonUtil.getFormattedNameVersion(sw.getName(), + sw.getVersion()); softwareModule.setValue(softwareModNameVersion); softwareModule.setDescription(softwareModNameVersion); - softwareModule.setId(sw.getName()+"-label"); + softwareModule.setId(sw.getName() + "-label"); horizontalLayout.addComponent(softwareModule); horizontalLayout.setExpandRatio(softwareModule, 1f); if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission() && !isTargetAssigned && (isSoftModAvaiableForSoftType(alreadyAssignedSwModules, swModType))) { - horizontalLayout.addComponent(reassignSoftModule); + horizontalLayout.addComponent(reassignSoftModule); } verticalLayout.addComponent(horizontalLayout); } - + } - - return verticalLayout; + + return verticalLayout; } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java index c1f4767d1..9824f14c4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java @@ -148,8 +148,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet for (final Map.Entry entry : assignedSWModule.entrySet()) { item = softwareModuleTable.getContainerDataSource().getItem(entry.getKey()); if (item != null) { - item.getItemProperty(SOFT_MODULE) - .setValue(createSoftModuleLayout(entry.getValue().toString())); + item.getItemProperty(SOFT_MODULE).setValue(createSoftModuleLayout(entry.getValue().toString())); } } } @@ -164,7 +163,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet reassignSoftModule.setEnabled(false); return reassignSoftModule; } - return null; + return null; } private String getUnsavedAssigedSwModule(final String name, final String version) { @@ -205,26 +204,25 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet for (final Map.Entry entry : assignedSWModule.entrySet()) { final Item item = softwareModuleTable.getContainerDataSource().getItem(entry.getKey()); if (item != null) { - item.getItemProperty(SOFT_MODULE) - .setValue(createSoftModuleLayout(entry.getValue().toString())); + item.getItemProperty(SOFT_MODULE).setValue(createSoftModuleLayout(entry.getValue().toString())); } } } - - private VerticalLayout createSoftModuleLayout(String softwareModuleName){ - VerticalLayout verticalLayout = new VerticalLayout(); - HorizontalLayout horizontalLayout = new HorizontalLayout(); - horizontalLayout.setSizeFull(); - final Label softwareModule = HawkbitCommonUtil.getFormatedLabel(HawkbitCommonUtil.SP_STRING_EMPTY); + + private VerticalLayout createSoftModuleLayout(final String softwareModuleName) { + final VerticalLayout verticalLayout = new VerticalLayout(); + final HorizontalLayout horizontalLayout = new HorizontalLayout(); + horizontalLayout.setSizeFull(); + final Label softwareModule = HawkbitCommonUtil.getFormatedLabel(HawkbitCommonUtil.SP_STRING_EMPTY); final Button reassignSoftModule = assignSoftModuleButton(softwareModuleName); softwareModule.setValue(softwareModuleName); softwareModule.setDescription(softwareModuleName); - softwareModule.setId(softwareModuleName+"-label"); + softwareModule.setId(softwareModuleName + "-label"); horizontalLayout.addComponent(softwareModule); horizontalLayout.setExpandRatio(softwareModule, 1f); horizontalLayout.addComponent(reassignSoftModule); verticalLayout.addComponent(horizontalLayout); - return verticalLayout; + return verticalLayout; } private VerticalLayout createSoftwareModuleTab() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java index 1f9ef040e..57f5ba2e5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIDefinitions.java @@ -304,7 +304,7 @@ public final class SPUIDefinitions { * New Create Update option group id. */ public static final String CREATE_OPTION_GROUP_DISTRIBUTION_SET_TYPE_ID = "create.option.group.dist.set.type.id"; - + /** * Assign option group id(Firmware/Software). */ From 1cef0b4d4600794291515bb9673b11fa3a24653a Mon Sep 17 00:00:00 2001 From: gah6kor Date: Mon, 18 Jul 2016 15:04:41 +0200 Subject: [PATCH 009/118] Fix for the max assignments. --- .../hawkbit/ui/artifacts/smtable/SoftwareModuleDetails.java | 6 +++--- .../ui/distributions/dstable/DistributionSetDetails.java | 2 +- .../ui/distributions/dstable/DistributionSetTable.java | 2 +- .../hawkbit/ui/distributions/smtable/SwModuleDetails.java | 6 +++--- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleDetails.java index 653994a17..9eb88c3f4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleDetails.java @@ -70,10 +70,10 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta protected void populateDetailsWidget() { String maxAssign = HawkbitCommonUtil.SP_STRING_EMPTY; if (getSelectedBaseEntity() != null) { - if (getSelectedBaseEntity().getType().getMaxAssignments() == Integer.MAX_VALUE) { - maxAssign = getI18n().get("label.multiAssign.type"); - } else { + if (getSelectedBaseEntity().getType().getMaxAssignments() == 1) { maxAssign = getI18n().get("label.singleAssign.type"); + } else { + maxAssign = getI18n().get("label.multiAssign.type"); } updateSoftwareModuleDetailsLayout(getSelectedBaseEntity().getType().getName(), getSelectedBaseEntity().getVendor(), maxAssign); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java index 9824f14c4..c18f4ac80 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java @@ -181,7 +181,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet * type is drroped, then add to the list. */ - if (module.getType().getMaxAssignments() == Integer.MAX_VALUE) { + if (module.getType().getMaxAssignments() > 1) { assignedSWModule.get(module.getType().getName()).append("
").append("") .append(getUnsavedAssigedSwModule(module.getName(), module.getVersion())).append(""); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index a52c0b683..a22409244 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -295,7 +295,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable> map, final SoftwareModule softwareModule, final SoftwareModuleIdName softwareModuleIdName) { - if (softwareModule.getType().getMaxAssignments() == Integer.MAX_VALUE) { + if (softwareModule.getType().getMaxAssignments() > 1) { if (!map.containsKey(softwareModule.getType().getId())) { map.put(softwareModule.getType().getId(), new HashSet()); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java index 472ce8ce1..80dac8a3d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java @@ -99,10 +99,10 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay private void populateDetails() { String maxAssign = HawkbitCommonUtil.SP_STRING_EMPTY; if (getSelectedBaseEntity() != null) { - if (getSelectedBaseEntity().getType().getMaxAssignments() == Integer.MAX_VALUE) { - maxAssign = getI18n().get("label.multiAssign.type"); - } else { + if (getSelectedBaseEntity().getType().getMaxAssignments() == 1) { maxAssign = getI18n().get("label.singleAssign.type"); + } else { + maxAssign = getI18n().get("label.multiAssign.type"); } updateSwModuleDetailsLayout(getSelectedBaseEntity().getType().getName(), getSelectedBaseEntity().getVendor(), maxAssign); From 56616be58d1d882e3396bc9fe8ebaece3a0143a1 Mon Sep 17 00:00:00 2001 From: gah6kor Date: Mon, 18 Jul 2016 15:08:11 +0200 Subject: [PATCH 010/118] Formatted the code --- .../ui/common/detailslayout/SoftwareModuleDetailsTable.java | 2 +- .../ui/distributions/dstable/DistributionSetDetails.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java index 08ec45582..1af6aabe1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java @@ -224,7 +224,7 @@ public class SoftwareModuleDetailsTable extends Table { softwareModule.setDescription(softwareModNameVersion); softwareModule.setId(sw.getName() + "-label"); horizontalLayout.addComponent(softwareModule); - horizontalLayout.setExpandRatio(softwareModule, 1f); + horizontalLayout.setExpandRatio(softwareModule, 1F); if (isUnassignSoftModAllowed && permissionChecker.hasUpdateDistributionPermission() && !isTargetAssigned && (isSoftModAvaiableForSoftType(alreadyAssignedSwModules, swModType))) { horizontalLayout.addComponent(reassignSoftModule); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java index c18f4ac80..9a7b5d3a2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java @@ -219,7 +219,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet softwareModule.setDescription(softwareModuleName); softwareModule.setId(softwareModuleName + "-label"); horizontalLayout.addComponent(softwareModule); - horizontalLayout.setExpandRatio(softwareModule, 1f); + horizontalLayout.setExpandRatio(softwareModule, 1F); horizontalLayout.addComponent(reassignSoftModule); verticalLayout.addComponent(horizontalLayout); return verticalLayout; From 5f1db53defb244763315731257b1a9d85cfec6c1 Mon Sep 17 00:00:00 2001 From: GAH6KOR Date: Thu, 21 Jul 2016 12:39:54 +0200 Subject: [PATCH 011/118] Removed the extra level of abstraction and modified the code accordingly. --- .../AbstractDescriptorEventVisitorImpl.java | 189 ----- .../jpa/model/AbstractJpaBaseEntity.java | 6 +- .../repository/jpa/model/AcceptVisitor.java | 18 - .../model/EntityPropertyChangeListener.java | 31 +- ...ventVisitor.java => EventAwareEntity.java} | 17 +- .../repository/jpa/model/JpaAction.java | 373 +++++----- .../jpa/model/JpaDistributionSet.java | 602 ++++++++-------- .../repository/jpa/model/JpaRollout.java | 423 +++++------ .../repository/jpa/model/JpaRolloutGroup.java | 500 ++++++------- .../repository/jpa/model/JpaTarget.java | 491 +++++++------ .../repository/jpa/model/JpaTargetInfo.java | 668 +++++++++--------- .../helper/EntityPropertyChangeHelper.java | 42 ++ 12 files changed, 1673 insertions(+), 1687 deletions(-) delete mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java delete mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java rename hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/{AbstractDescriptorEventVisitor.java => EventAwareEntity.java} (53%) create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java deleted file mode 100644 index 8755f8051..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitorImpl.java +++ /dev/null @@ -1,189 +0,0 @@ -/** - * 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.jpa.model; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Map; -import java.util.stream.Collectors; - -import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; -import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; -import org.eclipse.hawkbit.repository.jpa.executor.AfterTransactionCommitExecutor; -import org.eclipse.hawkbit.repository.jpa.model.DescriptorEventDetails.ActionType; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; -import org.eclipse.persistence.descriptors.DescriptorEvent; -import org.eclipse.persistence.internal.sessions.ObjectChangeSet; -import org.eclipse.persistence.queries.UpdateObjectQuery; -import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.google.common.eventbus.EventBus; - -/** - * Implementation of @link{AbstractDescriptorEventVisitor} .Publishes the - * appropriate event after any action on entity like create/update. - * - */ -public class AbstractDescriptorEventVisitorImpl implements - AbstractDescriptorEventVisitor { - - private static final String COMPLETE = "complete"; - private static final Logger LOG = LoggerFactory - .getLogger(AbstractDescriptorEventVisitorImpl.class); - - @Override - public void publishEventPostAction(final DescriptorEventDetails event) { - Method method = null; - DescriptorEvent descriptorEvent = event.getDescriptorEvent(); - ActionType actiontype = event.getActiontype(); - try { - method = getMethod(descriptorEvent, actiontype); - if (method != null) { - method.invoke(this, descriptorEvent.getObject(), - descriptorEvent); - } - } catch (NoSuchMethodException | SecurityException - | IllegalAccessException | IllegalArgumentException - | InvocationTargetException e) { - LOG.info( - "Exception when invoking approriate method to publis event {}", - e); - } - } - - private Method getMethod(DescriptorEvent descriptorEvent, - ActionType actiontype) throws NoSuchMethodException { - if (actiontype == ActionType.UPDATE) { - return this.getClass().getMethod("publishEventAfterUpdate", - descriptorEvent.getObject().getClass(), - DescriptorEvent.class); - } else if (actiontype == ActionType.CREATE) { - return this.getClass().getMethod("publishEventAfterCreate", - descriptorEvent.getObject().getClass(), - DescriptorEvent.class); - } - return null; - } - - public void publishEventAfterCreate(JpaAction action, DescriptorEvent event) { - if (action.getRollout() != null) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post(new ActionCreatedEvent(action))); - } - } - - public void publishEventAfterCreate(JpaTarget target, DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post(new TargetCreatedEvent(target))); - } - - public void publishEventAfterCreate(JpaDistributionSet ds, - DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post(new DistributionCreatedEvent(ds))); - - } - - public void publishEventAfterUpdate(JpaAction action, DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post( - new ActionPropertyChangeEvent(action, getChangeSet( - Action.class, event)))); - } - - public void publishEventAfterUpdate(JpaTarget target, DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post(new TargetUpdatedEvent(target))); - } - - public void publishEventAfterUpdate(JpaTargetInfo targetInfo, - DescriptorEvent event) { - getAfterTransactionCommmitExecutor() - .afterCommit( - () -> getEventBus().post( - new TargetInfoUpdateEvent(targetInfo))); - } - - public void publishEventAfterUpdate(JpaRollout entity, DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post( - new RolloutPropertyChangeEvent(entity, getChangeSet( - Rollout.class, event)))); - } - - public void publishEventAfterUpdate(JpaRolloutGroup entity, - DescriptorEvent event) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post( - new RolloutGroupPropertyChangeEvent(entity, - getChangeSet(RolloutGroup.class, event)))); - - } - - public void publishEventAfterUpdate(JpaDistributionSet entity, - DescriptorEvent event) { - Map.Values> changeSet = getChangeSet( - JpaDistributionSet.class, event); - if (changeSet.containsKey(COMPLETE) - && changeSet.get(COMPLETE).getOldValue().equals(false) - && changeSet.get(COMPLETE).getNewValue().equals(true)) { - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus().post( - new DistributionCreatedEvent(entity))); - } - - getAfterTransactionCommmitExecutor().afterCommit( - () -> getEventBus() - .post(new DistributionSetUpdateEvent(entity))); - - } - - private Map.Values> getChangeSet( - final Class clazz, final DescriptorEvent event) { - final T rolloutGroup = clazz.cast(event.getObject()); - final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()) - .getObjectChangeSet(); - return changeSet - .getChanges() - .stream() - .filter(record -> record instanceof DirectToFieldChangeRecord) - .map(record -> (DirectToFieldChangeRecord) record) - .collect( - Collectors.toMap( - record -> record.getAttribute(), - record -> new AbstractPropertyChangeEvent( - rolloutGroup, null).new Values(record - .getOldValue(), record.getNewValue()))); - } - - private AfterTransactionCommitExecutor getAfterTransactionCommmitExecutor() { - return AfterTransactionCommitExecutorHolder.getInstance() - .getAfterCommit(); - } - - private EventBus getEventBus() { - return EventBusHolder.getInstance().getEventBus(); - } - -} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index 2785676fb..c2e91afea 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -32,7 +32,7 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; @MappedSuperclass @Access(AccessType.FIELD) @EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class }) -public abstract class AbstractJpaBaseEntity implements BaseEntity,AcceptVisitor { +public abstract class AbstractJpaBaseEntity implements BaseEntity { private static final long serialVersionUID = 1L; @Id @@ -179,8 +179,4 @@ public abstract class AbstractJpaBaseEntity implements BaseEntity,AcceptVisitor } - @Override - public void postActionOnEntity(AbstractDescriptorEventVisitor visitor, DescriptorEventDetails eventDetails){ - visitor.publishEventPostAction(eventDetails); - } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java deleted file mode 100644 index 78d89219b..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AcceptVisitor.java +++ /dev/null @@ -1,18 +0,0 @@ -/** - * 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.jpa.model; - -/** - * Interface to accept visitor @link{AbstractDescriptorEventVisitor}. - * - */ -public interface AcceptVisitor { - public void postActionOnEntity(AbstractDescriptorEventVisitor visitor, - DescriptorEventDetails eventDetails); -} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java index bdb366edb..df36309df 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.repository.jpa.model; -import org.eclipse.hawkbit.repository.jpa.model.DescriptorEventDetails.ActionType; import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.descriptors.DescriptorEventAdapter; @@ -18,19 +17,23 @@ import org.eclipse.persistence.descriptors.DescriptorEventAdapter; */ public class EntityPropertyChangeListener extends DescriptorEventAdapter { - @Override - public void postInsert(final DescriptorEvent event) { - AbstractDescriptorEventVisitor visitor = new AbstractDescriptorEventVisitorImpl(); - ((AbstractJpaBaseEntity) event.getObject()).postActionOnEntity(visitor, - new DescriptorEventDetails(ActionType.CREATE, event)); + @Override + public void postInsert(final DescriptorEvent event) { + + final Object object = event.getObject(); + if (object instanceof EventAwareEntity) { + ((EventAwareEntity) object).fireCreateEvent(object,event); + } + } + + @Override + public void postUpdate(final DescriptorEvent event) { + + final Object object = event.getObject(); + if (object instanceof EventAwareEntity) { + ((EventAwareEntity) object).fireUpdateEvent(object,event); + } + } - } - @Override - public void postUpdate(final DescriptorEvent event) { - AbstractDescriptorEventVisitor visitor = new AbstractDescriptorEventVisitorImpl(); - ((AbstractJpaBaseEntity) event.getObject()).postActionOnEntity(visitor, - new DescriptorEventDetails(ActionType.UPDATE, event)); - } - } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java similarity index 53% rename from hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java rename to hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java index ce32b025f..2c1fe51d2 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractDescriptorEventVisitor.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java @@ -8,12 +8,13 @@ */ package org.eclipse.hawkbit.repository.jpa.model; -/** - * - * Interface defining the action to be performed after entity is - * created/updated. - * - */ -public interface AbstractDescriptorEventVisitor { - void publishEventPostAction(DescriptorEventDetails eventDetails); +import org.eclipse.persistence.descriptors.DescriptorEvent; + +public interface EventAwareEntity { + + public void fireCreateEvent(T t,DescriptorEvent descriptorEvent); + + public void fireUpdateEvent(T t,DescriptorEvent descriptorEvent); + + public void fireDeleteEvent(T t,DescriptorEvent descriptorEvent); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java index 5fa2c3bed..fc879aa87 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java @@ -1,174 +1,199 @@ -/** - * 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.jpa.model; - -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.NamedEntityGraphs; -import javax.persistence.NamedSubgraph; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.ActionStatus; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.persistence.annotations.CascadeOnDelete; - -/** - * JPA implementation of {@link Action}. - */ -@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"), - @Index(name = "sp_idx_action_02", columnList = "tenant,target,active"), - @Index(name = "sp_idx_action_prim", columnList = "tenant,id") }) -@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }), - @NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"), - @NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) }) -@Entity -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action { - private static final long serialVersionUID = 1L; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds")) - private JpaDistributionSet distributionSet; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target")) - private JpaTarget target; - - @Column(name = "active") - private boolean active; - - @Column(name = "action_type", nullable = false) - @Enumerated(EnumType.STRING) - private ActionType actionType; - - @Column(name = "forced_time") - private long forcedTime; - - @Column(name = "status") - private Status status; - - @CascadeOnDelete - @OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = { - CascadeType.REMOVE }) - private List actionStatus; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup")) - private JpaRolloutGroup rolloutGroup; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) - private JpaRollout rollout; - - @Override - public DistributionSet getDistributionSet() { - return distributionSet; - } - - @Override - public void setDistributionSet(final DistributionSet distributionSet) { - this.distributionSet = (JpaDistributionSet) distributionSet; - } - - public void setActive(final boolean active) { - this.active = active; - } - - @Override - public Status getStatus() { - return status; - } - - @Override - public void setStatus(final Status status) { - this.status = status; - } - - @Override - public boolean isActive() { - return active; - } - - public void setActionType(final ActionType actionType) { - this.actionType = actionType; - } - - @Override - public ActionType getActionType() { - return actionType; - } - - @Override - public List getActionStatus() { - return actionStatus; - } - - @Override - public void setTarget(final Target target) { - this.target = (JpaTarget) target; - } - - @Override - public Target getTarget() { - return target; - } - - @Override - public long getForcedTime() { - return forcedTime; - } - - public void setForcedTime(final long forcedTime) { - this.forcedTime = forcedTime; - } - - @Override - public RolloutGroup getRolloutGroup() { - return rolloutGroup; - } - - public void setRolloutGroup(final RolloutGroup rolloutGroup) { - this.rolloutGroup = (JpaRolloutGroup) rolloutGroup; - } - - @Override - public Rollout getRollout() { - return rollout; - } - - public void setRollout(final Rollout rollout) { - this.rollout = (JpaRollout) rollout; - } - - @Override - public String toString() { - return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]"; - } - -} +/** + * 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.jpa.model; + +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.NamedEntityGraphs; +import javax.persistence.NamedSubgraph; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.ActionStatus; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA implementation of {@link Action}. + */ +@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"), + @Index(name = "sp_idx_action_02", columnList = "tenant,target,active"), + @Index(name = "sp_idx_action_prim", columnList = "tenant,id") }) +@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }), + @NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"), + @NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) }) +@Entity +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action,EventAwareEntity { + private static final long serialVersionUID = 1L; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds")) + private JpaDistributionSet distributionSet; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target")) + private JpaTarget target; + + @Column(name = "active") + private boolean active; + + @Column(name = "action_type", nullable = false) + @Enumerated(EnumType.STRING) + private ActionType actionType; + + @Column(name = "forced_time") + private long forcedTime; + + @Column(name = "status") + private Status status; + + @CascadeOnDelete + @OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = { + CascadeType.REMOVE }) + private List actionStatus; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup")) + private JpaRolloutGroup rolloutGroup; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) + private JpaRollout rollout; + + @Override + public DistributionSet getDistributionSet() { + return distributionSet; + } + + @Override + public void setDistributionSet(final DistributionSet distributionSet) { + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + public void setActive(final boolean active) { + this.active = active; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public void setStatus(final Status status) { + this.status = status; + } + + @Override + public boolean isActive() { + return active; + } + + public void setActionType(final ActionType actionType) { + this.actionType = actionType; + } + + @Override + public ActionType getActionType() { + return actionType; + } + + @Override + public List getActionStatus() { + return actionStatus; + } + + @Override + public void setTarget(final Target target) { + this.target = (JpaTarget) target; + } + + @Override + public Target getTarget() { + return target; + } + + @Override + public long getForcedTime() { + return forcedTime; + } + + public void setForcedTime(final long forcedTime) { + this.forcedTime = forcedTime; + } + + @Override + public RolloutGroup getRolloutGroup() { + return rolloutGroup; + } + + public void setRolloutGroup(final RolloutGroup rolloutGroup) { + this.rolloutGroup = (JpaRolloutGroup) rolloutGroup; + } + + @Override + public Rollout getRollout() { + return rollout; + } + + public void setRollout(final Rollout rollout) { + this.rollout = (JpaRollout) rollout; + } + + @Override + public String toString() { + return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); + + } + + @Override + public void fireUpdateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus(). + post(new ActionPropertyChangeEvent(jpaAction, EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); + + } + + + @Override + public void fireDeleteEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index 676215424..af8984286 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -1,282 +1,320 @@ -/** - * 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.jpa.model; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; -import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; -import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.persistence.annotations.CascadeOnDelete; - -/** - * Jpa implementation of {@link DistributionSet}. - * - */ -@Entity -@Table(name = "sp_distribution_set", uniqueConstraints = { - @UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = { - @Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"), - @Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"), - @Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") }) -@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"), - @NamedAttributeNode("tags"), @NamedAttributeNode("type") }) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet { - private static final long serialVersionUID = 1L; - - @Column(name = "required_migration_step") - private boolean requiredMigrationStep; - - @ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY) - @JoinTable(name = "sp_ds_module", joinColumns = { - @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = { - @JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) }) - private final Set modules = new HashSet<>(); - - @ManyToMany(targetEntity = JpaDistributionSetTag.class) - @JoinTable(name = "sp_ds_dstag", joinColumns = { - @JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = { - @JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) }) - private Set tags = new HashSet<>(); - - @Column(name = "deleted") - private boolean deleted; - - @OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY) - private List assignedToTargets; - - @OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY) - private List installedAtTargets; - - @OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY) - private List actions; - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = { - CascadeType.REMOVE }) - @JoinColumn(name = "ds_id", insertable = false, updatable = false) - private final List metadata = new ArrayList<>(); - - @ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class) - @JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) - private DistributionSetType type; - - @Column(name = "complete") - private boolean complete; - - /** - * Default constructor. - */ - public JpaDistributionSet() { - super(); - } - - /** - * Parameterized constructor. - * - * @param name - * of the {@link DistributionSet} - * @param version - * of the {@link DistributionSet} - * @param description - * of the {@link DistributionSet} - * @param type - * of the {@link DistributionSet} - * @param moduleList - * {@link SoftwareModule}s of the {@link DistributionSet} - */ - public JpaDistributionSet(final String name, final String version, final String description, - final DistributionSetType type, final Collection moduleList) { - super(name, version, description); - - this.type = type; - if (moduleList != null) { - moduleList.forEach(this::addModule); - } - if (this.type != null) { - complete = this.type.checkComplete(this); - } - } - - @Override - public Set getTags() { - return tags; - } - - @Override - public boolean isDeleted() { - return deleted; - } - - @Override - public List getMetadata() { - return Collections.unmodifiableList(metadata); - } - - public List getActions() { - return actions; - } - - @Override - public boolean isRequiredMigrationStep() { - return requiredMigrationStep; - } - - @Override - public DistributionSet setDeleted(final boolean deleted) { - this.deleted = deleted; - return this; - } - - @Override - public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) { - requiredMigrationStep = isRequiredMigrationStep; - return this; - } - - public DistributionSet setTags(final Set tags) { - this.tags = tags; - return this; - } - - @Override - public List getAssignedTargets() { - return assignedToTargets; - } - - @Override - public List getInstalledTargets() { - return installedAtTargets; - } - - @Override - public String toString() { - return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision() - + ", getId()=" + getId() + "]"; - } - - @Override - public Set getModules() { - return Collections.unmodifiableSet(modules); - } - - @Override - public boolean addModule(final SoftwareModule softwareModule) { - - // we cannot allow that modules are added without a type defined - if (type == null) { - throw new DistributionSetTypeUndefinedException(); - } - - // check if it is allowed to such a module to this DS type - if (!type.containsModuleType(softwareModule.getType())) { - throw new UnsupportedSoftwareModuleForThisDistributionSetException(); - } - - final Optional found = modules.stream() - .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); - - if (found.isPresent()) { - return false; - } - - final long allready = modules.stream() - .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count(); - - if (allready >= softwareModule.getType().getMaxAssignments()) { - final Optional sameKey = modules.stream() - .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst(); - modules.remove(sameKey.get()); - } - - if (modules.add(softwareModule)) { - complete = type.checkComplete(this); - return true; - } - - return false; - } - - @Override - public boolean removeModule(final SoftwareModule softwareModule) { - final Optional found = modules.stream() - .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); - - if (found.isPresent()) { - modules.remove(found.get()); - complete = type.checkComplete(this); - return true; - } - - return false; - - } - - @Override - public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) { - final Optional result = modules.stream().filter(module -> module.getType().equals(type)) - .findFirst(); - - if (result.isPresent()) { - return result.get(); - } - - return null; - } - - @Override - public DistributionSetType getType() { - return type; - } - - @Override - public void setType(final DistributionSetType type) { - this.type = type; - } - - @Override - public boolean isComplete() { - return complete; - } - -} +/** + * 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.jpa.model; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; +import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; +import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * Jpa implementation of {@link DistributionSet}. + * + */ +@Entity +@Table(name = "sp_distribution_set", uniqueConstraints = { + @UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = { + @Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"), + @Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"), + @Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") }) +@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"), + @NamedAttributeNode("tags"), @NamedAttributeNode("type") }) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet,EventAwareEntity { + private static final long serialVersionUID = 1L; + + private static final String COMPLETE = "complete"; + + @Column(name = "required_migration_step") + private boolean requiredMigrationStep; + + @ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY) + @JoinTable(name = "sp_ds_module", joinColumns = { + @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = { + @JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) }) + private final Set modules = new HashSet<>(); + + @ManyToMany(targetEntity = JpaDistributionSetTag.class) + @JoinTable(name = "sp_ds_dstag", joinColumns = { + @JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = { + @JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) }) + private Set tags = new HashSet<>(); + + @Column(name = "deleted") + private boolean deleted; + + @OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY) + private List assignedToTargets; + + @OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY) + private List installedAtTargets; + + @OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY) + private List actions; + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = { + CascadeType.REMOVE }) + @JoinColumn(name = "ds_id", insertable = false, updatable = false) + private final List metadata = new ArrayList<>(); + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class) + @JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) + private DistributionSetType type; + + @Column(name = "complete") + private boolean complete; + + /** + * Default constructor. + */ + public JpaDistributionSet() { + super(); + } + + /** + * Parameterized constructor. + * + * @param name + * of the {@link DistributionSet} + * @param version + * of the {@link DistributionSet} + * @param description + * of the {@link DistributionSet} + * @param type + * of the {@link DistributionSet} + * @param moduleList + * {@link SoftwareModule}s of the {@link DistributionSet} + */ + public JpaDistributionSet(final String name, final String version, final String description, + final DistributionSetType type, final Collection moduleList) { + super(name, version, description); + + this.type = type; + if (moduleList != null) { + moduleList.forEach(this::addModule); + } + if (this.type != null) { + complete = this.type.checkComplete(this); + } + } + + @Override + public Set getTags() { + return tags; + } + + @Override + public boolean isDeleted() { + return deleted; + } + + @Override + public List getMetadata() { + return Collections.unmodifiableList(metadata); + } + + public List getActions() { + return actions; + } + + @Override + public boolean isRequiredMigrationStep() { + return requiredMigrationStep; + } + + @Override + public DistributionSet setDeleted(final boolean deleted) { + this.deleted = deleted; + return this; + } + + @Override + public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) { + requiredMigrationStep = isRequiredMigrationStep; + return this; + } + + public DistributionSet setTags(final Set tags) { + this.tags = tags; + return this; + } + + @Override + public List getAssignedTargets() { + return assignedToTargets; + } + + @Override + public List getInstalledTargets() { + return installedAtTargets; + } + + @Override + public String toString() { + return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision() + + ", getId()=" + getId() + "]"; + } + + @Override + public Set getModules() { + return Collections.unmodifiableSet(modules); + } + + @Override + public boolean addModule(final SoftwareModule softwareModule) { + + // we cannot allow that modules are added without a type defined + if (type == null) { + throw new DistributionSetTypeUndefinedException(); + } + + // check if it is allowed to such a module to this DS type + if (!type.containsModuleType(softwareModule.getType())) { + throw new UnsupportedSoftwareModuleForThisDistributionSetException(); + } + + final Optional found = modules.stream() + .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); + + if (found.isPresent()) { + return false; + } + + final long allready = modules.stream() + .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count(); + + if (allready >= softwareModule.getType().getMaxAssignments()) { + final Optional sameKey = modules.stream() + .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst(); + modules.remove(sameKey.get()); + } + + if (modules.add(softwareModule)) { + complete = type.checkComplete(this); + return true; + } + + return false; + } + + @Override + public boolean removeModule(final SoftwareModule softwareModule) { + final Optional found = modules.stream() + .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); + + if (found.isPresent()) { + modules.remove(found.get()); + complete = type.checkComplete(this); + return true; + } + + return false; + + } + + @Override + public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) { + final Optional result = modules.stream().filter(module -> module.getType().equals(type)) + .findFirst(); + + if (result.isPresent()) { + return result.get(); + } + + return null; + } + + @Override + public DistributionSetType getType() { + return type; + } + + @Override + public void setType(final DistributionSetType type) { + this.type = type; + } + + @Override + public boolean isComplete() { + return complete; + } + + @Override + public void fireCreateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); + + } + + @Override + public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + final Map.Values> changeSet = EntityPropertyChangeHelper.getChangeSet( + JpaDistributionSet.class, descriptorEvent); + if (changeSet.containsKey(COMPLETE) + && changeSet.get(COMPLETE).getOldValue().equals(false) + && changeSet.get(COMPLETE).getNewValue().equals(true)) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post( + new DistributionCreatedEvent(jpaDistributionSet))); + } + + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); + + } + + @Override + public void fireDeleteEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java index 3cbe65717..73d19086d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java @@ -1,200 +1,223 @@ -/** - * 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.jpa.model; - -import java.util.List; - -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.jpa.cache.CacheField; -import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; -import org.eclipse.hawkbit.repository.model.Action.ActionType; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; - -/** - * JPA implementation of a {@link Rollout}. - * - */ -@Entity -@Table(name = "sp_rollout", indexes = { - @Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "tenant" }, name = "uk_rollout")) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaRollout extends AbstractJpaNamedEntity implements Rollout { - - private static final long serialVersionUID = 1L; - - @OneToMany(targetEntity = JpaRolloutGroup.class) - @JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup")) - private List rolloutGroups; - - @Column(name = "target_filter", length = 1024, nullable = false) - private String targetFilterQuery; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds")) - private JpaDistributionSet distributionSet; - - @Column(name = "status") - private RolloutStatus status = RolloutStatus.CREATING; - - @Column(name = "last_check") - private long lastCheck; - - @Column(name = "action_type", nullable = false) - @Enumerated(EnumType.STRING) - private ActionType actionType = ActionType.FORCED; - - @Column(name = "forced_time") - private long forcedTime; - - @Column(name = "total_targets") - private long totalTargets; - - @Transient - @CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL) - private int rolloutGroupsTotal; - - @Transient - @CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED) - private int rolloutGroupsCreated; - - @Transient - private transient TotalTargetCountStatus totalTargetCountStatus; - - @Override - public DistributionSet getDistributionSet() { - return distributionSet; - } - - @Override - public void setDistributionSet(final DistributionSet distributionSet) { - this.distributionSet = (JpaDistributionSet) distributionSet; - } - - @Override - public List getRolloutGroups() { - return rolloutGroups; - } - - public void setRolloutGroups(final List rolloutGroups) { - this.rolloutGroups = rolloutGroups; - } - - @Override - public String getTargetFilterQuery() { - return targetFilterQuery; - } - - @Override - public void setTargetFilterQuery(final String targetFilterQuery) { - this.targetFilterQuery = targetFilterQuery; - } - - @Override - public RolloutStatus getStatus() { - return status; - } - - public void setStatus(final RolloutStatus status) { - this.status = status; - } - - public long getLastCheck() { - return lastCheck; - } - - public void setLastCheck(final long lastCheck) { - this.lastCheck = lastCheck; - } - - @Override - public ActionType getActionType() { - return actionType; - } - - @Override - public void setActionType(final ActionType actionType) { - this.actionType = actionType; - } - - @Override - public long getForcedTime() { - return forcedTime; - } - - @Override - public void setForcedTime(final long forcedTime) { - this.forcedTime = forcedTime; - } - - @Override - public long getTotalTargets() { - return totalTargets; - } - - public void setTotalTargets(final long totalTargets) { - this.totalTargets = totalTargets; - } - - public int getRolloutGroupsTotal() { - return rolloutGroupsTotal; - } - - public void setRolloutGroupsTotal(final int rolloutGroupsTotal) { - this.rolloutGroupsTotal = rolloutGroupsTotal; - } - - @Override - public int getRolloutGroupsCreated() { - return rolloutGroupsCreated; - } - - public void setRolloutGroupsCreated(final int rolloutGroupsCreated) { - this.rolloutGroupsCreated = rolloutGroupsCreated; - } - - @Override - public TotalTargetCountStatus getTotalTargetCountStatus() { - if (totalTargetCountStatus == null) { - totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); - } - return totalTargetCountStatus; - } - - public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { - this.totalTargetCountStatus = totalTargetCountStatus; - } - - @Override - public String toString() { - return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery - + ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck - + ", getName()=" + getName() + ", getId()=" + getId() + "]"; - } - -} +/** + * 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.jpa.model; + +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.cache.CacheField; +import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action.ActionType; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA implementation of a {@link Rollout}. + * + */ +@Entity +@Table(name = "sp_rollout", indexes = { + @Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "tenant" }, name = "uk_rollout")) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaRollout extends AbstractJpaNamedEntity implements Rollout,EventAwareEntity { + + private static final long serialVersionUID = 1L; + + @OneToMany(targetEntity = JpaRolloutGroup.class) + @JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup")) + private List rolloutGroups; + + @Column(name = "target_filter", length = 1024, nullable = false) + private String targetFilterQuery; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds")) + private JpaDistributionSet distributionSet; + + @Column(name = "status") + private RolloutStatus status = RolloutStatus.CREATING; + + @Column(name = "last_check") + private long lastCheck; + + @Column(name = "action_type", nullable = false) + @Enumerated(EnumType.STRING) + private ActionType actionType = ActionType.FORCED; + + @Column(name = "forced_time") + private long forcedTime; + + @Column(name = "total_targets") + private long totalTargets; + + @Transient + @CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL) + private int rolloutGroupsTotal; + + @Transient + @CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED) + private int rolloutGroupsCreated; + + @Transient + private transient TotalTargetCountStatus totalTargetCountStatus; + + @Override + public DistributionSet getDistributionSet() { + return distributionSet; + } + + @Override + public void setDistributionSet(final DistributionSet distributionSet) { + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + @Override + public List getRolloutGroups() { + return rolloutGroups; + } + + public void setRolloutGroups(final List rolloutGroups) { + this.rolloutGroups = rolloutGroups; + } + + @Override + public String getTargetFilterQuery() { + return targetFilterQuery; + } + + @Override + public void setTargetFilterQuery(final String targetFilterQuery) { + this.targetFilterQuery = targetFilterQuery; + } + + @Override + public RolloutStatus getStatus() { + return status; + } + + public void setStatus(final RolloutStatus status) { + this.status = status; + } + + public long getLastCheck() { + return lastCheck; + } + + public void setLastCheck(final long lastCheck) { + this.lastCheck = lastCheck; + } + + @Override + public ActionType getActionType() { + return actionType; + } + + @Override + public void setActionType(final ActionType actionType) { + this.actionType = actionType; + } + + @Override + public long getForcedTime() { + return forcedTime; + } + + @Override + public void setForcedTime(final long forcedTime) { + this.forcedTime = forcedTime; + } + + @Override + public long getTotalTargets() { + return totalTargets; + } + + public void setTotalTargets(final long totalTargets) { + this.totalTargets = totalTargets; + } + + public int getRolloutGroupsTotal() { + return rolloutGroupsTotal; + } + + public void setRolloutGroupsTotal(final int rolloutGroupsTotal) { + this.rolloutGroupsTotal = rolloutGroupsTotal; + } + + @Override + public int getRolloutGroupsCreated() { + return rolloutGroupsCreated; + } + + public void setRolloutGroupsCreated(final int rolloutGroupsCreated) { + this.rolloutGroupsCreated = rolloutGroupsCreated; + } + + @Override + public TotalTargetCountStatus getTotalTargetCountStatus() { + if (totalTargetCountStatus == null) { + totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); + } + return totalTargetCountStatus; + } + + public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { + this.totalTargetCountStatus = totalTargetCountStatus; + } + + @Override + public String toString() { + return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery + + ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck + + ", getName()=" + getName() + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + + } + + @Override + public void fireUpdateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). + post(new RolloutPropertyChangeEvent(jpaRollout, EntityPropertyChangeHelper.getChangeSet( + Rollout.class, descriptorEvent)))); + + } + + @Override + public void fireDeleteEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java index 79da6630a..6456a3e93 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java @@ -1,239 +1,261 @@ -/** - * 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.jpa.model; - -import java.util.ArrayList; -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; - -/** - * JPA entity definition of persisting a group of an rollout. - * - */ -@Entity -@Table(name = "sp_rolloutgroup", indexes = { - @Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "rollout", "tenant" }, name = "uk_rolloutgroup")) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup { - - private static final long serialVersionUID = 1L; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout")) - private JpaRollout rollout; - - @Column(name = "status") - private RolloutGroupStatus status = RolloutGroupStatus.READY; - - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class) - @JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false) - private final List rolloutTargetGroup = new ArrayList<>(); - - @ManyToOne(fetch = FetchType.LAZY) - private JpaRolloutGroup parent; - - @Column(name = "success_condition", nullable = false) - private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD; - - @Column(name = "success_condition_exp", length = 512, nullable = false) - private String successConditionExp; - - @Column(name = "success_action", nullable = false) - private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP; - - @Column(name = "success_action_exp", length = 512, nullable = false) - private String successActionExp; - - @Column(name = "error_condition") - private RolloutGroupErrorCondition errorCondition; - - @Column(name = "error_condition_exp", length = 512) - private String errorConditionExp; - - @Column(name = "error_action") - private RolloutGroupErrorAction errorAction; - - @Column(name = "error_action_exp", length = 512) - private String errorActionExp; - - @Column(name = "total_targets") - private long totalTargets; - - @Transient - private transient TotalTargetCountStatus totalTargetCountStatus; - - @Override - public Rollout getRollout() { - return rollout; - } - - @Override - public void setRollout(final Rollout rollout) { - this.rollout = (JpaRollout) rollout; - } - - @Override - public RolloutGroupStatus getStatus() { - return status; - } - - @Override - public void setStatus(final RolloutGroupStatus status) { - this.status = status; - } - - public List getRolloutTargetGroup() { - return rolloutTargetGroup; - } - - @Override - public RolloutGroup getParent() { - return parent; - } - - public void setParent(final RolloutGroup parent) { - this.parent = (JpaRolloutGroup) parent; - } - - @Override - public RolloutGroupSuccessCondition getSuccessCondition() { - return successCondition; - } - - @Override - public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { - successCondition = finishCondition; - } - - @Override - public String getSuccessConditionExp() { - return successConditionExp; - } - - @Override - public void setSuccessConditionExp(final String finishExp) { - successConditionExp = finishExp; - } - - @Override - public RolloutGroupErrorCondition getErrorCondition() { - return errorCondition; - } - - @Override - public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { - this.errorCondition = errorCondition; - } - - @Override - public String getErrorConditionExp() { - return errorConditionExp; - } - - @Override - public void setErrorConditionExp(final String errorExp) { - errorConditionExp = errorExp; - } - - @Override - public RolloutGroupErrorAction getErrorAction() { - return errorAction; - } - - @Override - public void setErrorAction(final RolloutGroupErrorAction errorAction) { - this.errorAction = errorAction; - } - - @Override - public String getErrorActionExp() { - return errorActionExp; - } - - @Override - public void setErrorActionExp(final String errorActionExp) { - this.errorActionExp = errorActionExp; - } - - @Override - public RolloutGroupSuccessAction getSuccessAction() { - return successAction; - } - - @Override - public String getSuccessActionExp() { - return successActionExp; - } - - @Override - public long getTotalTargets() { - return totalTargets; - } - - public void setTotalTargets(final long totalTargets) { - this.totalTargets = totalTargets; - } - - public void setSuccessAction(final RolloutGroupSuccessAction successAction) { - this.successAction = successAction; - } - - public void setSuccessActionExp(final String successActionExp) { - this.successActionExp = successActionExp; - } - - /** - * @return the totalTargetCountStatus - */ - @Override - public TotalTargetCountStatus getTotalTargetCountStatus() { - if (totalTargetCountStatus == null) { - totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); - } - return totalTargetCountStatus; - } - - /** - * @param totalTargetCountStatus - * the totalTargetCountStatus to set - */ - @Override - public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { - this.totalTargetCountStatus = totalTargetCountStatus; - } - - @Override - public String toString() { - return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup - + ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp - + ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName() - + ", getId()=" + getId() + "]"; - } - -} +/** + * 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.jpa.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA entity definition of persisting a group of an rollout. + * + */ +@Entity +@Table(name = "sp_rolloutgroup", indexes = { + @Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "rollout", "tenant" }, name = "uk_rolloutgroup")) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup,EventAwareEntity { + + private static final long serialVersionUID = 1L; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout")) + private JpaRollout rollout; + + @Column(name = "status") + private RolloutGroupStatus status = RolloutGroupStatus.READY; + + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class) + @JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false) + private final List rolloutTargetGroup = new ArrayList<>(); + + @ManyToOne(fetch = FetchType.LAZY) + private JpaRolloutGroup parent; + + @Column(name = "success_condition", nullable = false) + private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD; + + @Column(name = "success_condition_exp", length = 512, nullable = false) + private String successConditionExp; + + @Column(name = "success_action", nullable = false) + private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP; + + @Column(name = "success_action_exp", length = 512, nullable = false) + private String successActionExp; + + @Column(name = "error_condition") + private RolloutGroupErrorCondition errorCondition; + + @Column(name = "error_condition_exp", length = 512) + private String errorConditionExp; + + @Column(name = "error_action") + private RolloutGroupErrorAction errorAction; + + @Column(name = "error_action_exp", length = 512) + private String errorActionExp; + + @Column(name = "total_targets") + private long totalTargets; + + @Transient + private transient TotalTargetCountStatus totalTargetCountStatus; + + @Override + public Rollout getRollout() { + return rollout; + } + + @Override + public void setRollout(final Rollout rollout) { + this.rollout = (JpaRollout) rollout; + } + + @Override + public RolloutGroupStatus getStatus() { + return status; + } + + @Override + public void setStatus(final RolloutGroupStatus status) { + this.status = status; + } + + public List getRolloutTargetGroup() { + return rolloutTargetGroup; + } + + @Override + public RolloutGroup getParent() { + return parent; + } + + public void setParent(final RolloutGroup parent) { + this.parent = (JpaRolloutGroup) parent; + } + + @Override + public RolloutGroupSuccessCondition getSuccessCondition() { + return successCondition; + } + + @Override + public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { + successCondition = finishCondition; + } + + @Override + public String getSuccessConditionExp() { + return successConditionExp; + } + + @Override + public void setSuccessConditionExp(final String finishExp) { + successConditionExp = finishExp; + } + + @Override + public RolloutGroupErrorCondition getErrorCondition() { + return errorCondition; + } + + @Override + public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { + this.errorCondition = errorCondition; + } + + @Override + public String getErrorConditionExp() { + return errorConditionExp; + } + + @Override + public void setErrorConditionExp(final String errorExp) { + errorConditionExp = errorExp; + } + + @Override + public RolloutGroupErrorAction getErrorAction() { + return errorAction; + } + + @Override + public void setErrorAction(final RolloutGroupErrorAction errorAction) { + this.errorAction = errorAction; + } + + @Override + public String getErrorActionExp() { + return errorActionExp; + } + + @Override + public void setErrorActionExp(final String errorActionExp) { + this.errorActionExp = errorActionExp; + } + + @Override + public RolloutGroupSuccessAction getSuccessAction() { + return successAction; + } + + @Override + public String getSuccessActionExp() { + return successActionExp; + } + + @Override + public long getTotalTargets() { + return totalTargets; + } + + public void setTotalTargets(final long totalTargets) { + this.totalTargets = totalTargets; + } + + public void setSuccessAction(final RolloutGroupSuccessAction successAction) { + this.successAction = successAction; + } + + public void setSuccessActionExp(final String successActionExp) { + this.successActionExp = successActionExp; + } + + /** + * @return the totalTargetCountStatus + */ + @Override + public TotalTargetCountStatus getTotalTargetCountStatus() { + if (totalTargetCountStatus == null) { + totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); + } + return totalTargetCountStatus; + } + + /** + * @param totalTargetCountStatus + * the totalTargetCountStatus to set + */ + @Override + public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { + this.totalTargetCountStatus = totalTargetCountStatus; + } + + @Override + public String toString() { + return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup + + ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp + + ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName() + + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + + } + + @Override + public void fireUpdateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). + post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, + EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); + } + + @Override + public void fireDeleteEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index 183405470..f6a2b8346 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -1,234 +1,257 @@ -/** - * 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.jpa.model; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker; -import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetTag; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.springframework.data.domain.Persistable; - -/** - * JPA implementation of {@link Target}. - * - */ -@Entity -@Table(name = "sp_target", indexes = { - @Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"), - @Index(name = "sp_idx_target_02", columnList = "tenant,name"), - @Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"), - @Index(name = "sp_idx_target_04", columnList = "tenant,created_at"), - @Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "controller_id", "tenant" }, name = "uk_tenant_controller_id")) -@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"), - @NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") }) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target { - private static final long serialVersionUID = 1L; - - @Column(name = "controller_id", length = 64) - @Size(min = 1) - @NotNull - private String controllerId; - - @Transient - private boolean entityNew; - - @ManyToMany(targetEntity = JpaTargetTag.class) - @JoinTable(name = "sp_target_target_tag", joinColumns = { - @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { - @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) - private Set tags = new HashSet<>(); - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { - CascadeType.REMOVE }, targetEntity = JpaAction.class) - @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) - private final List actions = new ArrayList<>(); - - @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class) - @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) - private JpaDistributionSet assignedDistributionSet; - - @CascadeOnDelete - @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class) - @PrimaryKeyJoinColumn - private JpaTargetInfo targetInfo; - - /** - * the security token of the target which allows if enabled to authenticate - * with this security token. - */ - @Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128) - private String securityToken; - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) - @JoinColumn(name = "target_Id", insertable = false, updatable = false) - private final List rolloutTargetGroup = new ArrayList<>(); - - /** - * Constructor. - * - * @param controllerId - * controller ID of the {@link Target} - */ - public JpaTarget(final String controllerId) { - this(controllerId, SecurityTokenGeneratorHolder.getInstance().generateToken()); - } - - /** - * Constructor. - * - * @param controllerId - * controller ID of the {@link Target} - * @param securityToken - * for target authentication if enabled - */ - public JpaTarget(final String controllerId, final String securityToken) { - this.controllerId = controllerId; - setName(controllerId); - this.securityToken = securityToken; - targetInfo = new JpaTargetInfo(this); - } - - /** - * empty constructor for JPA. - */ - JpaTarget() { - controllerId = null; - securityToken = null; - } - - @Override - public DistributionSet getAssignedDistributionSet() { - return assignedDistributionSet; - } - - @Override - public String getControllerId() { - return controllerId; - } - - @Override - public Set getTags() { - return tags; - } - - public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) { - this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet; - } - - public void setControllerId(final String controllerId) { - this.controllerId = controllerId; - } - - public void setTags(final Set tags) { - this.tags = tags; - } - - @Override - public List getActions() { - return actions; - } - - @Override - @Transient - public boolean isNew() { - return entityNew; - } - - /** - * @param isNew - * the isNew to set - */ - public void setNew(final boolean entityNew) { - this.entityNew = entityNew; - } - - /** - * @return the targetInfo - */ - @Override - public TargetInfo getTargetInfo() { - return targetInfo; - } - - /** - * @param targetInfo - * the targetInfo to set - */ - public void setTargetInfo(final TargetInfo targetInfo) { - this.targetInfo = (JpaTargetInfo) targetInfo; - } - - /** - * @return the securityToken if the current security context contains the - * necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN} - * or the current context is executed as system code, otherwise - * {@code null}. - */ - @Override - public String getSecurityToken() { - if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode() - || SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { - return securityToken; - } - return null; - } - - /** - * @param securityToken - * the securityToken to set - */ - public void setSecurityToken(final String securityToken) { - this.securityToken = securityToken; - } - - @Override - public String toString() { - return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]"; - } - -} +/** + * 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.jpa.model; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import org.eclipse.hawkbit.im.authentication.SpPermission; +import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker; +import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.springframework.data.domain.Persistable; + +/** + * JPA implementation of {@link Target}. + * + */ +@Entity +@Table(name = "sp_target", indexes = { + @Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"), + @Index(name = "sp_idx_target_02", columnList = "tenant,name"), + @Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"), + @Index(name = "sp_idx_target_04", columnList = "tenant,created_at"), + @Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "controller_id", "tenant" }, name = "uk_tenant_controller_id")) +@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"), + @NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") }) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target, EventAwareEntity { + private static final long serialVersionUID = 1L; + + @Column(name = "controller_id", length = 64) + @Size(min = 1) + @NotNull + private String controllerId; + + @Transient + private boolean entityNew; + + @ManyToMany(targetEntity = JpaTargetTag.class) + @JoinTable(name = "sp_target_target_tag", joinColumns = { + @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { + @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) + private Set tags = new HashSet<>(); + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { + CascadeType.REMOVE }, targetEntity = JpaAction.class) + @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) + private final List actions = new ArrayList<>(); + + @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class) + @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) + private JpaDistributionSet assignedDistributionSet; + + @CascadeOnDelete + @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class) + @PrimaryKeyJoinColumn + private JpaTargetInfo targetInfo; + + /** + * the security token of the target which allows if enabled to authenticate + * with this security token. + */ + @Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128) + private String securityToken; + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) + @JoinColumn(name = "target_Id", insertable = false, updatable = false) + private final List rolloutTargetGroup = new ArrayList<>(); + + /** + * Constructor. + * + * @param controllerId + * controller ID of the {@link Target} + */ + public JpaTarget(final String controllerId) { + this(controllerId, SecurityTokenGeneratorHolder.getInstance().generateToken()); + } + + /** + * Constructor. + * + * @param controllerId + * controller ID of the {@link Target} + * @param securityToken + * for target authentication if enabled + */ + public JpaTarget(final String controllerId, final String securityToken) { + this.controllerId = controllerId; + setName(controllerId); + this.securityToken = securityToken; + targetInfo = new JpaTargetInfo(this); + } + + /** + * empty constructor for JPA. + */ + JpaTarget() { + controllerId = null; + securityToken = null; + } + + @Override + public DistributionSet getAssignedDistributionSet() { + return assignedDistributionSet; + } + + @Override + public String getControllerId() { + return controllerId; + } + + @Override + public Set getTags() { + return tags; + } + + public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) { + this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet; + } + + public void setControllerId(final String controllerId) { + this.controllerId = controllerId; + } + + public void setTags(final Set tags) { + this.tags = tags; + } + + @Override + public List getActions() { + return actions; + } + + @Override + @Transient + public boolean isNew() { + return entityNew; + } + + /** + * @param isNew + * the isNew to set + */ + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; + } + + /** + * @return the targetInfo + */ + @Override + public TargetInfo getTargetInfo() { + return targetInfo; + } + + /** + * @param targetInfo + * the targetInfo to set + */ + public void setTargetInfo(final TargetInfo targetInfo) { + this.targetInfo = (JpaTargetInfo) targetInfo; + } + + /** + * @return the securityToken if the current security context contains the + * necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN} + * or the current context is executed as system code, otherwise + * {@code null}. + */ + @Override + public String getSecurityToken() { + if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode() + || SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { + return securityToken; + } + return null; + } + + /** + * @param securityToken + * the securityToken to set + */ + @Override + public void setSecurityToken(final String securityToken) { + this.securityToken = securityToken; + } + + @Override + public String toString() { + return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); + } + + @Override + public void fireUpdateEvent(final JpaTarget jpaTarget,final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); + + } + + @Override + public void fireDeleteEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { + + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java index 0606def4f..a21c7547f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java @@ -1,324 +1,344 @@ -/** - * 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.jpa.model; - -import java.net.URI; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.persistence.CascadeType; -import javax.persistence.CollectionTable; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.MapKeyColumn; -import javax.persistence.MapsId; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.persistence.Transient; - -import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; -import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.PollStatus; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.domain.Persistable; - -/** - * A table which contains all the information inserted, updated by the - * controller itself. So this entity does not provide audit information because - * changes on this entity are mostly only done by controller requests. That's - * the reason that we store these information in a separated table so we don't - * modifying the {@link Target} itself when a controller reports it's - * {@link #lastTargetQuery} for example. - * - */ -@Table(name = "sp_target_info", indexes = { - @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) -@Entity -public class JpaTargetInfo implements Persistable, TargetInfo { - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); - - @Id - private Long targetId; - - @Transient - private boolean entityNew; - - @CascadeOnDelete - @OneToOne(cascade = { CascadeType.MERGE, - CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class) - @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ")) - @MapsId - private JpaTarget target; - - @Column(name = "address", length = 512) - private String address; - - @Column(name = "last_target_query") - private Long lastTargetQuery; - - @Column(name = "install_date") - private Long installationDate; - - @Column(name = "update_status", nullable = false, length = 255) - @Enumerated(EnumType.STRING) - private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN; - - @ManyToOne(optional = true, fetch = FetchType.LAZY) - @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) - private JpaDistributionSet installedDistributionSet; - - /** - * Read only on management API. Are commited by controller. - */ - @ElementCollection - @Column(name = "attribute_value", length = 128) - @MapKeyColumn(name = "attribute_key", nullable = false, length = 32) - @CollectionTable(name = "sp_target_attributes", joinColumns = { - @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) - - private final Map controllerAttributes = Collections.synchronizedMap(new HashMap()); - - // set default request controller attributes to true, because we want to - // request them the first - // time - @Column(name = "request_controller_attributes", nullable = false) - private boolean requestControllerAttributes = true; - - /** - * Constructor for {@link TargetStatus}. - * - * @param target - * related to this status. - */ - public JpaTargetInfo(final JpaTarget target) { - this.target = target; - targetId = target.getId(); - } - - JpaTargetInfo() { - target = null; - targetId = null; - } - - @Override - public Long getId() { - return targetId; - } - - @Override - @Transient - public boolean isNew() { - return entityNew; - } - - /** - * @param isNew - * the isNew to set - */ - public void setNew(final boolean entityNew) { - this.entityNew = entityNew; - } - - /** - * @return the ipAddress - */ - @Override - public URI getAddress() { - if (address == null) { - return null; - } - try { - return URI.create(address); - } catch (final IllegalArgumentException e) { - LOG.warn("Invalid address provided. Cloud not be configured to URI", e); - return null; - } - } - - /** - * @param address - * the target address to set - * - * @throws IllegalArgumentException - * If the given string violates RFC 2396 - */ - @Override - public void setAddress(final String address) { - // check if this is a real URI - if (address != null) { - try { - URI.create(address); - } catch (final IllegalArgumentException e) { - throw new InvalidTargetAddressException( - "The given address " + address + " violates the RFC-2396 specification", e); - } - } - - this.address = address; - } - - public Long getTargetId() { - return targetId; - } - - public void setTargetId(final Long targetId) { - this.targetId = targetId; - } - - @Override - public Target getTarget() { - return target; - } - - public void setTarget(final JpaTarget target) { - this.target = target; - } - - @Override - public Long getLastTargetQuery() { - return lastTargetQuery; - } - - public void setLastTargetQuery(final Long lastTargetQuery) { - this.lastTargetQuery = lastTargetQuery; - } - - public void setRequestControllerAttributes(final boolean requestControllerAttributes) { - this.requestControllerAttributes = requestControllerAttributes; - } - - @Override - public Map getControllerAttributes() { - return controllerAttributes; - } - - @Override - public boolean isRequestControllerAttributes() { - return requestControllerAttributes; - } - - @Override - public Long getInstallationDate() { - return installationDate; - } - - public void setInstallationDate(final Long installationDate) { - this.installationDate = installationDate; - } - - @Override - public TargetUpdateStatus getUpdateStatus() { - return updateStatus; - } - - public void setUpdateStatus(final TargetUpdateStatus updateStatus) { - this.updateStatus = updateStatus; - } - - @Override - public DistributionSet getInstalledDistributionSet() { - return installedDistributionSet; - } - - public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) { - this.installedDistributionSet = installedDistributionSet; - } - - /** - * @return the poll time which holds the last poll time of the target, the - * next poll time and the overdue time. In case the - * {@link #lastTargetQuery} is not set e.g. the target never polled - * before this method returns {@code null} - */ - @Override - public PollStatus getPollStatus() { - if (lastTargetQuery == null) { - return null; - } - return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> { - final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder - .getInstance().getTenantConfigurationManagement() - .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); - final Duration overdueTime = DurationHelper.formattedStringToDuration( - TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement() - .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) - .getValue()); - final LocalDateTime currentDate = LocalDateTime.now(); - final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), - ZoneId.systemDefault()); - final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); - final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); - return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); - }); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - result = prime * result + ((targetId == null) ? 0 : targetId.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TargetInfo)) { - return false; - } - final JpaTargetInfo other = (JpaTargetInfo) obj; - if (target == null) { - if (other.target != null) { - return false; - } - } else if (!target.equals(other.target)) { - return false; - } - if (targetId == null) { - if (other.targetId != null) { - return false; - } - } else if (!targetId.equals(other.targetId)) { - return false; - } - return true; - } -} +/** + * 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.jpa.model; + +import java.net.URI; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.CascadeType; +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.MapKeyColumn; +import javax.persistence.MapsId; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Transient; + +import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; +import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.PollStatus; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Persistable; + +/** + * A table which contains all the information inserted, updated by the + * controller itself. So this entity does not provide audit information because + * changes on this entity are mostly only done by controller requests. That's + * the reason that we store these information in a separated table so we don't + * modifying the {@link Target} itself when a controller reports it's + * {@link #lastTargetQuery} for example. + * + */ +@Table(name = "sp_target_info", indexes = { + @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) +@Entity +@EntityListeners(EntityPropertyChangeListener.class) +public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareEntity { + private static final long serialVersionUID = 1L; + + private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); + + @Id + private Long targetId; + + @Transient + private boolean entityNew; + + @CascadeOnDelete + @OneToOne(cascade = { CascadeType.MERGE, + CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class) + @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ")) + @MapsId + private JpaTarget target; + + @Column(name = "address", length = 512) + private String address; + + @Column(name = "last_target_query") + private Long lastTargetQuery; + + @Column(name = "install_date") + private Long installationDate; + + @Column(name = "update_status", nullable = false, length = 255) + @Enumerated(EnumType.STRING) + private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN; + + @ManyToOne(optional = true, fetch = FetchType.LAZY) + @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) + private JpaDistributionSet installedDistributionSet; + + /** + * Read only on management API. Are commited by controller. + */ + @ElementCollection + @Column(name = "attribute_value", length = 128) + @MapKeyColumn(name = "attribute_key", nullable = false, length = 32) + @CollectionTable(name = "sp_target_attributes", joinColumns = { + @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) + + private final Map controllerAttributes = Collections.synchronizedMap(new HashMap()); + + // set default request controller attributes to true, because we want to + // request them the first + // time + @Column(name = "request_controller_attributes", nullable = false) + private boolean requestControllerAttributes = true; + + /** + * Constructor for {@link TargetStatus}. + * + * @param target + * related to this status. + */ + public JpaTargetInfo(final JpaTarget target) { + this.target = target; + targetId = target.getId(); + } + + JpaTargetInfo() { + target = null; + targetId = null; + } + + @Override + public Long getId() { + return targetId; + } + + @Override + @Transient + public boolean isNew() { + return entityNew; + } + + /** + * @param isNew + * the isNew to set + */ + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; + } + + /** + * @return the ipAddress + */ + @Override + public URI getAddress() { + if (address == null) { + return null; + } + try { + return URI.create(address); + } catch (final IllegalArgumentException e) { + LOG.warn("Invalid address provided. Cloud not be configured to URI", e); + return null; + } + } + + /** + * @param address + * the target address to set + * + * @throws IllegalArgumentException + * If the given string violates RFC 2396 + */ + @Override + public void setAddress(final String address) { + // check if this is a real URI + if (address != null) { + try { + URI.create(address); + } catch (final IllegalArgumentException e) { + throw new InvalidTargetAddressException( + "The given address " + address + " violates the RFC-2396 specification", e); + } + } + + this.address = address; + } + + public Long getTargetId() { + return targetId; + } + + public void setTargetId(final Long targetId) { + this.targetId = targetId; + } + + @Override + public Target getTarget() { + return target; + } + + public void setTarget(final JpaTarget target) { + this.target = target; + } + + @Override + public Long getLastTargetQuery() { + return lastTargetQuery; + } + + public void setLastTargetQuery(final Long lastTargetQuery) { + this.lastTargetQuery = lastTargetQuery; + } + + public void setRequestControllerAttributes(final boolean requestControllerAttributes) { + this.requestControllerAttributes = requestControllerAttributes; + } + + @Override + public Map getControllerAttributes() { + return controllerAttributes; + } + + @Override + public boolean isRequestControllerAttributes() { + return requestControllerAttributes; + } + + @Override + public Long getInstallationDate() { + return installationDate; + } + + public void setInstallationDate(final Long installationDate) { + this.installationDate = installationDate; + } + + @Override + public TargetUpdateStatus getUpdateStatus() { + return updateStatus; + } + + public void setUpdateStatus(final TargetUpdateStatus updateStatus) { + this.updateStatus = updateStatus; + } + + @Override + public DistributionSet getInstalledDistributionSet() { + return installedDistributionSet; + } + + public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) { + this.installedDistributionSet = installedDistributionSet; + } + + /** + * @return the poll time which holds the last poll time of the target, the + * next poll time and the overdue time. In case the + * {@link #lastTargetQuery} is not set e.g. the target never polled + * before this method returns {@code null} + */ + @Override + public PollStatus getPollStatus() { + if (lastTargetQuery == null) { + return null; + } + return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> { + final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder + .getInstance().getTenantConfigurationManagement() + .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); + final Duration overdueTime = DurationHelper.formattedStringToDuration( + TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement() + .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) + .getValue()); + final LocalDateTime currentDate = LocalDateTime.now(); + final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), + ZoneId.systemDefault()); + final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); + final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); + return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); + }); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + result = prime * result + ((targetId == null) ? 0 : targetId.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TargetInfo)) { + return false; + } + final JpaTargetInfo other = (JpaTargetInfo) obj; + if (target == null) { + if (other.target != null) { + return false; + } + } else if (!target.equals(other.target)) { + return false; + } + if (targetId == null) { + if (other.targetId != null) { + return false; + } + } else if (!targetId.equals(other.targetId)) { + return false; + } + return true; + } + + @Override + public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo,final DescriptorEvent descriptorEvent) { + // there is no target info created event + } + + @Override + public void fireUpdateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); + } + + @Override + public void fireDeleteEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + } +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java new file mode 100644 index 000000000..71c374c5f --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java @@ -0,0 +1,42 @@ +/** + * 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.jpa.model.helper; + +import java.util.Map; +import java.util.stream.Collectors; + +import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; +import org.eclipse.hawkbit.repository.model.TenantAwareBaseEntity; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.eclipse.persistence.internal.sessions.ObjectChangeSet; +import org.eclipse.persistence.queries.UpdateObjectQuery; +import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord; + +public class EntityPropertyChangeHelper { + + + public static Map.Values> getChangeSet( + final Class clazz, final DescriptorEvent event) { + final T rolloutGroup = clazz.cast(event.getObject()); + final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()) + .getObjectChangeSet(); + return changeSet + .getChanges() + .stream() + .filter(record -> record instanceof DirectToFieldChangeRecord) + .map(record -> (DirectToFieldChangeRecord) record) + .collect( + Collectors.toMap( + record -> record.getAttribute(), + record -> new AbstractPropertyChangeEvent( + rolloutGroup, null).new Values(record + .getOldValue(), record.getNewValue()))); + } + +} From 82fa485ddceb7be6e2913dea552954bf6214e20e Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 10:13:07 +0200 Subject: [PATCH 012/118] suppress warning squid:S2221 Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/security/SystemSecurityContext.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java index 979080344..0e3863d97 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java @@ -101,7 +101,9 @@ public class SystemSecurityContext { try { setSystemContext(SecurityContextHolder.getContext()); return callable.call(); - } catch (final Exception e) { + // The callable API throws a Exception and not a specific + // one + } catch (@SuppressWarnings("squid:S2221") final Exception e) { throw Throwables.propagate(e); } }); From 812498d2fe0b25e4e0fc1cd5ea4b91c0dc8a2c67 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 10:22:35 +0200 Subject: [PATCH 013/118] don't use constructor using default encoding Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index d1bf85103..19ceb123f 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.amqp; import java.net.URI; import java.net.URISyntaxException; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.UUID; @@ -417,7 +418,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService { } private static String convertCorrelationId(final Message message) { - return new String(message.getMessageProperties().getCorrelationId()); + return new String(message.getMessageProperties().getCorrelationId(), StandardCharsets.UTF_8); } private Action getUpdateActionStatus(final ActionStatus actionStatus) { From 928ad1520b5088cd51629e8771e280f71d82ace5 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 10:39:55 +0200 Subject: [PATCH 014/118] remove port 8080 to fix tests Signed-off-by: Michael Hirsch --- .../hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java | 4 ++-- .../hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java index 0ec0d0d7e..584c774d5 100644 --- a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java +++ b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiDeploymentBaseTest.java @@ -60,8 +60,8 @@ import ru.yandex.qatools.allure.annotations.Stories; @Stories("Deployment Action Resource") public class DdiDeploymentBaseTest extends AbstractRestIntegrationTestWithMongoDB { - private static final String HTTP_LOCALHOST = "http://localhost:8080/"; - private static final String HTTPS_LOCALHOST = "https://localhost:8080/"; + private static final String HTTP_LOCALHOST = "http://localhost/"; + private static final String HTTPS_LOCALHOST = "https://localhost/"; @Test() @Description("Ensures that artifacts are not found, when softare module does not exists.") diff --git a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java index 8cd92d2bd..92e8f390d 100644 --- a/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java +++ b/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/util/PropertyBasedArtifactUrlHandlerTest.java @@ -35,8 +35,8 @@ import ru.yandex.qatools.allure.annotations.Stories; org.eclipse.hawkbit.RepositoryApplicationConfiguration.class }) public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTestWithMongoDB { - private static final String HTTPS_LOCALHOST = "https://localhost:8080/"; - private static final String HTTP_LOCALHOST = "http://localhost:8080/"; + private static final String HTTPS_LOCALHOST = "https://localhost/"; + private static final String HTTP_LOCALHOST = "http://localhost/"; @Autowired private ArtifactUrlHandler urlHandlerProperties; From 9727af7a993746310bcb6990871adead703eae3f Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 10:54:05 +0200 Subject: [PATCH 015/118] don't use getBytes using default encoding Signed-off-by: Michael Hirsch --- .../java/org/eclipse/hawkbit/simulator/amqp/SenderService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java index f2c0e7fcb..d7f81be4e 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SenderService.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.simulator.amqp; +import java.nio.charset.StandardCharsets; import java.util.UUID; import org.slf4j.Logger; @@ -58,7 +59,7 @@ public abstract class SenderService extends MessageService { } message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME); final String correlationId = UUID.randomUUID().toString(); - message.getMessageProperties().setCorrelationId(correlationId.getBytes()); + message.getMessageProperties().setCorrelationId(correlationId.getBytes(StandardCharsets.UTF_8)); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Sending message {} to exchange {} with correlationId {}", message, address, correlationId); From 400c8bafcf51f6190a492f7af06ffecd36e2599e Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 11:10:59 +0200 Subject: [PATCH 016/118] move method to the right inner class Signed-off-by: Michael Hirsch --- .../hawkbit/ui/common/tagdetails/AbstractTagToken.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java index 9d36e3de0..042492613 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java @@ -211,11 +211,11 @@ public abstract class AbstractTagToken implements Serializ unassignTag(tagDetails.get(tokenId).getName()); } - } + private Property getItemNameProperty(final Object tokenId) { + final Item item = tokenField.getContainerDataSource().getItem(tokenId); + return item.getItemProperty("name"); + } - private Property getItemNameProperty(final Object tokenId) { - final Item item = tokenField.getContainerDataSource().getItem(tokenId); - return item.getItemProperty("name"); } private String getColor(final Object tokenId) { From 40a12c0321144bc6ed779e17e6932b91c9497134 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 11:16:37 +0200 Subject: [PATCH 017/118] remove unnecessary IOException from method signature Signed-off-by: Michael Hirsch --- .../im/authentication/UserAuthenticationFilter.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/UserAuthenticationFilter.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/UserAuthenticationFilter.java index ecd980b03..fd59f1d30 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/UserAuthenticationFilter.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/UserAuthenticationFilter.java @@ -8,8 +8,6 @@ */ package org.eclipse.hawkbit.im.authentication; -import java.io.IOException; - import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -46,14 +44,11 @@ public interface UserAuthenticationFilter { * the servlet response * @param chain * the filterchain - * @throws IOException - * cannot read from request * @throws ServletException * servlet exception */ - void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException; + void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException; /** * @see Filter#destroy() From 227267af880c9ecd5597f97c0756870ea75d6044 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 11:18:05 +0200 Subject: [PATCH 018/118] avoid more than 3 nested if/switch/try blocks Signed-off-by: Michael Hirsch --- .../hawkbit/im/authentication/SpPermission.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index daf5f0dd9..52935a0cb 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -185,18 +185,22 @@ public final class SpPermission { field.setAccessible(true); try { final String role = (String) field.get(null); - if (!(exclusionRoles.contains(role))) { - allPermissions.add(role); - } + addIfNotExcluded(exclusionRoles, allPermissions, role); } catch (final IllegalAccessException e) { LOGGER.error(e.getMessage(), e); } - } } return allPermissions; } + private static void addIfNotExcluded(final Collection exclusionRoles, final List allPermissions, + final String role) { + if (!(exclusionRoles.contains(role))) { + allPermissions.add(role); + } + } + /** * Contains all the spring security evaluation expressions for the * {@link PreAuthorize} annotation for method security. From 7e94c9f68447ddcb79b3619eb328c4d2ebbe8506 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 11:58:11 +0200 Subject: [PATCH 019/118] write comment in constructor why necessary Signed-off-by: Michael Hirsch --- .../hawkbit/mgmt/json/model/artifact/MgmtArtifactHash.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/artifact/MgmtArtifactHash.java b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/artifact/MgmtArtifactHash.java index d43ae4339..770c8ffcf 100644 --- a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/artifact/MgmtArtifactHash.java +++ b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/json/model/artifact/MgmtArtifactHash.java @@ -27,6 +27,7 @@ public class MgmtArtifactHash { * Default constructor. */ public MgmtArtifactHash() { + // used for jackson to instantiate } /** From 2f263faca0d553bcdd615a022f114a8aaaabfdc6 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 12:01:28 +0200 Subject: [PATCH 020/118] suppress warning for multiple checked exception declaration Signed-off-by: Michael Hirsch --- .../im/authentication/UserAuthenticationFilter.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/UserAuthenticationFilter.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/UserAuthenticationFilter.java index fd59f1d30..deaff089f 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/UserAuthenticationFilter.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/UserAuthenticationFilter.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.im.authentication; +import java.io.IOException; + import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -44,11 +46,16 @@ public interface UserAuthenticationFilter { * the servlet response * @param chain * the filterchain + * @throws IOException + * cannot read from request * @throws ServletException * servlet exception */ - - void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException; + // this declaration of multiple checked exception is necessary so it's + // aligned with the servlet API. + @SuppressWarnings("squid:S1160") + void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException; /** * @see Filter#destroy() From ebf2c15da91442e43a684f51b7033ac3c9087645 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 12:07:35 +0200 Subject: [PATCH 021/118] use private method getEntityFactory() Signed-off-by: Michael Hirsch --- .../eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java index cb869714b..4ba722284 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/details/ArtifactBeanQuery.java @@ -69,7 +69,7 @@ public class ArtifactBeanQuery extends AbstractBeanQuery { @Override protected LocalArtifact constructBean() { - return entityFactory.generateLocalArtifact(); + return getEntityFactory().generateLocalArtifact(); } @Override From a04333b393dd09fed27b29883fe4075f3598cdb8 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 13:30:58 +0200 Subject: [PATCH 022/118] re-insert the method cleanMessageHeaderProperties Signed-off-by: Michael Hirsch --- .../java/org/eclipse/hawkbit/amqp/BaseAmqpService.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java index 1d9693ed7..b9314ac27 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java @@ -107,4 +107,14 @@ public class BaseAmqpService { protected RabbitTemplate getRabbitTemplate() { return rabbitTemplate; } + + /** + * Clean message properties before sending a message. + * + * @param message + * the message to cleaned up + */ + protected void cleanMessageHeaderProperties(final Message message) { + message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME); + } } From b97f787a8af058bffcf23c70d11fb84da0b94983 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 25 Jul 2016 14:39:51 +0200 Subject: [PATCH 023/118] Formatted the code --- .../ui/management/dstable/DistributionDetails.java | 14 +++++++------- .../hawkbit/ui/utils/SPUIComponentIdProvider.java | 4 ++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java index e59820e9c..83f829e68 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java @@ -83,7 +83,7 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail void onEvent(final MetadataEvent event) { UI.getCurrent() .access(() -> { - DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); + final DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) { if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) { dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey()); @@ -146,7 +146,7 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail @Override protected String getTabSheetId() { - return SPUIComponentIdProvider.DISTRIBUTION_DETAILS_TABSHEET; + return SPUIComponentIdProvider.DISTRIBUTIONSET_DETAILS_TABSHEET_ID; } @Override @@ -214,21 +214,21 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail @Override protected String getShowMetadataButtonId() { - DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState + final DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState .getLastSelectedDistribution().get() : null; return SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + lastselectedDistDS.getName() + "." + lastselectedDistDS.getVersion(); } - private boolean isDistributionSetSelected(DistributionSet ds) { - DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState + private boolean isDistributionSetSelected(final DistributionSet ds) { + final DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState .getLastSelectedDistribution().get() : null; return ds!=null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName()) && lastselectedManageDS.getVersion().endsWith(ds.getVersion()); } @Override - protected void showMetadata(ClickEvent event) { - DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); + protected void showMetadata(final ClickEvent event) { + final DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null)); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java index 3e8c3436b..5c0456c7d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUIComponentIdProvider.java @@ -518,6 +518,10 @@ public final class SPUIComponentIdProvider { * Tab sheet id. */ public static final String TARGET_DETAILS_TABSHEET = "target.details.tabsheet"; + /** + * Tab sheet id. + */ + public static final String DISTRIBUTION_DETAILS_TABSHEET = "distribution.details.tabsheet."; /** * Combobox id. From b919dd714604a56d0e6775e8b3beb80c95ee3ed1 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 25 Jul 2016 15:52:27 +0200 Subject: [PATCH 024/118] Fix for the selenium testcase failure --- .../hawkbit/ui/management/dstable/DistributionDetails.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java index 83f829e68..1150e75a3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java @@ -146,7 +146,7 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail @Override protected String getTabSheetId() { - return SPUIComponentIdProvider.DISTRIBUTIONSET_DETAILS_TABSHEET_ID; + return SPUIComponentIdProvider.DISTRIBUTION_DETAILS_TABSHEET; } @Override From 2ad6f6946f879cce8cbadd16a7a2dc7d9db01160 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 16:01:32 +0200 Subject: [PATCH 025/118] improve code quality Signed-off-by: Michael Hirsch --- .../amqp/DefaultAmqpSenderService.java | 3 +- .../smtable/SoftwareModuleDetails.java | 80 +++---- .../common/AbstractMetadataPopupLayout.java | 75 +++--- .../hawkbit/ui/common/CommonDialogWindow.java | 18 +- .../AbstractTableDetailsLayout.java | 18 +- .../SoftwareModuleMetadatadetailslayout.java | 222 +++++++++--------- .../dstable/DistributionSetDetails.java | 76 +++--- .../dstable/DsMetadataPopupLayout.java | 30 +-- .../smtable/SwModuleDetails.java | 64 +++-- .../CreateOrUpdateFilterHeader.java | 9 +- .../dstable/DistributionDetails.java | 78 +++--- .../management/targettable/TargetDetails.java | 14 +- .../ui/rollout/rollout/RolloutListGrid.java | 2 +- 13 files changed, 335 insertions(+), 354 deletions(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/DefaultAmqpSenderService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/DefaultAmqpSenderService.java index d951cce5d..1eb6d31f2 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/DefaultAmqpSenderService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/DefaultAmqpSenderService.java @@ -9,6 +9,7 @@ package org.eclipse.hawkbit.amqp; import java.net.URI; +import java.nio.charset.StandardCharsets; import java.util.UUID; import org.eclipse.hawkbit.util.IpUtil; @@ -46,7 +47,7 @@ public class DefaultAmqpSenderService implements AmqpSenderService { final String correlationId = UUID.randomUUID().toString(); final String exchange = extractExchange(replyTo); - message.getMessageProperties().setCorrelationId(correlationId.getBytes()); + message.getMessageProperties().setCorrelationId(correlationId.getBytes(StandardCharsets.UTF_8)); if (LOGGER.isTraceEnabled()) { LOGGER.trace("Sending message {} to exchange {} with correlationId {}", message, exchange, correlationId); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleDetails.java index 15904169d..a9a14700d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtable/SoftwareModuleDetails.java @@ -53,42 +53,42 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta @Autowired private transient SoftwareManagement softwareManagement; - + @Autowired private SwMetadataPopupLayout swMetadataPopupLayout; - + @Autowired - private EntityFactory entityFactory; - + private transient EntityFactory entityFactory; + private SoftwareModuleMetadatadetailslayout swmMetadataTable; - + /** * softwareLayout Initialize the component. */ @Override protected void init() { swmMetadataTable = new SoftwareModuleMetadatadetailslayout(); - swmMetadataTable.init(getI18n(), getPermissionChecker(),softwareManagement,swMetadataPopupLayout,entityFactory); + swmMetadataTable.init(getI18n(), getPermissionChecker(), softwareManagement, swMetadataPopupLayout, + entityFactory); super.init(); } - + @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final MetadataEvent event) { - UI.getCurrent() - .access(() -> { - SoftwareModuleMetadata softwareModuleMetadata = event.getSoftwareModuleMetadata(); - if (softwareModuleMetadata != null - && isSoftwareModuleSelected(softwareModuleMetadata.getSoftwareModule())) { - if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_SOFTWARE_MODULE_METADATA) { - swmMetadataTable.createMetadata(event.getSoftwareModuleMetadata().getKey()); - } else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_SOFTWARE_MODULE_METADATA) { - swmMetadataTable.deleteMetadata(event.getSoftwareModuleMetadata().getKey()); - } - } - }); + UI.getCurrent().access(() -> { + final SoftwareModuleMetadata softwareModuleMetadata = event.getSoftwareModuleMetadata(); + if (softwareModuleMetadata != null + && isSoftwareModuleSelected(softwareModuleMetadata.getSoftwareModule())) { + if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_SOFTWARE_MODULE_METADATA) { + swmMetadataTable.createMetadata(event.getSoftwareModuleMetadata().getKey()); + } else if (event + .getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_SOFTWARE_MODULE_METADATA) { + swmMetadataTable.deleteMetadata(event.getSoftwareModuleMetadata().getKey()); + } + } + }); } - - + @Override protected String getEditButtonId() { return SPUIComponentIdProvider.UPLOAD_SW_MODULE_EDIT_BUTTON; @@ -101,7 +101,7 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null); detailsTab.addTab(swmMetadataTable, getI18n().get("caption.metadata"), null); } - + @Override protected void onEdit(final ClickEvent event) { final Window addSoftwareModule = softwareModuleAddUpdateWindow @@ -126,7 +126,7 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta updateSoftwareModuleDetailsLayout(HawkbitCommonUtil.SP_STRING_EMPTY, HawkbitCommonUtil.SP_STRING_EMPTY, maxAssign); } - + populateMetadataDetails(); } @@ -188,38 +188,30 @@ public class SoftwareModuleDetails extends AbstractNamedVersionedEntityTableDeta protected String getDetailsHeaderCaptionId() { return SPUIComponentIdProvider.TARGET_DETAILS_HEADER_LABEL_ID; } - - + @Override - protected void populateMetadataDetails(){ + protected void populateMetadataDetails() { swmMetadataTable.populateSMMetadata(getSelectedBaseEntity()); - } - - private boolean isSoftwareModuleSelected(SoftwareModule softwareModule) { - final SoftwareModule selectedUploadSWModule = artifactUploadState.getSelectedBaseSoftwareModule().isPresent() ? artifactUploadState - .getSelectedBaseSoftwareModule().get() : null; + } + + private boolean isSoftwareModuleSelected(final SoftwareModule softwareModule) { + final SoftwareModule selectedUploadSWModule = artifactUploadState.getSelectedBaseSoftwareModule().isPresent() + ? artifactUploadState.getSelectedBaseSoftwareModule().get() : null; return softwareModule != null && selectedUploadSWModule != null && selectedUploadSWModule.getName().equals(softwareModule.getName()) && selectedUploadSWModule.getVersion().equals(softwareModule.getVersion()); } - + @Override protected Boolean isMetadataIconToBeDisplayed() { return true; } - - @Override - protected String getShowMetadataButtonId() { - SoftwareModule selectedBaseEntity = getSelectedBaseEntity(); - return SPUIComponentIdProvider.SW_TABLE_MANAGE_METADATA_ID + "." + selectedBaseEntity.getName() + "." - + selectedBaseEntity.getVersion(); - } @Override - protected void showMetadata(ClickEvent event) { - SoftwareModule swmodule = softwareManagement.findSoftwareModuleWithDetails(getSelectedBaseEntityId()); - /* display the window */ - UI.getCurrent().addWindow(swMetadataPopupLayout.getWindow(swmodule,null)); + protected void showMetadata(final ClickEvent event) { + final SoftwareModule swmodule = softwareManagement.findSoftwareModuleWithDetails(getSelectedBaseEntityId()); + /* display the window */ + UI.getCurrent().addWindow(swMetadataPopupLayout.getWindow(swmodule, null)); } - + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java index 050d7c79f..ff1cc3db1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/AbstractMetadataPopupLayout.java @@ -38,7 +38,6 @@ import com.vaadin.server.FontAwesome; import com.vaadin.ui.AbstractTextField.TextChangeEventMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; -import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.Grid; import com.vaadin.ui.Grid.SelectionMode; @@ -98,7 +97,7 @@ public abstract class AbstractMetadataPopupLayout { if (ok) { - deleteMetadata(getSelectedEntity(), key, value); - uiNotification.displaySuccess(i18n.get("message.metadata.deleted.successfully", key)); - final Object selectedRow = metaDataGrid.getSelectedRow(); - metaDataGrid.getContainerDataSource().removeItem(event.getItemId()); - // force grid to refresh - metaDataGrid.clearSortOrder(); - if (!metaDataGrid.getContainerDataSource().getItemIds().isEmpty()) { - if (selectedRow != null) { - if (selectedRow.equals(event.getItemId())) { - metaDataGrid.select(metaDataGrid.getContainerDataSource().getIdByIndex(0)); - } else { - metaDataGrid.select(selectedRow); - } - } - } else { - keyTextField.clear(); - valueTextArea.clear(); - metaDataGrid.select(null); - if (hasCreatePermission()) { - keyTextField.setEnabled(true); - valueTextArea.setEnabled(true); - addIcon.setEnabled(false); - } - } + handleOkDeleteMetadata(event, key, value); } }); UI.getCurrent().addWindow(confirmDialog.getWindow()); confirmDialog.getWindow().bringToFront(); } + private void handleOkDeleteMetadata(final RendererClickEvent event, final String key, final String value) { + deleteMetadata(getSelectedEntity(), key, value); + uiNotification.displaySuccess(i18n.get("message.metadata.deleted.successfully", key)); + final Object selectedRow = metaDataGrid.getSelectedRow(); + metaDataGrid.getContainerDataSource().removeItem(event.getItemId()); + // force grid to refresh + metaDataGrid.clearSortOrder(); + if (!metaDataGrid.getContainerDataSource().getItemIds().isEmpty()) { + if (selectedRow != null) { + if (selectedRow.equals(event.getItemId())) { + metaDataGrid.select(metaDataGrid.getContainerDataSource().getIdByIndex(0)); + } else { + metaDataGrid.select(selectedRow); + } + } + } else { + clearTextFields(); + } + } + + private void clearTextFields() { + keyTextField.clear(); + valueTextArea.clear(); + metaDataGrid.select(null); + if (hasCreatePermission()) { + keyTextField.setEnabled(true); + valueTextArea.setEnabled(true); + addIcon.setEnabled(false); + } + } + private Button createAddIcon() { addIcon = SPUIComponentProvider.getButton(SPUIComponentIdProvider.METADTA_ADD_ICON_ID, i18n.get("button.save"), null, null, false, FontAwesome.PLUS, SPUIButtonStyleSmallNoBorder.class); - addIcon.addClickListener(event -> onAdd(event)); + addIcon.addClickListener(event -> onAdd()); return addIcon; } private Label createHeaderCaption() { - final Label captionLabel = SPUIComponentProvider.getLabel(i18n.get("caption.metadata"), - SPUILabelDefinitions.SP_WIDGET_CAPTION); - return captionLabel; + return SPUIComponentProvider.getLabel(i18n.get("caption.metadata"), SPUILabelDefinitions.SP_WIDGET_CAPTION); } - private IndexedContainer getMetadataContainer() { + private static IndexedContainer getMetadataContainer() { final IndexedContainer swcontactContainer = new IndexedContainer(); swcontactContainer.addContainerProperty(KEY, String.class, ""); swcontactContainer.addContainerProperty(VALUE, String.class, ""); @@ -340,7 +344,7 @@ public abstract class AbstractMetadataPopupLayout close(); + private final ClickListener closeClickListener = event -> close(); private final transient Map orginalValues; @@ -115,6 +115,10 @@ public class CommonDialogWindow extends Window implements Serializable { * the saveButtonClickListener * @param cancelButtonClickListener * the cancelButtonClickListener + * @param layout + * the abstract layout + * @param i18n + * the i18n service */ public CommonDialogWindow(final String caption, final Component content, final String helpLink, final ClickListener saveButtonClickListener, final ClickListener cancelButtonClickListener, @@ -233,11 +237,11 @@ public class CommonDialogWindow extends Window implements Serializable { } protected void addCloseListenerForSaveButton() { - saveButton.addClickListener(close); + saveButton.addClickListener(closeClickListener); } protected void addCloseListenerForCancelButton() { - cancelButton.addClickListener(close); + cancelButton.addClickListener(closeClickListener); } protected void addComponenetListeners() { @@ -275,7 +279,8 @@ public class CommonDialogWindow extends Window implements Serializable { return false; } - private boolean isValueEquals(final AbstractField field, final Object orginalValue, final Object currentValue) { + private static boolean isValueEquals(final AbstractField field, final Object orginalValue, + final Object currentValue) { if (Set.class.equals(field.getType())) { return CollectionUtils.isEqualCollection(CollectionUtils.emptyIfNull((Collection) orginalValue), CollectionUtils.emptyIfNull((Collection) currentValue)); @@ -289,7 +294,7 @@ public class CommonDialogWindow extends Window implements Serializable { return Objects.equals(orginalValue, currentValue); } - private Object getCurrentVaue(final Component currentChangedComponent, final Object newValue, + private static Object getCurrentVaue(final Component currentChangedComponent, final Object newValue, final AbstractField field) { Object currentValue = field.getValue(); if (field instanceof Table) { @@ -365,7 +370,7 @@ public class CommonDialogWindow extends Window implements Serializable { return false; } - private List> getAllComponents(final AbstractLayout abstractLayout) { + private static List> getAllComponents(final AbstractLayout abstractLayout) { final List> components = new ArrayList<>(); final Iterator iterate = abstractLayout.iterator(); @@ -464,6 +469,7 @@ public class CommonDialogWindow extends Window implements Serializable { private class ChangeListener implements ValueChangeListener, TextChangeListener, ItemSetChangeListener { + private static final long serialVersionUID = 1L; private final Field field; public ChangeListener(final Field field) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java index b6475f647..b0b563f0e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java @@ -64,7 +64,7 @@ public abstract class AbstractTableDetailsLayout extends private Button editButton; private Button manageMetadataBtn; - + private TabSheet detailsTab; private VerticalLayout detailsLayout; @@ -140,11 +140,11 @@ public abstract class AbstractTableDetailsLayout extends editButton.addClickListener(this::onEdit); editButton.setEnabled(false); - manageMetadataBtn = SPUIComponentProvider.getButton("", "", "", null, false, - FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class); + manageMetadataBtn = SPUIComponentProvider.getButton("", "", "", null, false, FontAwesome.LIST_ALT, + SPUIButtonStyleSmallNoBorder.class); manageMetadataBtn.setId(getEditButtonId()); manageMetadataBtn.setDescription(i18n.get("tooltip.metadata.icon")); - manageMetadataBtn.addClickListener(this::showMetadata); + manageMetadataBtn.addClickListener(this::showMetadata); manageMetadataBtn.setEnabled(false); detailsTab = SPUIComponentProvider.getDetailsTabSheet(); @@ -295,8 +295,8 @@ public abstract class AbstractTableDetailsLayout extends descriptionLayout = getTabLayout(); return descriptionLayout; } - - /** + + /** * Default caption of header to be displayed when no data row selected in * table. * @@ -341,7 +341,7 @@ public abstract class AbstractTableDetailsLayout extends } protected abstract void populateDetailsWidget(); - + protected abstract void populateMetadataDetails(); protected Long getSelectedBaseEntityId() { @@ -352,10 +352,8 @@ public abstract class AbstractTableDetailsLayout extends protected abstract String getName(); - protected abstract String getShowMetadataButtonId(); - protected abstract Boolean isMetadataIconToBeDisplayed(); - + protected abstract void showMetadata(Button.ClickEvent event); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java index 854347c11..d5753c033 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java @@ -41,130 +41,142 @@ import com.vaadin.ui.themes.ValoTheme; @ViewScope public class SoftwareModuleMetadatadetailslayout extends Table { - private static final long serialVersionUID = 2913758299611838818L; + private static final long serialVersionUID = 2913758299611838818L; - private static final String METADATA_KEY = "Key"; + private static final String METADATA_KEY = "Key"; - private SpPermissionChecker permissionChecker; + private SpPermissionChecker permissionChecker; - private SoftwareManagement softwareManagement; + private transient SoftwareManagement softwareManagement; - private SwMetadataPopupLayout swMetadataPopupLayout; + private SwMetadataPopupLayout swMetadataPopupLayout; - private I18N i18n; + private I18N i18n; - private Long selectedSWModuleId; + private Long selectedSWModuleId; - private transient EntityFactory entityFactory; + private transient EntityFactory entityFactory; - public void init(final I18N i18n, final SpPermissionChecker permissionChecker, - final SoftwareManagement softwareManagement, final SwMetadataPopupLayout swMetadataPopupLayout, - final EntityFactory entityFactory) { - this.i18n = i18n; - this.permissionChecker = permissionChecker; - this.softwareManagement = softwareManagement; - this.swMetadataPopupLayout = swMetadataPopupLayout; - this.entityFactory = entityFactory; - createSWMMetadataTable(); - addCustomGeneratedColumns(); - } + /** + * Initialize the layout. + * + * @param i18n + * the i18n service + * @param permissionChecker + * the permission checker service + * @param softwareManagement + * the software management service + * @param swMetadataPopupLayout + * the software module metadata popup layout + * @param entityFactory + * the entity factory service + */ + public void init(final I18N i18n, final SpPermissionChecker permissionChecker, + final SoftwareManagement softwareManagement, final SwMetadataPopupLayout swMetadataPopupLayout, + final EntityFactory entityFactory) { + this.i18n = i18n; + this.permissionChecker = permissionChecker; + this.softwareManagement = softwareManagement; + this.swMetadataPopupLayout = swMetadataPopupLayout; + this.entityFactory = entityFactory; + createSWMMetadataTable(); + addCustomGeneratedColumns(); + } - /** - * Populate software module metadata table. - * - * @param swModule - */ - public void populateSMMetadata(final SoftwareModule swModule) { - removeAllItems(); - if (null == swModule) { - return; - } - selectedSWModuleId = swModule.getId(); - final List swMetadataList = swModule.getMetadata(); - if (null != swMetadataList && !swMetadataList.isEmpty()) { - swMetadataList.forEach(swMetadata -> setSWMetadataProperties(swMetadata)); - } - } + /** + * Populate software module metadata table. + * + * @param swModule + */ + public void populateSMMetadata(final SoftwareModule swModule) { + removeAllItems(); + if (null == swModule) { + return; + } + selectedSWModuleId = swModule.getId(); + final List swMetadataList = swModule.getMetadata(); + if (null != swMetadataList && !swMetadataList.isEmpty()) { + swMetadataList.forEach(swMetadata -> setSWMetadataProperties(swMetadata)); + } + } - /** - * Create metadata. - * - * @param metadataKeyName - */ - public void createMetadata(final String metadataKeyName) { - final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource(); - final Item item = metadataContainer.addItem(metadataKeyName); - item.getItemProperty(METADATA_KEY).setValue(metadataKeyName); + /** + * Create metadata. + * + * @param metadataKeyName + */ + public void createMetadata(final String metadataKeyName) { + final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource(); + final Item item = metadataContainer.addItem(metadataKeyName); + item.getItemProperty(METADATA_KEY).setValue(metadataKeyName); - } + } - /** - * Delete metadata. - * - * @param metadataKeyName - */ - public void deleteMetadata(final String metadataKeyName) { - final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource(); - metadataContainer.removeItem(metadataKeyName); - } + /** + * Delete metadata. + * + * @param metadataKeyName + */ + public void deleteMetadata(final String metadataKeyName) { + final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource(); + metadataContainer.removeItem(metadataKeyName); + } - private void createSWMMetadataTable() { - addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES); - addStyleName(ValoTheme.TABLE_NO_STRIPES); - addStyleName(SPUIStyleDefinitions.SW_MODULE_TABLE); - setSelectable(false); - setImmediate(true); - setContainerDataSource(getSwModuleMetadataContainer()); - setColumnHeaderMode(ColumnHeaderMode.EXPLICIT); - addSMMetadataTableHeader(); - setSizeFull(); - //same as height of other tabs in details tabsheet - setHeight(116,Unit.PIXELS); - } + private void createSWMMetadataTable() { + addStyleName(ValoTheme.TABLE_NO_HORIZONTAL_LINES); + addStyleName(ValoTheme.TABLE_NO_STRIPES); + addStyleName(SPUIStyleDefinitions.SW_MODULE_TABLE); + setSelectable(false); + setImmediate(true); + setContainerDataSource(getSwModuleMetadataContainer()); + setColumnHeaderMode(ColumnHeaderMode.EXPLICIT); + addSMMetadataTableHeader(); + setSizeFull(); + // same as height of other tabs in details tabsheet + setHeight(116, Unit.PIXELS); + } - private IndexedContainer getSwModuleMetadataContainer() { - final IndexedContainer container = new IndexedContainer(); - container.addContainerProperty(METADATA_KEY, String.class, ""); - setColumnAlignment(METADATA_KEY, Align.LEFT); - return container; - } + private IndexedContainer getSwModuleMetadataContainer() { + final IndexedContainer container = new IndexedContainer(); + container.addContainerProperty(METADATA_KEY, String.class, ""); + setColumnAlignment(METADATA_KEY, Align.LEFT); + return container; + } - private void addSMMetadataTableHeader() { - setColumnHeader(METADATA_KEY, i18n.get("header.key")); - } + private void addSMMetadataTableHeader() { + setColumnHeader(METADATA_KEY, i18n.get("header.key")); + } + private void setSWMetadataProperties(final SoftwareModuleMetadata swMetadata) { + final Item item = getContainerDataSource().addItem(swMetadata.getKey()); + item.getItemProperty(METADATA_KEY).setValue(swMetadata.getKey()); + } - private void setSWMetadataProperties(final SoftwareModuleMetadata swMetadata) { - final Item item = getContainerDataSource().addItem(swMetadata.getKey()); - item.getItemProperty(METADATA_KEY).setValue(swMetadata.getKey()); - } + private void addCustomGeneratedColumns() { + addGeneratedColumn(METADATA_KEY, (source, itemId, columnId) -> customMetadataDetailButton((String) itemId)); + } - private void addCustomGeneratedColumns() { - addGeneratedColumn(METADATA_KEY, (source, itemId, columnId) -> customMetadataDetailButton((String) itemId)); - } + private Button customMetadataDetailButton(final String metadataKey) { + final Button viewLink = SPUIComponentProvider.getButton(getDetailLinkId(metadataKey), metadataKey, + "View" + metadataKey + " Metadata details", null, false, null, SPUIButtonStyleSmallNoBorder.class); + viewLink.setData(metadataKey); + if (permissionChecker.hasUpdateDistributionPermission()) { + viewLink.addStyleName(ValoTheme.BUTTON_TINY + " " + ValoTheme.BUTTON_LINK + " " + "on-focus-no-border link" + + " " + "text-style"); + viewLink.addClickListener(event -> showMetadataDetails(selectedSWModuleId, metadataKey)); + } + return viewLink; + } - private Button customMetadataDetailButton(final String metadataKey) { - final Button viewLink = SPUIComponentProvider.getButton(getDetailLinkId(metadataKey), metadataKey, "View" - + metadataKey + " Metadata details", null, false, null, SPUIButtonStyleSmallNoBorder.class); - viewLink.setData(metadataKey); - if (permissionChecker.hasUpdateDistributionPermission()) { - viewLink.addStyleName(ValoTheme.BUTTON_TINY + " " + ValoTheme.BUTTON_LINK + " " + "on-focus-no-border link" - + " " + "text-style"); - viewLink.addClickListener(event -> showMetadataDetails(selectedSWModuleId, metadataKey)); - } - return viewLink; - } + private static String getDetailLinkId(final String name) { + return new StringBuilder(SPUIComponentIdProvider.SW_METADATA_DETAIL_LINK).append('.').append(name).toString(); + } - private static String getDetailLinkId(final String name) { - return new StringBuilder(SPUIComponentIdProvider.SW_METADATA_DETAIL_LINK).append('.').append(name).toString(); - } - - private void showMetadataDetails(final Long selectedSWModuleId, final String metadataKey) { - SoftwareModule swmodule = softwareManagement.findSoftwareModuleById(selectedSWModuleId); - /* display the window */ - UI.getCurrent().addWindow( - swMetadataPopupLayout.getWindow(swmodule, - entityFactory.generateSoftwareModuleMetadata(swmodule, metadataKey, ""))); - } + private void showMetadataDetails(final Long selectedSWModuleId, final String metadataKey) { + final SoftwareModule swmodule = softwareManagement.findSoftwareModuleById(selectedSWModuleId); + /* display the window */ + UI.getCurrent().addWindow(swMetadataPopupLayout.getWindow(swmodule, + entityFactory.generateSoftwareModuleMetadata(swmodule, metadataKey, ""))); + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java index 03a86c44d..6e428ffba 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java @@ -68,7 +68,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet private static final String SOFT_MODULE = "softwareModule"; private static final String UNASSIGN_SOFT_MODULE = "unassignSoftModule"; - + @Autowired private ManageDistUIState manageDistUIState; @@ -83,37 +83,35 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet @Autowired private transient DistributionSetManagement distributionSetManagement; - + @Autowired private DsMetadataPopupLayout dsMetadataPopupLayout; - + @Autowired - private EntityFactory entityFactory; + private transient EntityFactory entityFactory; private SoftwareModuleDetailsTable softwareModuleTable; - + private DistributionSetMetadatadetailslayout dsMetadataTable; private VerticalLayout tagsLayout; - + private final Map assignedSWModule = new HashMap<>(); - - + @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final MetadataEvent event) { - UI.getCurrent() - .access(() -> { - DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); - if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) { - if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey()); - } else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey()); - } - } - }); + UI.getCurrent().access(() -> { + final DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); + if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) { + if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) { + dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey()); + } else if (event + .getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) { + dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey()); + } + } + }); } - /** * softwareLayout Initialize the component. @@ -124,8 +122,8 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet softwareModuleTable.init(getI18n(), true, getPermissionChecker(), distributionSetManagement, getEventBus(), manageDistUIState); dsMetadataTable = new DistributionSetMetadatadetailslayout(); - dsMetadataTable.init(getI18n(), getPermissionChecker(),distributionSetManagement, - dsMetadataPopupLayout,entityFactory); + dsMetadataTable.init(getI18n(), getPermissionChecker(), distributionSetManagement, dsMetadataPopupLayout, + entityFactory); super.init(); } @@ -141,7 +139,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet populateTags(); populateMetadataDetails(); } - + private void populateModule() { softwareModuleTable.populateModule(getSelectedBaseEntity()); showUnsavedAssignment(); @@ -271,12 +269,12 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet updateDistributionSetDetailsLayout(null, null); } } - + @Override - protected void populateMetadataDetails(){ + protected void populateMetadataDetails() { dsMetadataTable.populateDSMetadata(getSelectedBaseEntity()); - } - + } + private void updateDistributionSetDetailsLayout(final String type, final Boolean isMigrationRequired) { final VerticalLayout detailsTabLayout = getDetailsLayout(); detailsTabLayout.removeAllComponents(); @@ -403,26 +401,18 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet protected Boolean isMetadataIconToBeDisplayed() { return true; } - - @Override - protected String getShowMetadataButtonId() { - DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() ? manageDistUIState - .getLastSelectedDistribution().get() : null; - return SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + lastselectedDistDS.getName() + "." - + lastselectedDistDS.getVersion(); - } - - private boolean isDistributionSetSelected(DistributionSet ds) { - DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() ? manageDistUIState - .getLastSelectedDistribution().get() : null; + + private boolean isDistributionSetSelected(final DistributionSet ds) { + final DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() + ? manageDistUIState.getLastSelectedDistribution().get() : null; return ds != null && lastselectedDistDS != null && lastselectedDistDS.getName().equals(ds.getName()) && lastselectedDistDS.getVersion().endsWith(ds.getVersion()); } - @Override - protected void showMetadata(ClickEvent event) { - DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); - UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null)); + protected void showMetadata(final ClickEvent event) { + final DistributionSet ds = distributionSetManagement + .findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); + UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java index 2041944d4..26eecab8f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java @@ -36,23 +36,24 @@ public class DsMetadataPopupLayout extends AbstractMetadataPopupLayout getMetadataList() { return getSelectedEntity().getMetadata(); } - + /** * Update metadata for DistributionSet. */ @Override - protected void deleteMetadata(DistributionSet entity, String key, String value) { - DistributionSetMetadata dsMetaData = entityFactory.generateDistributionSetMetadata(entity, key, value); + protected void deleteMetadata(final DistributionSet entity, final String key, final String value) { + final DistributionSetMetadata dsMetaData = entityFactory.generateDistributionSetMetadata(entity, key, value); distributionSetManagement.deleteDistributionSetMetadata(entity, key); eventBus.publish(this, new MetadataEvent(MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA, dsMetaData)); } - + @Override protected boolean hasCreatePermission() { return permChecker.hasCreateDistributionPermission(); } - + @Override protected boolean hasUpdatePermission() { return permChecker.hasUpdateDistributionPermission(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java index 6cec80028..04a651b5e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/smtable/SwModuleDetails.java @@ -49,49 +49,50 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay @Autowired private ManageDistUIState manageDistUIState; - + @Autowired private transient SoftwareManagement softwareManagement; - + @Autowired private SwMetadataPopupLayout swMetadataPopupLayout; - + @Autowired - private EntityFactory entityFactory; - + private transient EntityFactory entityFactory; + private SoftwareModuleMetadatadetailslayout swmMetadataTable; - /** + /** * softwareLayout Initialize the component. */ @Override protected void init() { swmMetadataTable = new SoftwareModuleMetadatadetailslayout(); - swmMetadataTable.init(getI18n(), getPermissionChecker(),softwareManagement,swMetadataPopupLayout,entityFactory); + swmMetadataTable.init(getI18n(), getPermissionChecker(), softwareManagement, swMetadataPopupLayout, + entityFactory); super.init(); } - + /** * MetadataEvent. * * @param event * as instance of {@link MetadataEvent} */ - + @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final MetadataEvent event) { - UI.getCurrent() - .access(() -> { - SoftwareModuleMetadata softwareModuleMetadata = event.getSoftwareModuleMetadata(); - if (softwareModuleMetadata != null - && isSoftwareModuleSelected(softwareModuleMetadata.getSoftwareModule())) { - if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_SOFTWARE_MODULE_METADATA) { - swmMetadataTable.createMetadata(event.getSoftwareModuleMetadata().getKey()); - } else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_SOFTWARE_MODULE_METADATA) { - swmMetadataTable.deleteMetadata(event.getSoftwareModuleMetadata().getKey()); - } - } - }); + UI.getCurrent().access(() -> { + final SoftwareModuleMetadata softwareModuleMetadata = event.getSoftwareModuleMetadata(); + if (softwareModuleMetadata != null + && isSoftwareModuleSelected(softwareModuleMetadata.getSoftwareModule())) { + if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_SOFTWARE_MODULE_METADATA) { + swmMetadataTable.createMetadata(event.getSoftwareModuleMetadata().getKey()); + } else if (event + .getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_SOFTWARE_MODULE_METADATA) { + swmMetadataTable.deleteMetadata(event.getSoftwareModuleMetadata().getKey()); + } + } + }); } @EventBusListenerMethod(scope = EventScope.SESSION) @@ -119,7 +120,7 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay detailsTab.addTab(createDescriptionLayout(), getI18n().get("caption.tab.description"), null); detailsTab.addTab(createLogLayout(), getI18n().get("caption.logs.tab"), null); detailsTab.addTab(swmMetadataTable, getI18n().get("caption.metadata"), null); - } + } @Override protected String getDefaultCaption() { @@ -196,15 +197,15 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay protected String getDetailsHeaderCaptionId() { return SPUIComponentIdProvider.TARGET_DETAILS_HEADER_LABEL_ID; } - + @Override protected void populateMetadataDetails() { swmMetadataTable.populateSMMetadata(getSelectedBaseEntity()); } - private boolean isSoftwareModuleSelected(SoftwareModule softwareModule) { - final Long selectedDistSWModuleId = manageDistUIState.getSelectedBaseSwModuleId().isPresent() ? manageDistUIState - .getSelectedBaseSwModuleId().get() : null; + private boolean isSoftwareModuleSelected(final SoftwareModule softwareModule) { + final Long selectedDistSWModuleId = manageDistUIState.getSelectedBaseSwModuleId().isPresent() + ? manageDistUIState.getSelectedBaseSwModuleId().get() : null; return softwareModule != null && selectedDistSWModuleId != null && selectedDistSWModuleId.equals(softwareModule.getId()); } @@ -213,17 +214,10 @@ public class SwModuleDetails extends AbstractNamedVersionedEntityTableDetailsLay protected Boolean isMetadataIconToBeDisplayed() { return true; } - - @Override - protected String getShowMetadataButtonId() { - SoftwareModule selectedBaseEntity = getSelectedBaseEntity(); - return SPUIComponentIdProvider.SW_TABLE_MANAGE_METADATA_ID + "." + selectedBaseEntity.getName() + "." - + selectedBaseEntity.getVersion(); - } @Override - protected void showMetadata(ClickEvent event) { - SoftwareModule swmodule = softwareManagement.findSoftwareModuleWithDetails(getSelectedBaseEntityId()); + protected void showMetadata(final ClickEvent event) { + final SoftwareModule swmodule = softwareManagement.findSoftwareModuleWithDetails(getSelectedBaseEntityId()); UI.getCurrent().addWindow(swMetadataPopupLayout.getWindow(swmodule, null)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java index b785ae8b6..1023d98ed 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filtermanagement/CreateOrUpdateFilterHeader.java @@ -60,8 +60,7 @@ import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.themes.ValoTheme; /** - * - * + * A Vaadin layout for create or update the target filter. */ @SpringComponent @ViewScope @@ -494,11 +493,7 @@ public class CreateOrUpdateFilterHeader extends VerticalLayout implements Button if (filterManagementUIState.isCreateFilterViewDisplayed() && !doesAlreadyExists()) { createTargetFilterQuery(); } else { - if (!nameTextField.getValue().equals(oldFilterName) && !doesAlreadyExists()) { - updateCustomFilter(); - } else { - updateCustomFilter(); - } + updateCustomFilter(); } } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java index e59820e9c..4765e9ac1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java @@ -53,48 +53,47 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail @Autowired private DistributionTagToken distributionTagToken; - + @Autowired - private transient DistributionSetManagement distributionSetManagement; - + private transient DistributionSetManagement distributionSetManagement; + @Autowired private DsMetadataPopupLayout dsMetadataPopupLayout; - + @Autowired - private EntityFactory entityFactory; + private transient EntityFactory entityFactory; private SoftwareModuleDetailsTable softwareModuleTable; private DistributionSetMetadatadetailslayout dsMetadataTable; - + @Override protected void init() { softwareModuleTable = new SoftwareModuleDetailsTable(); softwareModuleTable.init(getI18n(), false, getPermissionChecker(), null, null, null); - + dsMetadataTable = new DistributionSetMetadatadetailslayout(); - dsMetadataTable.init(getI18n(), getPermissionChecker(),distributionSetManagement, - dsMetadataPopupLayout,entityFactory); - + dsMetadataTable.init(getI18n(), getPermissionChecker(), distributionSetManagement, dsMetadataPopupLayout, + entityFactory); + super.init(); } @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final MetadataEvent event) { - UI.getCurrent() - .access(() -> { - DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); - if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) { - if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey()); - } else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey()); - } - } - }); + UI.getCurrent().access(() -> { + final DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); + if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) { + if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) { + dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey()); + } else if (event + .getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) { + dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey()); + } + } + }); } - @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final DistributionTableEvent distributionTableEvent) { onBaseEntityEvent(distributionTableEvent); @@ -156,12 +155,11 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail populateMetadataDetails(); } - - + @Override - protected void populateMetadataDetails(){ + protected void populateMetadataDetails() { dsMetadataTable.populateDSMetadata(getSelectedBaseEntity()); - } + } private void populateDetails(final DistributionSet ds) { if (ds != null) { @@ -206,30 +204,24 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail protected String getDetailsHeaderCaptionId() { return SPUIComponentIdProvider.DISTRIBUTION_DETAILS_HEADER_LABEL_ID; } - + @Override protected Boolean isMetadataIconToBeDisplayed() { return true; } - - @Override - protected String getShowMetadataButtonId() { - DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState - .getLastSelectedDistribution().get() : null; - return SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + lastselectedDistDS.getName() + "." - + lastselectedDistDS.getVersion(); - } - private boolean isDistributionSetSelected(DistributionSet ds) { - DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState - .getLastSelectedDistribution().get() : null; - return ds!=null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName()) + + private boolean isDistributionSetSelected(final DistributionSet ds) { + final DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() + ? managementUIState.getLastSelectedDistribution().get() : null; + return ds != null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName()) && lastselectedManageDS.getVersion().endsWith(ds.getVersion()); } @Override - protected void showMetadata(ClickEvent event) { - DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); - UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null)); + protected void showMetadata(final ClickEvent event) { + final DistributionSet ds = distributionSetManagement + .findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); + UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null)); } - + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java index ebb2ef185..f398c460c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetDetails.java @@ -107,7 +107,6 @@ public class TargetDetails extends AbstractTableDetailsLayout { return; } targetAddUpdateWindowLayout.getWindow(getSelectedBaseEntity().getControllerId()); - // targetAddUpdateWindowLayout.populateValuesOfTarget(getSelectedBaseEntity().getControllerId()); openWindow(); } @@ -229,7 +228,7 @@ public class TargetDetails extends AbstractTableDetailsLayout { * as Module (JVM|OS|AH) * @return Label as UI */ - private Label getSWModlabel(final String labelName, final SoftwareModule swModule) { + private static Label getSWModlabel(final String labelName, final SoftwareModule swModule) { return SPUIComponentProvider.createNameValueLabel(labelName + " : ", swModule.getName(), swModule.getVersion()); } @@ -253,24 +252,19 @@ public class TargetDetails extends AbstractTableDetailsLayout { return SPUIComponentIdProvider.TARGET_DETAILS_HEADER_LABEL_ID; } - @Override - protected String getShowMetadataButtonId() { - return null; - } - @Override protected Boolean isMetadataIconToBeDisplayed() { return false; } @Override - protected void showMetadata(ClickEvent event) { - //No implementation required + protected void showMetadata(final ClickEvent event) { + // No implementation required } @Override protected void populateMetadataDetails() { - //No implementation required + // No implementation required } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java index b58e2e7b8..9ebb1d065 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/RolloutListGrid.java @@ -443,7 +443,7 @@ public class RolloutListGrid extends AbstractGrid { return null; } - private String getDSDetails(final Item rolloutItem) { + private static String getDSDetails(final Item rolloutItem) { final StringBuilder swModuleNames = new StringBuilder(); final StringBuilder swModuleVendors = new StringBuilder(); final Set swModules = (Set) rolloutItem.getItemProperty(SW_MODULES).getValue(); From 5ae190c8c3120ac907996e261c11db2006719aa5 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 17:11:04 +0200 Subject: [PATCH 026/118] improve code quality Signed-off-by: Michael Hirsch --- .../hawkbit/ui/common/table/AbstractTable.java | 15 ++++++++++----- .../ui/management/targettable/TargetTable.java | 3 ++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java index b3b74836c..e8bb18e90 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/table/AbstractTable.java @@ -26,8 +26,6 @@ import org.eclipse.hawkbit.ui.utils.SPDateTimeUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.TableColumn; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventBus; @@ -49,9 +47,9 @@ import com.vaadin.ui.themes.ValoTheme; */ public abstract class AbstractTable extends Table { - private static final long serialVersionUID = 4856562746502217630L; + private static final float DEFAULT_COLUMN_NAME_MIN_SIZE = 0.8F; - private static final Logger LOG = LoggerFactory.getLogger(AbstractTable.class); + private static final long serialVersionUID = 4856562746502217630L; @Autowired protected transient EventBus.SessionEventBus eventBus; @@ -89,6 +87,13 @@ public abstract class AbstractTable extends Table { eventBus.unsubscribe(this); } + /** + * Gets the selected item id or in multiselect mode a set of selected ids. + * + * @param table + * the table to retrieve the selected ID(s) + * @return the ID(s) which are selected in the table + */ public static Set getTableValue(final Table table) { @SuppressWarnings("unchecked") Set values = (Set) table.getValue(); @@ -351,7 +356,7 @@ public abstract class AbstractTable extends Table { } protected float getColumnNameMinimizedSize() { - return 0.8F; + return DEFAULT_COLUMN_NAME_MIN_SIZE; } /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java index 0a70f60d5..4e43ea39b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTable.java @@ -899,6 +899,7 @@ public class TargetTable extends AbstractTable { /** * Select all rows in the table. */ + @Override public void selectAll() { // As Vaadin Table only returns the current ItemIds which are visible @@ -999,4 +1000,4 @@ public class TargetTable extends AbstractTable { private boolean isFilteredByTags() { return !managementUIState.getTargetTableFilters().getClickedTargetTags().isEmpty(); } -} \ No newline at end of file +} From 7a32d931b5bec0e8e122e076f5ea9acbab527962 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 25 Jul 2016 17:12:56 +0200 Subject: [PATCH 027/118] improve code quality Signed-off-by: Michael Hirsch --- .../management/dstable/DistributionTable.java | 47 +++++++++---------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index f6cd80853..ed69ee9a2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -18,7 +18,6 @@ import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; import org.eclipse.hawkbit.repository.DistributionSetManagement; -import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -90,18 +89,15 @@ public class DistributionTable extends AbstractNamedVersionTable showMetadataDetails(itemId)); - iconLayout.addComponent((Button)getPinButton(itemId)); + iconLayout.addComponent((Button) getPinButton(itemId)); iconLayout.addComponent(manageMetaDataBtn); return iconLayout; } - + }); } - - + private String getNameAndVerion(final Object itemId) { final Item item = getItem(itemId); final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue(); return name + "." + version; } - - private Button createManageMetadataButton(String nameVersionStr) { + + private Button createManageMetadataButton(final String nameVersionStr) { final Button manageMetadataBtn = SPUIComponentProvider.getButton( SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false, FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class); @@ -281,9 +276,9 @@ public class DistributionTable extends AbstractNamedVersionTable Date: Thu, 28 Jul 2016 10:09:51 +0200 Subject: [PATCH 028/118] sonar pom hygiene Signed-off-by: Michael Hirsch --- pom.xml | 37 +------------------------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/pom.xml b/pom.xml index 9038d2e56..d78d6d2cc 100644 --- a/pom.xml +++ b/pom.xml @@ -127,30 +127,11 @@ jacoco https://projects.eclipse.org/projects/iot.hawkbit https://circleci.com/gh/eclipse/hawkbit - 0.7.7.201606060606 - - 1.4 - - reuseReports - ${project.basedir}/../target/ - jacoco-ut.exec - ${jacoco.outputDir}/${jacoco.out.ut.file} - jacoco-it.exec - ${jacoco.outputDir}/${jacoco.out.it.file} @@ -295,7 +276,6 @@ 1 ${jacoco.agent.ut.arg} - -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" @@ -312,13 +292,6 @@ **/Abstract*.java - - - org.aspectj - aspectjweaver - ${aspectj.version} - - org.apache.maven.plugins @@ -326,8 +299,7 @@ true 3 - -Xmx1024m ${jacoco.agent.ut.arg} - -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar" + -Xmx1024m ${jacoco.agent.ut.arg} listener @@ -335,13 +307,6 @@ - - - org.aspectj - aspectjweaver - ${aspectj.version} - - integration-test From 271ee88d1242259287f231ad5b6a292cadaa8a3a Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 28 Jul 2016 10:38:29 +0200 Subject: [PATCH 029/118] remove unnecessary property declaration Signed-off-by: Michael Hirsch --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index d78d6d2cc..8426b9740 100644 --- a/pom.xml +++ b/pom.xml @@ -100,7 +100,6 @@ 1.5.4 1.0.2 0.9.1 - 1.8.5 19.0 1.4.3 1.50.2 @@ -124,7 +123,6 @@ https://sonar.eu-gb.mybluemix.net eclipse/hawkbit - jacoco https://projects.eclipse.org/projects/iot.hawkbit https://circleci.com/gh/eclipse/hawkbit 0.7.7.201606060606 From 7fa89d7d3cb63c41fe8936d4891d48663de8be22 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Thu, 28 Jul 2016 12:39:12 +0200 Subject: [PATCH 030/118] Add entity lifercycle interceptor interface and add a entity listener. Signed-off-by: SirWayne --- .../repository/model/EntityInterceptor.java | 79 +++++++++++++++++++ .../RepositoryApplicationConfiguration.java | 9 +++ .../jpa/model/AbstractJpaBaseEntity.java | 3 +- .../jpa/model/EntityInterceptorListener.java | 69 ++++++++++++++++ .../model/helper/EntityInterceptorHolder.java | 42 ++++++++++ 5 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/EntityInterceptor.java create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/EntityInterceptor.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/EntityInterceptor.java new file mode 100644 index 000000000..b6fff3f91 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/model/EntityInterceptor.java @@ -0,0 +1,79 @@ +/** + * 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.model; + +/** + * Interface for the entity interceptor lifecycle. + */ +public interface EntityInterceptor { + + /** + * Callback for the {@link @PrePersist} lifecycle event. + * + * @param entity + * the model entity + */ + default void prePersist(final Object entity) { + }; + + /** + * Callback for the {@link @PostPersist} lifecycle event. + * + * @param entity + * the model entity + */ + default void postPersist(final Object entity) { + }; + + /** + * Callback for the {@link @PostRemove} lifecycle event. + * + * @param entity + * the model entity + */ + default void postRemove(final Object entity) { + }; + + /** + * Callback for the {@link @PreRemove} lifecycle event. + * + * @param entity + * the model entity + */ + default void preRemove(final Object entity) { + }; + + /** + * Callback for the {@link @PostLoad} lifecycle event. + * + * @param entity + * the model entity + */ + default void postLoad(final Object entity) { + }; + + /** + * Callback for the {@link @PreUpdate} lifecycle event. + * + * @param entity + * the model entity + */ + default void preUpdate(final Object entity) { + }; + + /** + * Callback for the {@link @PostUpdate} lifecycle event. + * + * @param entity + * the model entity + */ + default void postUpdate(final Object entity) { + }; + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java index 7236cbe79..f06d44516 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/RepositoryApplicationConfiguration.java @@ -46,6 +46,7 @@ import org.eclipse.hawkbit.repository.jpa.aspects.ExceptionMappingAspectHandler; import org.eclipse.hawkbit.repository.jpa.configuration.MultiTenantJpaTransactionManager; import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.CacheManagerHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.SystemManagementHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; @@ -144,6 +145,14 @@ public class RepositoryApplicationConfiguration extends JpaBaseConfiguration { return SecurityTokenGeneratorHolder.getInstance(); } + /** + * @return the singleton instance of the {@link EntityInterceptorHolder} + */ + @Bean + public EntityInterceptorHolder entityInterceptorHolder() { + return EntityInterceptorHolder.getInstance(); + } + /** * @return the singleton instance of the {@link CacheManagerHolder} */ diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java index 257828c6f..ca8ac60df 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/AbstractJpaBaseEntity.java @@ -31,7 +31,8 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; */ @MappedSuperclass @Access(AccessType.FIELD) -@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class }) +@EntityListeners({ AuditingEntityListener.class, CacheFieldEntityListener.class, EntityPropertyChangeListener.class, + EntityInterceptorListener.class }) public abstract class AbstractJpaBaseEntity implements BaseEntity { private static final long serialVersionUID = 1L; diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java new file mode 100644 index 000000000..15062f27f --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java @@ -0,0 +1,69 @@ +/** + * 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.jpa.model; + +import javax.persistence.PostLoad; +import javax.persistence.PostPersist; +import javax.persistence.PostRemove; +import javax.persistence.PostUpdate; +import javax.persistence.PrePersist; +import javax.persistence.PreRemove; +import javax.persistence.PreUpdate; + +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder; + +/** + * Entity listener which calls all entity interceptor for the lifecyles + * callbacks. + */ +public class EntityInterceptorListener { + + @PrePersist + protected void prePersist(final Object entity) { + EntityInterceptorHolder.getInstance().getEntityInterceptors() + .forEach(interceptor -> interceptor.prePersist(entity)); + } + + @PostPersist + protected void postPersist(final Object entity) { + EntityInterceptorHolder.getInstance().getEntityInterceptors() + .forEach(interceptor -> interceptor.postPersist(entity)); + } + + @PostRemove + protected void postRemove(final Object entity) { + EntityInterceptorHolder.getInstance().getEntityInterceptors() + .forEach(interceptor -> interceptor.postRemove(entity)); + } + + @PreRemove + protected void preRemove(final Object entity) { + EntityInterceptorHolder.getInstance().getEntityInterceptors() + .forEach(interceptor -> interceptor.preRemove(entity)); + } + + @PostLoad + protected void postLoad(final Object entity) { + EntityInterceptorHolder.getInstance().getEntityInterceptors() + .forEach(interceptor -> interceptor.postLoad(entity)); + } + + @PreUpdate + protected void preUpdate(final Object entity) { + EntityInterceptorHolder.getInstance().getEntityInterceptors() + .forEach(interceptor -> interceptor.preUpdate(entity)); + } + + @PostUpdate + protected void postUpdate(final Object entity) { + EntityInterceptorHolder.getInstance().getEntityInterceptors() + .forEach(interceptor -> interceptor.postUpdate(entity)); + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java new file mode 100644 index 000000000..8153ddc32 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java @@ -0,0 +1,42 @@ +/** + * 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.jpa.model.helper; + +import java.util.List; + +import org.eclipse.hawkbit.repository.model.EntityInterceptor; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * A singleton bean which holds the {@link EntityInterceptor} to have all + * interceptors in spring beans. + * + */ +public final class EntityInterceptorHolder { + + private static final EntityInterceptorHolder SINGLETON = new EntityInterceptorHolder(); + + @Autowired + private List entityInterceptors; + + private EntityInterceptorHolder() { + + } + + /** + * @return the entity intreceptor holder singleton instance + */ + public static EntityInterceptorHolder getInstance() { + return SINGLETON; + } + + public List getEntityInterceptors() { + return entityInterceptors; + } +} From bf28a8dde8764522c00085614b79b85da84216a0 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 28 Jul 2016 14:07:19 +0200 Subject: [PATCH 031/118] Fixed the issue for metadata not getting updated and also the refresh of page not displaying the distribution details in deployment and distribution view. Signed-off-by: Gaurav --- .../repository/DistributionSetManagement.java | 1206 +++++++-------- .../repository/SoftwareManagement.java | 990 ++++++------ .../jpa/JpaDistributionSetManagement.java | 61 +- .../repository/jpa/JpaSoftwareManagement.java | 1335 +++++++++-------- .../AbstractTableDetailsLayout.java | 1 - .../DistributionSetMetadatadetailslayout.java | 112 +- .../SoftwareModuleMetadatadetailslayout.java | 4 +- .../dstable/DistributionSetDetails.java | 65 +- .../dstable/DsMetadataPopupLayout.java | 32 +- .../ui/distributions/event/MetadataEvent.java | 9 +- .../DistributionAddUpdateWindowLayout.java | 10 +- .../dstable/DistributionDetails.java | 69 +- 12 files changed, 1936 insertions(+), 1958 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index a2e7e5213..f7566b86b 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -1,598 +1,608 @@ -/** - * 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; - -import java.util.Collection; -import java.util.List; -import java.util.Set; - -import javax.validation.constraints.NotNull; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.exception.DistributionSetCreationFailedMissingMandatoryModuleException; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetFilter; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; -import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; -import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.Tag; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder; -import org.hibernate.validator.constraints.NotEmpty; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.security.access.prepost.PreAuthorize; - -/** - * Management service for {@link DistributionSet}s. - * - */ -public interface DistributionSetManagement { - - // TODO rename/document the whole with details thing (document what the - // details are and maybe find a better name, e.g. with dependencies?) - - /** - * Assigns {@link SoftwareModule} to existing {@link DistributionSet}. - * - * @param ds - * to assign and update - * @param softwareModules - * to get assigned - * @return the updated {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet assignSoftwareModules(@NotNull DistributionSet ds, Set softwareModules); - - /** - * Assign a {@link DistributionSetTag} assignment to given - * {@link DistributionSet}s. - * - * @param dsIds - * to assign for - * @param tag - * to assign - * @return list of assigned ds - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List assignTag(@NotEmpty Collection dsIds, @NotNull DistributionSetTag tag); - - /** - * Count all {@link DistributionSet}s in the repository that are not marked - * as deleted. - * - * @return number of {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetsAll(); - - /** - * Count all {@link DistributionSet}s in the repository that are not marked - * as deleted. - * - * @param type - * to look for - * - * @return number of {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetsByType(@NotNull DistributionSetType type); - - /** - * @return number of {@link DistributionSetType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetTypesAll(); - - /** - * Creates a new {@link DistributionSet}. - * - * @param dSet - * {@link DistributionSet} to be created - * @return the new persisted {@link DistributionSet} - * - * @throws EntityAlreadyExistsException - * if a given entity already exists - * @throws DistributionSetCreationFailedMissingMandatoryModuleException - * is {@link DistributionSet} does not contain mandatory - * {@link SoftwareModule}s. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - DistributionSet createDistributionSet(@NotNull DistributionSet dSet); - - /** - * creates a list of distribution set meta data entries. - * - * @param metadata - * the meta data entries to create or update - * @return the updated or created distribution set meta data entries - * @throws EntityAlreadyExistsException - * in case one of the meta data entry already exists for the - * specific key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List createDistributionSetMetadata(@NotEmpty Collection metadata); - - /** - * creates or updates a single distribution set meta data entry. - * - * @param metadata - * the meta data entry to create or update - * @return the updated or created distribution set meta data entry - * @throws EntityAlreadyExistsException - * in case the meta data entry already exists for the specific - * key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetMetadata createDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); - - /** - * Creates multiple {@link DistributionSet}s. - * - * @param distributionSets - * to be created - * @return the new {@link DistributionSet}s - * @throws EntityAlreadyExistsException - * if a given entity already exists - * @throws DistributionSetCreationFailedMissingMandatoryModuleException - * is {@link DistributionSet} does not contain mandatory - * {@link SoftwareModule}s. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createDistributionSets(@NotNull Collection distributionSets); - - /** - * Creates new {@link DistributionSetType}. - * - * @param type - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - DistributionSetType createDistributionSetType(@NotNull DistributionSetType type); - - /** - * Creates multiple {@link DistributionSetType}s. - * - * @param types - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createDistributionSetTypes(@NotNull Collection types); - - /** - *

- * {@link DistributionSet} can be deleted/erased from the repository if they - * have never been assigned to any {@link UpdateAction} or {@link Target}. - *

- * - *

- * If they have been assigned that need to be marked as deleted which as a - * result means that they cannot be assigned anymore to any targets. (define - * e.g. findByDeletedFalse()) - *

- * - * @param set - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSet(@NotNull DistributionSet set); - - /** - * Deleted {@link DistributionSet}s by their IDs. That is either a soft - * delete of the entities have been linked to an {@link UpdateAction} before - * or a hard delete if not. - * - * @param distributionSetIDs - * to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSet(@NotEmpty Long... distributionSetIDs); - - /** - * deletes a distribution set meta data entry. - * - * @param id - * the ID of the distribution set meta data to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - void deleteDistributionSetMetadata(@NotNull final DistributionSet distributionSet, @NotNull final String key); - - /** - * Deletes or mark as delete in case the type is in use. - * - * @param type - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSetType(@NotNull DistributionSetType type); - - /** - * retrieves the distribution set for a given action. - * - * @param action - * the action associated with the distribution set - * @return the distribution set which is associated with the action - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByAction(@NotNull Action action); - - /** - * Find {@link DistributionSet} based on given ID without details, e.g. - * {@link DistributionSet#getAgentHub()}. - * - * @param distid - * to look for. - * @return {@link DistributionSet} or null if it does not exist - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetById(@NotNull Long distid); - - /** - * Find {@link DistributionSet} based on given ID including (lazy loaded) - * details, e.g. {@link DistributionSet#getAgentHub()}. - * - * Note: for performance reasons it is recommended to use - * {@link #findDistributionSetById(Long)} if details are not necessary. - * - * @param distid - * to look for. - * @return {@link DistributionSet} or null if it does not exist - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByIdWithDetails(@NotNull Long distid); - - /** - * Find distribution set by name and version. - * - * @param distributionName - * name of {@link DistributionSet}; case insensitive - * @param version - * version of {@link DistributionSet} - * @return the page with the found {@link DistributionSet} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version); - - /** - * finds all meta data by the given distribution set id. - * - * @param distributionSetId - * the distribution set id to retrieve the meta data from - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given distribution - * set id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, - @NotNull Pageable pageable); - - /** - * finds all meta data by the given distribution set id. - * - * @param distributionSetId - * the distribution set id to retrieve the meta data from - * @param rsqlParam - * rsql query string - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given distribution - * set id - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, - @NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Retrieves {@link DistributionSet} List for overview purposes (no - * {@link SoftwareModule}s and {@link DistributionSetTag}s). - * - * Please use {@link #findDistributionSetListWithDetails(Iterable)} if - * details are required. - * - * @param dist - * List of {@link DistributionSet} IDs to be found - * @return the found {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - List findDistributionSetsAll(Collection dist); - - // TODO discuss: use enum instead of the true,false,null switch ? - /** - * finds all {@link DistributionSet}s. - * - * @param pageReq - * the pagination parameter - * @param deleted - * if TRUE, {@link DistributionSet}s marked as deleted are - * returned. If FALSE, on {@link DistributionSet}s with - * {@link DistributionSet#isDeleted()} == FALSE are returned. - * null if both are to be returned - * @param complete - * to true for returning only completed distribution - * sets or false for only incomplete ones nor - * null to return both. - * @param complete - * set to if false incomplete DS should also be - * shown. - * - * - * @return all found {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsByDeletedAndOrCompleted(@NotNull Pageable pageReq, Boolean deleted, - Boolean complete); - - /** - * finds all {@link DistributionSet}s. - * - * @param rsqlParam - * rsql query string - * @param pageReq - * the pagination parameter - * @param deleted - * if TRUE, {@link DistributionSet}s marked as deleted are - * returned. If FALSE, on {@link DistributionSet}s with - * {@link DistributionSet#isDeleted()} == FALSE are returned. - * null if both are to be returned - * @return all found {@link DistributionSet}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsAll(@NotNull String rsqlParam, @NotNull Pageable pageReq, - Boolean deleted); - - /** - * method retrieves all {@link DistributionSet}s from the repository in the - * following order: - *

- * 1) {@link DistributionSet}s which have the given {@link Target} as - * {@link TargetStatus#getInstalledDistributionSet()} - *

- * 2) {@link DistributionSet}s which have the given {@link Target} as - * {@link Target#getAssignedDistributionSet()} - *

- * 3) {@link DistributionSet}s which have no connection to the given - * {@link Target} ordered by ID of the DistributionSet. - * - * @param pageable - * the page request to page the result set * - * @param distributionSetFilterBuilder - * has details of filters to be applied - * @param assignedOrInstalled - * the controllerID of the Target to be ordered by - * @return - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsAllOrderedByLinkTarget(@NotNull Pageable pageable, - @NotNull DistributionSetFilterBuilder distributionSetFilterBuilder, @NotEmpty String assignedOrInstalled); - - /** - * retrieves {@link DistributionSet}s by filtering on the given parameters. - * - * @param pageable - * page parameter - * @param distributionSetFilter - * has details of filters to be applied. - * @return the page of found {@link DistributionSet} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsByFilters(@NotNull Pageable pageable, - @NotNull DistributionSetFilter distributionSetFilter); - - /** - * @param id - * as {@link DistributionSetType#getId()} - * @return {@link DistributionSetType} if found or null if not - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeById(@NotNull Long id); - - /** - * @param key - * as {@link DistributionSetType#getKey()} - * @return {@link DistributionSetType} if found or null if not - */ - - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeByKey(@NotNull String key); - - /** - * @param name - * as {@link DistributionSetType#getName()} - * @return {@link DistributionSetType} if found or null if not - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeByName(@NotEmpty String name); - - /** - * @param pageable - * parameter - * @return all {@link DistributionSetType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetTypesAll(@NotNull Pageable pageable); - - /** - * Generic predicate based query for {@link DistributionSetType}. - * - * @param rsqlParam - * rsql query string - * @param pageable - * parameter for paging - * - * @return the found {@link SoftwareModuleType}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * finds a single distribution set meta data by its id. - * - * @param id - * the id of the distribution set meta data containing the meta - * data key and the ID of the distribution set - * @return the found DistributionSetMetadata or {@code null} if not exits - * @throws EntityNotFoundException - * in case the meta data does not exists for the given key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetMetadata findOne(@NotNull DistributionSet distributionSet, @NotNull String key); - - /** - * Checks if a {@link DistributionSet} is currently in use by a target in - * the repository. - * - * @param distributionSet - * to check - * - * @return true if in use - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - boolean isDistributionSetInUse(@NotNull DistributionSet distributionSet); - - /** - * {@link Entity} based method call for - * {@link #toggleTagAssignment(Collection, String)}. - * - * @param sets - * to toggle for - * @param tag - * to toggle - * @return {@link DistributionSetTagAssignmentResult} with all meta data of - * the assignment outcome. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection sets, - @NotNull DistributionSetTag tag); - - /** - * Toggles {@link DistributionSetTag} assignment to given - * {@link DistributionSet}s by means that if some (or all) of the targets in - * the list have the {@link Tag} not yet assigned, they will be. If all of - * theme have the tag already assigned they will be removed instead. - * - * @param dsIds - * to toggle for - * @param tagName - * to toggle - * @return {@link DistributionSetTagAssignmentResult} with all meta data of - * the assignment outcome. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection dsIds, @NotNull String tagName); - - /** - * Unassign all {@link DistributionSet} from a given - * {@link DistributionSetTag} . - * - * @param tag - * to unassign all ds - * @return list of unassigned ds - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List unAssignAllDistributionSetsByTag(@NotNull DistributionSetTag tag); - - /** - * Unassigns a {@link SoftwareModule} form an existing - * {@link DistributionSet}. - * - * @param ds - * to get unassigned form - * @param softwareModule - * to get unassigned - * @return the updated {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet unassignSoftwareModule(@NotNull DistributionSet ds, @NotNull SoftwareModule softwareModule); - - /** - * Unassign a {@link DistributionSetTag} assignment to given - * {@link DistributionSet}. - * - * @param dsId - * to unassign for - * @param distributionSetTag - * to unassign - * @return the unassigned ds or if no ds is unassigned - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet unAssignTag(@NotNull Long dsId, @NotNull DistributionSetTag distributionSetTag); - - /** - * Updates existing {@link DistributionSet}. - * - * @param ds - * to update - * @return the saved {@link Entity}. - * @throws NullPointerException - * of {@link DistributionSet#getId()} is null - * @throw DataDependencyViolationException in case of illegal update - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet updateDistributionSet(@NotNull DistributionSet ds); - - /** - * updates a distribution set meta data value if corresponding entry exists. - * - * @param metadata - * the meta data entry to be updated - * @return the updated meta data entry - * @throws EntityNotFoundException - * in case the meta data entry does not exists and cannot be - * updated - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetMetadata updateDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); - - /** - * Updates existing {@link DistributionSetType}. However, keep in mind that - * is not possible to change the {@link DistributionSetTypeElement}s while - * the DS type is already in use. - * - * @param dsType - * to update - * @return updated {@link Entity} - * - * @throws EntityReadOnlyException - * if use tries to change the {@link DistributionSetTypeElement} - * s while the DS type is already in use. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetType updateDistributionSetType(@NotNull DistributionSetType dsType); - -} +/** + * 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; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import javax.validation.constraints.NotNull; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.exception.DistributionSetCreationFailedMissingMandatoryModuleException; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetFilter; +import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder; +import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.repository.model.Tag; +import org.eclipse.hawkbit.repository.model.Target; +import org.hibernate.validator.constraints.NotEmpty; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.access.prepost.PreAuthorize; + +/** + * Management service for {@link DistributionSet}s. + * + */ +public interface DistributionSetManagement { + + // TODO rename/document the whole with details thing (document what the + // details are and maybe find a better name, e.g. with dependencies?) + + /** + * Assigns {@link SoftwareModule} to existing {@link DistributionSet}. + * + * @param ds + * to assign and update + * @param softwareModules + * to get assigned + * @return the updated {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet assignSoftwareModules(@NotNull DistributionSet ds, Set softwareModules); + + /** + * Assign a {@link DistributionSetTag} assignment to given + * {@link DistributionSet}s. + * + * @param dsIds + * to assign for + * @param tag + * to assign + * @return list of assigned ds + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List assignTag(@NotEmpty Collection dsIds, @NotNull DistributionSetTag tag); + + /** + * Count all {@link DistributionSet}s in the repository that are not marked + * as deleted. + * + * @return number of {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetsAll(); + + /** + * Count all {@link DistributionSet}s in the repository that are not marked + * as deleted. + * + * @param type + * to look for + * + * @return number of {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetsByType(@NotNull DistributionSetType type); + + /** + * @return number of {@link DistributionSetType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetTypesAll(); + + /** + * Creates a new {@link DistributionSet}. + * + * @param dSet + * {@link DistributionSet} to be created + * @return the new persisted {@link DistributionSet} + * + * @throws EntityAlreadyExistsException + * if a given entity already exists + * @throws DistributionSetCreationFailedMissingMandatoryModuleException + * is {@link DistributionSet} does not contain mandatory + * {@link SoftwareModule}s. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + DistributionSet createDistributionSet(@NotNull DistributionSet dSet); + + /** + * creates a list of distribution set meta data entries. + * + * @param metadata + * the meta data entries to create or update + * @return the updated or created distribution set meta data entries + * @throws EntityAlreadyExistsException + * in case one of the meta data entry already exists for the + * specific key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List createDistributionSetMetadata(@NotEmpty Collection metadata); + + /** + * creates or updates a single distribution set meta data entry. + * + * @param metadata + * the meta data entry to create or update + * @return the updated or created distribution set meta data entry + * @throws EntityAlreadyExistsException + * in case the meta data entry already exists for the specific + * key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetMetadata createDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); + + /** + * Creates multiple {@link DistributionSet}s. + * + * @param distributionSets + * to be created + * @return the new {@link DistributionSet}s + * @throws EntityAlreadyExistsException + * if a given entity already exists + * @throws DistributionSetCreationFailedMissingMandatoryModuleException + * is {@link DistributionSet} does not contain mandatory + * {@link SoftwareModule}s. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createDistributionSets(@NotNull Collection distributionSets); + + /** + * Creates new {@link DistributionSetType}. + * + * @param type + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + DistributionSetType createDistributionSetType(@NotNull DistributionSetType type); + + /** + * Creates multiple {@link DistributionSetType}s. + * + * @param types + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createDistributionSetTypes(@NotNull Collection types); + + /** + *

+ * {@link DistributionSet} can be deleted/erased from the repository if they + * have never been assigned to any {@link UpdateAction} or {@link Target}. + *

+ * + *

+ * If they have been assigned that need to be marked as deleted which as a + * result means that they cannot be assigned anymore to any targets. (define + * e.g. findByDeletedFalse()) + *

+ * + * @param set + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSet(@NotNull DistributionSet set); + + /** + * Deleted {@link DistributionSet}s by their IDs. That is either a soft + * delete of the entities have been linked to an {@link UpdateAction} before + * or a hard delete if not. + * + * @param distributionSetIDs + * to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSet(@NotEmpty Long... distributionSetIDs); + + /** + * deletes a distribution set meta data entry. + * + * @param id + * the ID of the distribution set meta data to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + void deleteDistributionSetMetadata(@NotNull final DistributionSet distributionSet, @NotNull final String key); + + /** + * Deletes or mark as delete in case the type is in use. + * + * @param type + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSetType(@NotNull DistributionSetType type); + + /** + * retrieves the distribution set for a given action. + * + * @param action + * the action associated with the distribution set + * @return the distribution set which is associated with the action + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByAction(@NotNull Action action); + + /** + * Find {@link DistributionSet} based on given ID without details, e.g. + * {@link DistributionSet#getAgentHub()}. + * + * @param distid + * to look for. + * @return {@link DistributionSet} or null if it does not exist + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetById(@NotNull Long distid); + + /** + * Find {@link DistributionSet} based on given ID including (lazy loaded) + * details, e.g. {@link DistributionSet#getAgentHub()}. + * + * Note: for performance reasons it is recommended to use + * {@link #findDistributionSetById(Long)} if details are not necessary. + * + * @param distid + * to look for. + * @return {@link DistributionSet} or null if it does not exist + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByIdWithDetails(@NotNull Long distid); + + /** + * Find distribution set by name and version. + * + * @param distributionName + * name of {@link DistributionSet}; case insensitive + * @param version + * version of {@link DistributionSet} + * @return the page with the found {@link DistributionSet} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given distribution + * set id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, + @NotNull Pageable pageable); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @return list of distributionSetMetadata for a given distribution set Id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @param rsqlParam + * rsql query string + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given distribution + * set id + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, + @NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Retrieves {@link DistributionSet} List for overview purposes (no + * {@link SoftwareModule}s and {@link DistributionSetTag}s). + * + * Please use {@link #findDistributionSetListWithDetails(Iterable)} if + * details are required. + * + * @param dist + * List of {@link DistributionSet} IDs to be found + * @return the found {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findDistributionSetsAll(Collection dist); + + // TODO discuss: use enum instead of the true,false,null switch ? + /** + * finds all {@link DistributionSet}s. + * + * @param pageReq + * the pagination parameter + * @param deleted + * if TRUE, {@link DistributionSet}s marked as deleted are + * returned. If FALSE, on {@link DistributionSet}s with + * {@link DistributionSet#isDeleted()} == FALSE are returned. + * null if both are to be returned + * @param complete + * to true for returning only completed distribution + * sets or false for only incomplete ones nor + * null to return both. + * @param complete + * set to if false incomplete DS should also be + * shown. + * + * + * @return all found {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsByDeletedAndOrCompleted(@NotNull Pageable pageReq, Boolean deleted, + Boolean complete); + + /** + * finds all {@link DistributionSet}s. + * + * @param rsqlParam + * rsql query string + * @param pageReq + * the pagination parameter + * @param deleted + * if TRUE, {@link DistributionSet}s marked as deleted are + * returned. If FALSE, on {@link DistributionSet}s with + * {@link DistributionSet#isDeleted()} == FALSE are returned. + * null if both are to be returned + * @return all found {@link DistributionSet}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsAll(@NotNull String rsqlParam, @NotNull Pageable pageReq, + Boolean deleted); + + /** + * method retrieves all {@link DistributionSet}s from the repository in the + * following order: + *

+ * 1) {@link DistributionSet}s which have the given {@link Target} as + * {@link TargetStatus#getInstalledDistributionSet()} + *

+ * 2) {@link DistributionSet}s which have the given {@link Target} as + * {@link Target#getAssignedDistributionSet()} + *

+ * 3) {@link DistributionSet}s which have no connection to the given + * {@link Target} ordered by ID of the DistributionSet. + * + * @param pageable + * the page request to page the result set * + * @param distributionSetFilterBuilder + * has details of filters to be applied + * @param assignedOrInstalled + * the controllerID of the Target to be ordered by + * @return + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsAllOrderedByLinkTarget(@NotNull Pageable pageable, + @NotNull DistributionSetFilterBuilder distributionSetFilterBuilder, @NotEmpty String assignedOrInstalled); + + /** + * retrieves {@link DistributionSet}s by filtering on the given parameters. + * + * @param pageable + * page parameter + * @param distributionSetFilter + * has details of filters to be applied. + * @return the page of found {@link DistributionSet} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsByFilters(@NotNull Pageable pageable, + @NotNull DistributionSetFilter distributionSetFilter); + + /** + * @param id + * as {@link DistributionSetType#getId()} + * @return {@link DistributionSetType} if found or null if not + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeById(@NotNull Long id); + + /** + * @param key + * as {@link DistributionSetType#getKey()} + * @return {@link DistributionSetType} if found or null if not + */ + + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeByKey(@NotNull String key); + + /** + * @param name + * as {@link DistributionSetType#getName()} + * @return {@link DistributionSetType} if found or null if not + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeByName(@NotEmpty String name); + + /** + * @param pageable + * parameter + * @return all {@link DistributionSetType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetTypesAll(@NotNull Pageable pageable); + + /** + * Generic predicate based query for {@link DistributionSetType}. + * + * @param rsqlParam + * rsql query string + * @param pageable + * parameter for paging + * + * @return the found {@link SoftwareModuleType}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * finds a single distribution set meta data by its id. + * + * @param id + * the id of the distribution set meta data containing the meta + * data key and the ID of the distribution set + * @return the found DistributionSetMetadata or {@code null} if not exits + * @throws EntityNotFoundException + * in case the meta data does not exists for the given key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetMetadata findOne(@NotNull DistributionSet distributionSet, @NotNull String key); + + /** + * Checks if a {@link DistributionSet} is currently in use by a target in + * the repository. + * + * @param distributionSet + * to check + * + * @return true if in use + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + boolean isDistributionSetInUse(@NotNull DistributionSet distributionSet); + + /** + * {@link Entity} based method call for + * {@link #toggleTagAssignment(Collection, String)}. + * + * @param sets + * to toggle for + * @param tag + * to toggle + * @return {@link DistributionSetTagAssignmentResult} with all meta data of + * the assignment outcome. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection sets, + @NotNull DistributionSetTag tag); + + /** + * Toggles {@link DistributionSetTag} assignment to given + * {@link DistributionSet}s by means that if some (or all) of the targets in + * the list have the {@link Tag} not yet assigned, they will be. If all of + * theme have the tag already assigned they will be removed instead. + * + * @param dsIds + * to toggle for + * @param tagName + * to toggle + * @return {@link DistributionSetTagAssignmentResult} with all meta data of + * the assignment outcome. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection dsIds, @NotNull String tagName); + + /** + * Unassign all {@link DistributionSet} from a given + * {@link DistributionSetTag} . + * + * @param tag + * to unassign all ds + * @return list of unassigned ds + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List unAssignAllDistributionSetsByTag(@NotNull DistributionSetTag tag); + + /** + * Unassigns a {@link SoftwareModule} form an existing + * {@link DistributionSet}. + * + * @param ds + * to get unassigned form + * @param softwareModule + * to get unassigned + * @return the updated {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet unassignSoftwareModule(@NotNull DistributionSet ds, @NotNull SoftwareModule softwareModule); + + /** + * Unassign a {@link DistributionSetTag} assignment to given + * {@link DistributionSet}. + * + * @param dsId + * to unassign for + * @param distributionSetTag + * to unassign + * @return the unassigned ds or if no ds is unassigned + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet unAssignTag(@NotNull Long dsId, @NotNull DistributionSetTag distributionSetTag); + + /** + * Updates existing {@link DistributionSet}. + * + * @param ds + * to update + * @return the saved {@link Entity}. + * @throws NullPointerException + * of {@link DistributionSet#getId()} is null + * @throw DataDependencyViolationException in case of illegal update + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet updateDistributionSet(@NotNull DistributionSet ds); + + /** + * updates a distribution set meta data value if corresponding entry exists. + * + * @param metadata + * the meta data entry to be updated + * @return the updated meta data entry + * @throws EntityNotFoundException + * in case the meta data entry does not exists and cannot be + * updated + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetMetadata updateDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); + + /** + * Updates existing {@link DistributionSetType}. However, keep in mind that + * is not possible to change the {@link DistributionSetTypeElement}s while + * the DS type is already in use. + * + * @param dsType + * to update + * @return updated {@link Entity} + * + * @throws EntityReadOnlyException + * if use tries to change the {@link DistributionSetTypeElement} + * s while the DS type is already in use. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetType updateDistributionSetType(@NotNull DistributionSetType dsType); + +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java index 0934e871e..e48aaa3ab 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java @@ -1,486 +1,504 @@ -/** - * 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; - -import java.util.Collection; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.hibernate.validator.constraints.NotEmpty; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.security.access.prepost.PreAuthorize; - -/** - * Service for managing {@link SoftwareModule}s. - * - */ -public interface SoftwareManagement { - - /** - * Counts {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * and {@link SoftwareModule#getType()} that are not marked as deleted. - * - * @param searchText - * to search for in name and version - * @param type - * to filter the result - * @return number of found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModuleByFilters(String searchText, SoftwareModuleType type); - - /** - * Count all {@link SoftwareModule}s in the repository that are not marked - * as deleted. - * - * @return number of {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModulesAll(); - - /** - * Counts {@link SoftwareModule}s with given {@link SoftwareModuleType}. - * - * @param type - * to count - * @return number of found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModulesByType(@NotNull SoftwareModuleType type); - - /** - * @return number of {@link SoftwareModuleType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModuleTypesAll(); - - /** - * Create {@link SoftwareModule}s in the repository. - * - * @param swModules - * {@link SoftwareModule}s to create - * @return SoftwareModule - * @throws EntityAlreadyExistsException - * if a given entity already exists - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createSoftwareModule(@NotNull Collection swModules); - - /** - * - * @param swModule - * SoftwareModule to create - * @return SoftwareModule - * @throws EntityAlreadyExistsException - * if a given entity already exists - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - SoftwareModule createSoftwareModule(@NotNull SoftwareModule swModule); - - /** - * creates a list of software module meta data entries. - * - * @param metadata - * the meta data entries to create or update - * @return the updated or created software module meta data entries - * @throws EntityAlreadyExistsException - * in case one of the meta data entry already exists for the - * specific key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List createSoftwareModuleMetadata(@NotNull Collection metadata); - - /** - * creates or updates a single software module meta data entry. - * - * @param metadata - * the meta data entry to create or update - * @return the updated or created software module meta data entry - * @throws EntityAlreadyExistsException - * in case the meta data entry already exists for the specific - * key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleMetadata createSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); - - /** - * Creates multiple {@link SoftwareModuleType}s. - * - * @param types - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createSoftwareModuleType(@NotNull final Collection types); - - /** - * Creates new {@link SoftwareModuleType}. - * - * @param type - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - SoftwareModuleType createSoftwareModuleType(@NotNull SoftwareModuleType type); - - /** - * Deletes the given {@link SoftwareModule} {@link Entity}. - * - * @param bsm - * is the {@link SoftwareModule} to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModule(@NotNull SoftwareModule bsm); - - /** - * deletes a software module meta data entry. - * - * @param id - * the ID of the software module meta data to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - void deleteSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotNull String key); - - /** - * Deletes {@link SoftwareModule}s which is any if the given ids. - * - * @param ids - * of the Software Modules to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModules(@NotNull Collection ids); - - /** - * Deletes or marks as delete in case the type is in use. - * - * @param type - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModuleType(@NotNull SoftwareModuleType type); - - /** - * @param pageable - * the page request to page the result set - * @param set - * to search for - * @return all {@link SoftwareModule}s that are assigned to given - * {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleByAssignedTo(@NotNull Pageable pageable, @NotNull DistributionSet set); - - /** - * @param pageable - * the page request to page the result set - * @param set - * to search for - * @param type - * to filter - * @return all {@link SoftwareModule}s that are assigned to given - * {@link DistributionSet} filtered by {@link SoftwareModuleType}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleByAssignedToAndType(@NotNull Pageable pageable, @NotNull DistributionSet set, - @NotNull SoftwareModuleType type); - - /** - * Filter {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * and {@link SoftwareModule#getType()} that are not marked as deleted. - * - * @param pageable - * page parameter - * @param searchText - * to be filtered as "like" on {@link SoftwareModule#getName()} - * @param type - * to be filtered as "like" on {@link SoftwareModule#getType()} - * @return the page of found {@link SoftwareModule} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModuleByFilters(@NotNull Pageable pageable, String searchText, - SoftwareModuleType type); - - /** - * Finds {@link SoftwareModule} by given id. - * - * @param id - * to search for - * @return the found {@link SoftwareModule}s or null if not - * found. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_CONTROLLER) - SoftwareModule findSoftwareModuleById(@NotNull Long id); - - /** - * retrieves {@link SoftwareModule} by their name AND version AND type.. - * - * @param name - * of the {@link SoftwareModule} - * @param version - * of the {@link SoftwareModule} - * @param type - * of the {@link SoftwareModule} - * @return the found {@link SoftwareModule} or null - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModule findSoftwareModuleByNameAndVersion(@NotEmpty String name, @NotEmpty String version, - @NotNull SoftwareModuleType type); - - /** - * finds a single software module meta data by its id. - * - * @param id - * the id of the software module meta data containing the meta - * data key and the ID of the software module - * @return the found SoftwareModuleMetadata or {@code null} if not exits - * @throws EntityNotFoundException - * in case the meta data does not exists for the given key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleMetadata findSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotEmpty String key); - - /** - * finds all meta data by the given software module id. - * - * @param swId - * the software module id to retrieve the meta data from - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given software - * module id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long swId, - @NotNull Pageable pageable); - - /** - * finds all meta data by the given software module id. - * - * @param softwareModuleId - * the software module id to retrieve the meta data from - * @param spec - * the specification to filter the result - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given software - * module id - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long softwareModuleId, - @NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Filter {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * search text and {@link SoftwareModule#getType()} that are not marked as - * deleted and sort them by means of given distribution set related modules - * on top of the list. - * - * After that the modules are sorted by {@link SoftwareModule#getName()} and - * {@link SoftwareModule#getVersion()} in ascending order. - * - * @param pageable - * page parameter - * @param orderByDistributionId - * the ID of distribution set to be ordered on top - * @param searchText - * filtered as "like" on {@link SoftwareModule#getName()} - * @param type - * filtered as "equal" on {@link SoftwareModule#getType()} - * @return the page of found {@link SoftwareModule} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( - @NotNull Pageable pageable, @NotNull Long orderByDistributionId, String searchText, - SoftwareModuleType type); - - /** - * Retrieves all software modules. Deleted ones are filtered. - * - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModulesAll(@NotNull Pageable pageable); - - /** - * Retrieves all software modules with a given list of ids - * {@link SoftwareModule#getId()}. - * - * @param ids - * to search for - * @return {@link List} of found {@link SoftwareModule}s - */ - List findSoftwareModulesById(@NotEmpty Collection ids); - - /** - * Retrieves all {@link SoftwareModule}s with a given specification. - * - * @param spec - * the specification to filter the software modules - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModule}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModulesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType} - * . - * - * @param pageable - * page parameters - * @param type - * to be filtered on - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModulesByType(@NotNull Pageable pageable, @NotNull SoftwareModuleType type); - - /** - * - * @param id - * to search for - * @return {@link SoftwareModuleType} in the repository with given - * {@link SoftwareModuleType#getId()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeById(@NotNull Long id); - - /** - * - * @param key - * to search for - * @return {@link SoftwareModuleType} in the repository with given - * {@link SoftwareModuleType#getKey()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeByKey(@NotNull String key); - - /** - * - * @param name - * to search for - * @return all {@link SoftwareModuleType}s in the repository with given - * {@link SoftwareModuleType#getName()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeByName(@NotNull String name); - - /** - * @param pageable - * parameter - * @return all {@link SoftwareModuleType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleTypesAll(@NotNull Pageable pageable); - - /** - * Retrieves all {@link SoftwareModuleType}s with a given specification. - * - * @param spec - * the specification to filter the software modules types - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModuleType}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Retrieves software module including details ( - * {@link SoftwareModule#getArtifacts()}). - * - * @param id - * parameter - * @param isDeleted - * parameter - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModule findSoftwareModuleWithDetails(@NotNull Long id); - - /** - * Updates existing {@link SoftwareModule}. Update-able values are - * {@link SoftwareModule#getDescription()} - * {@link SoftwareModule#getVendor()}. - * - * @param sm - * to update - * - * @return the saved {@link Entity}. - * - * @throws NullPointerException - * of {@link SoftwareModule#getId()} is null - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModule updateSoftwareModule(@NotNull SoftwareModule sm); - - /** - * updates a distribution set meta data value if corresponding entry exists. - * - * @param metadata - * the meta data entry to be updated - * @return the updated meta data entry - * @throws EntityNotFoundException - * in case the meta data entry does not exists and cannot be - * updated - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleMetadata updateSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); - - /** - * Updates existing {@link SoftwareModuleType}. Update-able value is - * {@link SoftwareModuleType#getDescription()} and - * {@link SoftwareModuleType#getColour()}. - * - * @param sm - * to update - * @return updated {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm); - -} +/** + * 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; + +import java.util.Collection; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; +import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.hibernate.validator.constraints.NotEmpty; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.security.access.prepost.PreAuthorize; + +/** + * Service for managing {@link SoftwareModule}s. + * + */ +public interface SoftwareManagement { + + /** + * Counts {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * and {@link SoftwareModule#getType()} that are not marked as deleted. + * + * @param searchText + * to search for in name and version + * @param type + * to filter the result + * @return number of found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModuleByFilters(String searchText, SoftwareModuleType type); + + /** + * Count all {@link SoftwareModule}s in the repository that are not marked + * as deleted. + * + * @return number of {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModulesAll(); + + /** + * Counts {@link SoftwareModule}s with given {@link SoftwareModuleType}. + * + * @param type + * to count + * @return number of found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModulesByType(@NotNull SoftwareModuleType type); + + /** + * @return number of {@link SoftwareModuleType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModuleTypesAll(); + + /** + * Create {@link SoftwareModule}s in the repository. + * + * @param swModules + * {@link SoftwareModule}s to create + * @return SoftwareModule + * @throws EntityAlreadyExistsException + * if a given entity already exists + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createSoftwareModule(@NotNull Collection swModules); + + /** + * + * @param swModule + * SoftwareModule to create + * @return SoftwareModule + * @throws EntityAlreadyExistsException + * if a given entity already exists + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + SoftwareModule createSoftwareModule(@NotNull SoftwareModule swModule); + + /** + * creates a list of software module meta data entries. + * + * @param metadata + * the meta data entries to create or update + * @return the updated or created software module meta data entries + * @throws EntityAlreadyExistsException + * in case one of the meta data entry already exists for the + * specific key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List createSoftwareModuleMetadata(@NotNull Collection metadata); + + /** + * creates or updates a single software module meta data entry. + * + * @param metadata + * the meta data entry to create or update + * @return the updated or created software module meta data entry + * @throws EntityAlreadyExistsException + * in case the meta data entry already exists for the specific + * key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleMetadata createSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); + + /** + * Creates multiple {@link SoftwareModuleType}s. + * + * @param types + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createSoftwareModuleType(@NotNull final Collection types); + + /** + * Creates new {@link SoftwareModuleType}. + * + * @param type + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + SoftwareModuleType createSoftwareModuleType(@NotNull SoftwareModuleType type); + + /** + * Deletes the given {@link SoftwareModule} {@link Entity}. + * + * @param bsm + * is the {@link SoftwareModule} to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModule(@NotNull SoftwareModule bsm); + + /** + * deletes a software module meta data entry. + * + * @param id + * the ID of the software module meta data to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + void deleteSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotNull String key); + + /** + * Deletes {@link SoftwareModule}s which is any if the given ids. + * + * @param ids + * of the Software Modules to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModules(@NotNull Collection ids); + + /** + * Deletes or marks as delete in case the type is in use. + * + * @param type + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModuleType(@NotNull SoftwareModuleType type); + + /** + * @param pageable + * the page request to page the result set + * @param set + * to search for + * @return all {@link SoftwareModule}s that are assigned to given + * {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleByAssignedTo(@NotNull Pageable pageable, @NotNull DistributionSet set); + + /** + * @param pageable + * the page request to page the result set + * @param set + * to search for + * @param type + * to filter + * @return all {@link SoftwareModule}s that are assigned to given + * {@link DistributionSet} filtered by {@link SoftwareModuleType}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleByAssignedToAndType(@NotNull Pageable pageable, @NotNull DistributionSet set, + @NotNull SoftwareModuleType type); + + /** + * Filter {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * and {@link SoftwareModule#getType()} that are not marked as deleted. + * + * @param pageable + * page parameter + * @param searchText + * to be filtered as "like" on {@link SoftwareModule#getName()} + * @param type + * to be filtered as "like" on {@link SoftwareModule#getType()} + * @return the page of found {@link SoftwareModule} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModuleByFilters(@NotNull Pageable pageable, String searchText, + SoftwareModuleType type); + + /** + * Finds {@link SoftwareModule} by given id. + * + * @param id + * to search for + * @return the found {@link SoftwareModule}s or null if not + * found. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.IS_CONTROLLER) + SoftwareModule findSoftwareModuleById(@NotNull Long id); + + /** + * retrieves {@link SoftwareModule} by their name AND version AND type.. + * + * @param name + * of the {@link SoftwareModule} + * @param version + * of the {@link SoftwareModule} + * @param type + * of the {@link SoftwareModule} + * @return the found {@link SoftwareModule} or null + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModule findSoftwareModuleByNameAndVersion(@NotEmpty String name, @NotEmpty String version, + @NotNull SoftwareModuleType type); + + /** + * finds a single software module meta data by its id. + * + * @param id + * the id of the software module meta data containing the meta + * data key and the ID of the software module + * @return the found SoftwareModuleMetadata or {@code null} if not exits + * @throws EntityNotFoundException + * in case the meta data does not exists for the given key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleMetadata findSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotEmpty String key); + + /** + * finds all meta data by the given software module id. + * + * @param swId + * the software module id to retrieve the meta data from + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given software + * module id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long swId, + @NotNull Pageable pageable); + + /** + * finds all meta data by the given software module id. + * + * @param softwareModuleId + * the software module id to retrieve the meta data from + * @param spec + * the specification to filter the result + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given software + * module id + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long softwareModuleId, + @NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Filter {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * search text and {@link SoftwareModule#getType()} that are not marked as + * deleted and sort them by means of given distribution set related modules + * on top of the list. + * + * After that the modules are sorted by {@link SoftwareModule#getName()} and + * {@link SoftwareModule#getVersion()} in ascending order. + * + * @param pageable + * page parameter + * @param orderByDistributionId + * the ID of distribution set to be ordered on top + * @param searchText + * filtered as "like" on {@link SoftwareModule#getName()} + * @param type + * filtered as "equal" on {@link SoftwareModule#getType()} + * @return the page of found {@link SoftwareModule} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( + @NotNull Pageable pageable, @NotNull Long orderByDistributionId, String searchText, + SoftwareModuleType type); + + /** + * Retrieves all software modules. Deleted ones are filtered. + * + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModulesAll(@NotNull Pageable pageable); + + /** + * Retrieves all software modules with a given list of ids + * {@link SoftwareModule#getId()}. + * + * @param ids + * to search for + * @return {@link List} of found {@link SoftwareModule}s + */ + List findSoftwareModulesById(@NotEmpty Collection ids); + + /** + * Retrieves all {@link SoftwareModule}s with a given specification. + * + * @param spec + * the specification to filter the software modules + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModule}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModulesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType} + * . + * + * @param pageable + * page parameters + * @param type + * to be filtered on + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModulesByType(@NotNull Pageable pageable, @NotNull SoftwareModuleType type); + + /** + * + * @param id + * to search for + * @return {@link SoftwareModuleType} in the repository with given + * {@link SoftwareModuleType#getId()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeById(@NotNull Long id); + + /** + * + * @param key + * to search for + * @return {@link SoftwareModuleType} in the repository with given + * {@link SoftwareModuleType#getKey()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeByKey(@NotNull String key); + + /** + * + * @param name + * to search for + * @return all {@link SoftwareModuleType}s in the repository with given + * {@link SoftwareModuleType#getName()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeByName(@NotNull String name); + + /** + * @param pageable + * parameter + * @return all {@link SoftwareModuleType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleTypesAll(@NotNull Pageable pageable); + + /** + * Retrieves all {@link SoftwareModuleType}s with a given specification. + * + * @param spec + * the specification to filter the software modules types + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModuleType}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Retrieves software module including details ( + * {@link SoftwareModule#getArtifacts()}). + * + * @param id + * parameter + * @param isDeleted + * parameter + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModule findSoftwareModuleWithDetails(@NotNull Long id); + + /** + * Updates existing {@link SoftwareModule}. Update-able values are + * {@link SoftwareModule#getDescription()} + * {@link SoftwareModule#getVendor()}. + * + * @param sm + * to update + * + * @return the saved {@link Entity}. + * + * @throws NullPointerException + * of {@link SoftwareModule#getId()} is null + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModule updateSoftwareModule(@NotNull SoftwareModule sm); + + /** + * updates a distribution set meta data value if corresponding entry exists. + * + * @param metadata + * the meta data entry to be updated + * @return the updated meta data entry + * @throws EntityNotFoundException + * in case the meta data entry does not exists and cannot be + * updated + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleMetadata updateSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); + + /** + * Updates existing {@link SoftwareModuleType}. Update-able value is + * {@link SoftwareModuleType#getDescription()} and + * {@link SoftwareModuleType#getColour()}. + * + * @param sm + * to update + * @return updated {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm); + + /** + * finds all meta data by the given software module id. + * + * @param softwareModuleId + * the software module id to retrieve the meta data from + + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + * @return result of all meta data entries for a given software + * module id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findSoftwareModuleMetadataBySoftwareModuleId(Long softwareModuleId); + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index b94677fb9..306b9bd80 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -173,39 +173,36 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override @Modifying @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteDistributionSet(final Long... distributionSetIDs) { - final List toHardDelete = new ArrayList<>(); + public void deleteDistributionSet(final Long... distributionSetIDs) { + final List toHardDelete = new ArrayList<>(); - final List assigned = distributionSetRepository - .findAssignedToTargetDistributionSetsById(distributionSetIDs); - assigned.addAll(distributionSetRepository - .findAssignedToRolloutDistributionSetsById(distributionSetIDs)); + final List assigned = distributionSetRepository + .findAssignedToTargetDistributionSetsById(distributionSetIDs); + assigned.addAll(distributionSetRepository.findAssignedToRolloutDistributionSetsById(distributionSetIDs)); - // soft delete assigned - if (!assigned.isEmpty()) { - distributionSetRepository.deleteDistributionSet(assigned - .toArray(new Long[assigned.size()])); - } + // soft delete assigned + if (!assigned.isEmpty()) { + distributionSetRepository.deleteDistributionSet(assigned.toArray(new Long[assigned.size()])); + } - // mark the rest as hard delete - for (final Long setId : distributionSetIDs) { - if (!assigned.contains(setId)) { - toHardDelete.add(setId); - } - } + // mark the rest as hard delete + for (final Long setId : distributionSetIDs) { + if (!assigned.contains(setId)) { + toHardDelete.add(setId); + } + } - // hard delete the rest if exixts - if (!toHardDelete.isEmpty()) { - // don't give the delete statement an empty list, JPA/Oracle cannot - // handle the empty list - distributionSetRepository.deleteByIdIn(toHardDelete); - } + // hard delete the rest if exixts + if (!toHardDelete.isEmpty()) { + // don't give the delete statement an empty list, JPA/Oracle cannot + // handle the empty list + distributionSetRepository.deleteByIdIn(toHardDelete); + } - afterCommit.afterCommit(() -> eventBus - .post(new DistributionDeletedEvent(tenantAware - .getCurrentTenant(), distributionSetIDs))); + afterCommit.afterCommit( + () -> eventBus.post(new DistributionDeletedEvent(tenantAware.getCurrentTenant(), distributionSetIDs))); - } + } @Override @Modifying @@ -530,6 +527,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying public void deleteDistributionSetMetadata(final DistributionSet distributionSet, final String key) { + entityManager.merge((JpaDistributionSet) distributionSet).setLastModifiedAt(0L); distributionSetMetadataRepository.delete(new DsMetadataCompositeKey(distributionSet, key)); } @@ -544,6 +542,15 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { pageable); } + @Override + public List findDistributionSetMetadataByDistributionSetId(final Long distributionSetId) { + + return new ArrayList(distributionSetMetadataRepository + .findAll((Specification) (root, query, cb) -> cb.equal( + root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id), + distributionSetId))); + } + @Override public Page findDistributionSetMetadataByDistributionSetId(final Long distributionSetId, final String rsqlParam, final Pageable pageable) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index b561667a9..afe1a1e02 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -1,663 +1,672 @@ -/** - * 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.jpa; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.persistence.EntityManager; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.ListJoin; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.SoftwareManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleFields; -import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata_; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_; -import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; -import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; -import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification; -import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; -import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.LocalArtifact; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.AuditorAware; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.SliceImpl; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Isolation; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import com.google.common.base.Strings; -import com.google.common.collect.Sets; - -/** - * JPA implementation of {@link SoftwareManagement}. - * - */ -@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -@Validated -public class JpaSoftwareManagement implements SoftwareManagement { - - @Autowired - private EntityManager entityManager; - - @Autowired - private DistributionSetRepository distributionSetRepository; - - @Autowired - private DistributionSetTypeRepository distributionSetTypeRepository; - - @Autowired - private SoftwareModuleRepository softwareModuleRepository; - - @Autowired - private SoftwareModuleMetadataRepository softwareModuleMetadataRepository; - - @Autowired - private SoftwareModuleTypeRepository softwareModuleTypeRepository; - - @Autowired - private NoCountPagingRepository criteriaNoCountDao; - - @Autowired - private AuditorAware auditorProvider; - - @Autowired - private ArtifactManagement artifactManagement; - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModule updateSoftwareModule(final SoftwareModule sm) { - checkNotNull(sm.getId()); - - final JpaSoftwareModule module = softwareModuleRepository.findOne(sm.getId()); - - boolean updated = false; - if (null == sm.getDescription() || !sm.getDescription().equals(module.getDescription())) { - module.setDescription(sm.getDescription()); - updated = true; - } - if (null == sm.getVendor() || !sm.getVendor().equals(module.getVendor())) { - module.setVendor(sm.getVendor()); - updated = true; - } - - return updated ? softwareModuleRepository.save(module) : module; - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleType sm) { - checkNotNull(sm.getId()); - - final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); - - boolean updated = false; - if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) { - type.setDescription(sm.getDescription()); - updated = true; - } - if (sm.getColour() != null && !sm.getColour().equals(type.getColour())) { - type.setColour(sm.getColour()); - updated = true; - } - return updated ? softwareModuleTypeRepository.save(type) : type; - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModule createSoftwareModule(final SoftwareModule swModule) { - if (null != swModule.getId()) { - throw new EntityAlreadyExistsException(); - } - return softwareModuleRepository.save((JpaSoftwareModule) swModule); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List createSoftwareModule(final Collection swModules) { - swModules.forEach(swModule -> { - if (null != swModule.getId()) { - throw new EntityAlreadyExistsException(); - } - }); - - @SuppressWarnings({ "unchecked", "rawtypes" }) - final Collection jpaCast = (Collection) swModules; - - return new ArrayList<>(softwareModuleRepository.save(jpaCast)); - } - - @Override - public Slice findSoftwareModulesByType(final Pageable pageable, final SoftwareModuleType type) { - - final List> specList = new LinkedList<>(); - - Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - - spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - private static Slice convertSmPage(final Slice findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, 0); - } - - private static Page convertSmPage(final Page findAll, final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - private static Page convertSmMdPage(final Page findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - @Override - public Long countSoftwareModulesByType(final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - - spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public SoftwareModule findSoftwareModuleById(final Long id) { - return artifactManagement.findSoftwareModuleById(id); - } - - @Override - public SoftwareModule findSoftwareModuleByNameAndVersion(final String name, final String version, - final SoftwareModuleType type) { - - return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, (JpaSoftwareModuleType) type); - } - - private boolean isUnassigned(final JpaSoftwareModule bsmMerged) { - return distributionSetRepository.findByModules(bsmMerged).isEmpty(); - } - - private Slice findSwModuleByCriteriaAPI(final Pageable pageable, - final List> specList) { - return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, - JpaSoftwareModule.class); - } - - private Long countSwModuleByCriteriaAPI(final List> specList) { - return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList)); - } - - private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) { - for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) { - artifactManagement.deleteLocalArtifact(localArtifact); - } - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModules(final Collection ids) { - final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); - final Set assignedModuleIds = new HashSet<>(); - swModulesToDelete.forEach(swModule -> { - - // delete binary data of artifacts - deleteGridFsArtifacts(swModule); - - if (isUnassigned(swModule)) { - - softwareModuleRepository.delete(swModule); - - } else { - - assignedModuleIds.add(swModule.getId()); - } - }); - - if (!assignedModuleIds.isEmpty()) { - String currentUser = null; - if (auditorProvider != null) { - currentUser = auditorProvider.getCurrentAuditor(); - } - softwareModuleRepository.deleteSoftwareModule(System.currentTimeMillis(), currentUser, - assignedModuleIds.toArray(new Long[0])); - } - } - - @Override - public Slice findSoftwareModulesAll(final Pageable pageable) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - spec = (root, query, cb) -> { - if (!query.getResultType().isAssignableFrom(Long.class)) { - root.fetch(JpaSoftwareModule_.type); - } - return cb.conjunction(); - }; - - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - @Override - public Long countSoftwareModulesAll() { - - final List> specList = new ArrayList<>(); - - final Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public SoftwareModule findSoftwareModuleWithDetails(final Long id) { - return artifactManagement.findSoftwareModuleWithDetails(id); - } - - @Override - public Page findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) { - final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class); - - return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable); - } - - @Override - public Page findSoftwareModuleTypesAll(final String rsqlParam, final Pageable pageable) { - - final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class); - - return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable); - } - - private static Page convertSmTPage(final Page findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - @Override - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - public List findSoftwareModulesById(final Collection ids) { - return new ArrayList<>(softwareModuleRepository.findByIdIn(ids)); - } - - @Override - public Slice findSoftwareModuleByFilters(final Pageable pageable, final String searchText, - final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - if (!Strings.isNullOrEmpty(searchText)) { - spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); - specList.add(spec); - } - - if (null != type) { - spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - } - - spec = (root, query, cb) -> { - if (!query.getResultType().isAssignableFrom(Long.class)) { - root.fetch(JpaSoftwareModule_.type); - } - return cb.conjunction(); - }; - - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - @Override - public Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( - final Pageable pageable, final Long orderByDistributionId, final String searchText, - final SoftwareModuleType ty) { - final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; - - final List resultList = new ArrayList<>(); - final int pageSize = pageable.getPageSize(); - final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); - - // get the assigned software modules - final CriteriaQuery assignedQuery = cb.createQuery(JpaSoftwareModule.class); - final Root assignedRoot = assignedQuery.from(JpaSoftwareModule.class); - assignedQuery.distinct(true); - final ListJoin assignedDsJoin = assignedRoot - .join(JpaSoftwareModule_.assignedTo); - // build the specifications and then to predicates necessary by the - // given filters - final Predicate[] specPredicate = specificationsToPredicate(buildSpecificationList(searchText, type), - assignedRoot, assignedQuery, cb, - cb.equal(assignedDsJoin.get(JpaDistributionSet_.id), orderByDistributionId)); - // if we have some predicates then add it to the where clause of the - // multi select - assignedQuery.where(specPredicate); - assignedQuery.orderBy(cb.asc(assignedRoot.get(JpaSoftwareModule_.name)), - cb.asc(assignedRoot.get(JpaSoftwareModule_.version))); - // don't page the assigned query on database, we need all assigned - // software modules to filter - // them out in the unassigned query - final List assignedSoftwareModules = entityManager.createQuery(assignedQuery) - .getResultList(); - // map result - if (pageable.getOffset() < assignedSoftwareModules.size()) { - assignedSoftwareModules - .subList(pageable.getOffset(), Math.min(assignedSoftwareModules.size(), pageable.getPageSize())) - .forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, true))); - } - - if (assignedSoftwareModules.size() >= pageSize) { - return new SliceImpl<>(resultList); - } - - // get the unassigned software modules - final CriteriaQuery unassignedQuery = cb.createQuery(JpaSoftwareModule.class); - unassignedQuery.distinct(true); - final Root unassignedRoot = unassignedQuery.from(JpaSoftwareModule.class); - - Predicate[] unassignedSpec; - if (!assignedSoftwareModules.isEmpty()) { - unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, - unassignedQuery, cb, cb.not(unassignedRoot.get(JpaSoftwareModule_.id) - .in(assignedSoftwareModules.stream().map(sw -> sw.getId()).collect(Collectors.toList())))); - } else { - unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, - unassignedQuery, cb); - } - - unassignedQuery.where(unassignedSpec); - unassignedQuery.orderBy(cb.asc(unassignedRoot.get(JpaSoftwareModule_.name)), - cb.asc(unassignedRoot.get(JpaSoftwareModule_.version))); - final List unassignedSoftwareModules = entityManager.createQuery(unassignedQuery) - .setFirstResult(Math.max(0, pageable.getOffset() - assignedSoftwareModules.size())) - .setMaxResults(pageSize).getResultList(); - // map result - unassignedSoftwareModules.forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, false))); - - return new SliceImpl<>(resultList); - } - - private static List> buildSpecificationList(final String searchText, - final JpaSoftwareModuleType type) { - final List> specList = new ArrayList<>(); - if (!Strings.isNullOrEmpty(searchText)) { - specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText)); - } - if (type != null) { - specList.add(SoftwareModuleSpecification.equalType(type)); - } - specList.add(SoftwareModuleSpecification.isDeletedFalse()); - return specList; - } - - private Predicate[] specificationsToPredicate(final List> specifications, - final Root root, final CriteriaQuery query, final CriteriaBuilder cb, - final Predicate... additionalPredicates) { - final List predicates = new ArrayList<>(); - specifications.forEach(spec -> predicates.add(spec.toPredicate(root, query, cb))); - for (final Predicate predicate : additionalPredicates) { - predicates.add(predicate); - } - return predicates.toArray(new Predicate[predicates.size()]); - } - - @Override - public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - if (!Strings.isNullOrEmpty(searchText)) { - spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); - specList.add(spec); - } - - if (null != type) { - spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - } - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public Page findSoftwareModuleTypesAll(final Pageable pageable) { - return softwareModuleTypeRepository.findByDeleted(pageable, false); - } - - @Override - public Long countSoftwareModuleTypesAll() { - return softwareModuleTypeRepository.countByDeleted(false); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeByKey(final String key) { - return softwareModuleTypeRepository.findByKey(key); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeById(final Long id) { - return softwareModuleTypeRepository.findOne(id); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeByName(final String name) { - return softwareModuleTypeRepository.findByName(name); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleType type) { - if (type.getId() != null) { - throw new EntityAlreadyExistsException("Given type contains an Id!"); - } - - return softwareModuleTypeRepository.save((JpaSoftwareModuleType) type); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModuleType(final SoftwareModuleType ty) { - final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; - - if (softwareModuleRepository.countByType(type) > 0 - || distributionSetTypeRepository.countByElementsSmType(type) > 0) { - final JpaSoftwareModuleType toDelete = entityManager.merge(type); - toDelete.setDeleted(true); - softwareModuleTypeRepository.save(toDelete); - } else { - softwareModuleTypeRepository.delete(type.getId()); - } - } - - @Override - public Page findSoftwareModuleByAssignedTo(final Pageable pageable, final DistributionSet set) { - return softwareModuleRepository.findByAssignedTo(pageable, (JpaDistributionSet) set); - } - - @Override - public Page findSoftwareModuleByAssignedToAndType(final Pageable pageable, - final DistributionSet set, final SoftwareModuleType type) { - return softwareModuleRepository.findByAssignedToAndType(pageable, (JpaDistributionSet) set, - (JpaSoftwareModuleType) type); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata md) { - final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; - - if (softwareModuleMetadataRepository.exists(metadata.getId())) { - throwMetadataKeyAlreadyExists(metadata.getId().getKey()); - } - // merge base software module so optLockRevision gets updated and audit - // log written because - // modifying metadata is modifying the base software module itself for - // auditing purposes. - entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); - return softwareModuleMetadataRepository.save(metadata); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public List createSoftwareModuleMetadata(final Collection md) { - @SuppressWarnings({ "unchecked", "rawtypes" }) - final Collection metadata = (Collection) md; - - for (final JpaSoftwareModuleMetadata softwareModuleMetadata : metadata) { - checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId()); - } - metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L)); - return new ArrayList<>(softwareModuleMetadataRepository.save(metadata)); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata md) { - final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; - - // check if exists otherwise throw entity not found exception - findSoftwareModuleMetadata(metadata.getId()); - // touch it to update the lock revision because we are modifying the - // software module - // indirectly - entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); - return softwareModuleMetadataRepository.save(metadata); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public void deleteSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { - softwareModuleMetadataRepository.delete(new SwMetadataCompositeKey(softwareModule, key)); - } - - @Override - public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long swId, - final Pageable pageable) { - return softwareModuleMetadataRepository.findBySoftwareModuleId(swId, pageable); - } - - @Override - public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId, - final String rsqlParam, final Pageable pageable) { - - final Specification spec = RSQLUtility.parse(rsqlParam, - SoftwareModuleMetadataFields.class); - return convertSmMdPage( - softwareModuleMetadataRepository - .findAll( - (Specification) (root, query, cb) -> cb.and( - cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) - .get(JpaSoftwareModule_.id), softwareModuleId), - spec.toPredicate(root, query, cb)), - pageable), - pageable); - } - - @Override - public SoftwareModuleMetadata findSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { - return findSoftwareModuleMetadata(new SwMetadataCompositeKey(softwareModule, key)); - } - - private SoftwareModuleMetadata findSoftwareModuleMetadata(final SwMetadataCompositeKey id) { - final SoftwareModuleMetadata findOne = softwareModuleMetadataRepository.findOne(id); - if (findOne == null) { - throw new EntityNotFoundException("Metadata with key '" + id.getKey() + "' does not exist"); - } - return findOne; - } - - private void checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(final SwMetadataCompositeKey metadataId) { - if (softwareModuleMetadataRepository.exists(metadataId)) { - throw new EntityAlreadyExistsException( - "Metadata entry with key '" + metadataId.getKey() + "' already exists"); - } - } - - private static void throwMetadataKeyAlreadyExists(final String metadataKey) { - throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists"); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModule(final SoftwareModule bsm) { - deleteSoftwareModules(Sets.newHashSet(bsm.getId())); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List createSoftwareModuleType(final Collection types) { - - return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); - } - -} +/** + * 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.jpa; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.ListJoin; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.ArtifactManagement; +import org.eclipse.hawkbit.repository.SoftwareManagement; +import org.eclipse.hawkbit.repository.SoftwareModuleFields; +import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_; +import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; +import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification; +import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; +import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.LocalArtifact; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.AuditorAware; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import com.google.common.base.Strings; +import com.google.common.collect.Sets; + +/** + * JPA implementation of {@link SoftwareManagement}. + * + */ +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) +@Validated +public class JpaSoftwareManagement implements SoftwareManagement { + + @Autowired + private EntityManager entityManager; + + @Autowired + private DistributionSetRepository distributionSetRepository; + + @Autowired + private DistributionSetTypeRepository distributionSetTypeRepository; + + @Autowired + private SoftwareModuleRepository softwareModuleRepository; + + @Autowired + private SoftwareModuleMetadataRepository softwareModuleMetadataRepository; + + @Autowired + private SoftwareModuleTypeRepository softwareModuleTypeRepository; + + @Autowired + private NoCountPagingRepository criteriaNoCountDao; + + @Autowired + private AuditorAware auditorProvider; + + @Autowired + private ArtifactManagement artifactManagement; + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModule updateSoftwareModule(final SoftwareModule sm) { + checkNotNull(sm.getId()); + + final JpaSoftwareModule module = softwareModuleRepository.findOne(sm.getId()); + + boolean updated = false; + if (null == sm.getDescription() || !sm.getDescription().equals(module.getDescription())) { + module.setDescription(sm.getDescription()); + updated = true; + } + if (null == sm.getVendor() || !sm.getVendor().equals(module.getVendor())) { + module.setVendor(sm.getVendor()); + updated = true; + } + + return updated ? softwareModuleRepository.save(module) : module; + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleType sm) { + checkNotNull(sm.getId()); + + final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); + + boolean updated = false; + if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) { + type.setDescription(sm.getDescription()); + updated = true; + } + if (sm.getColour() != null && !sm.getColour().equals(type.getColour())) { + type.setColour(sm.getColour()); + updated = true; + } + return updated ? softwareModuleTypeRepository.save(type) : type; + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModule createSoftwareModule(final SoftwareModule swModule) { + if (null != swModule.getId()) { + throw new EntityAlreadyExistsException(); + } + return softwareModuleRepository.save((JpaSoftwareModule) swModule); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public List createSoftwareModule(final Collection swModules) { + swModules.forEach(swModule -> { + if (null != swModule.getId()) { + throw new EntityAlreadyExistsException(); + } + }); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection jpaCast = (Collection) swModules; + + return new ArrayList<>(softwareModuleRepository.save(jpaCast)); + } + + @Override + public Slice findSoftwareModulesByType(final Pageable pageable, final SoftwareModuleType type) { + + final List> specList = new LinkedList<>(); + + Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + + spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + private static Slice convertSmPage(final Slice findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, 0); + } + + private static Page convertSmPage(final Page findAll, final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + private static Page convertSmMdPage(final Page findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + @Override + public Long countSoftwareModulesByType(final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + + spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public SoftwareModule findSoftwareModuleById(final Long id) { + return artifactManagement.findSoftwareModuleById(id); + } + + @Override + public SoftwareModule findSoftwareModuleByNameAndVersion(final String name, final String version, + final SoftwareModuleType type) { + + return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, (JpaSoftwareModuleType) type); + } + + private boolean isUnassigned(final JpaSoftwareModule bsmMerged) { + return distributionSetRepository.findByModules(bsmMerged).isEmpty(); + } + + private Slice findSwModuleByCriteriaAPI(final Pageable pageable, + final List> specList) { + return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, + JpaSoftwareModule.class); + } + + private Long countSwModuleByCriteriaAPI(final List> specList) { + return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList)); + } + + private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) { + for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) { + artifactManagement.deleteLocalArtifact(localArtifact); + } + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModules(final Collection ids) { + final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); + final Set assignedModuleIds = new HashSet<>(); + swModulesToDelete.forEach(swModule -> { + + // delete binary data of artifacts + deleteGridFsArtifacts(swModule); + + if (isUnassigned(swModule)) { + + softwareModuleRepository.delete(swModule); + + } else { + + assignedModuleIds.add(swModule.getId()); + } + }); + + if (!assignedModuleIds.isEmpty()) { + String currentUser = null; + if (auditorProvider != null) { + currentUser = auditorProvider.getCurrentAuditor(); + } + softwareModuleRepository.deleteSoftwareModule(System.currentTimeMillis(), currentUser, + assignedModuleIds.toArray(new Long[0])); + } + } + + @Override + public Slice findSoftwareModulesAll(final Pageable pageable) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + spec = (root, query, cb) -> { + if (!query.getResultType().isAssignableFrom(Long.class)) { + root.fetch(JpaSoftwareModule_.type); + } + return cb.conjunction(); + }; + + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + @Override + public Long countSoftwareModulesAll() { + + final List> specList = new ArrayList<>(); + + final Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public SoftwareModule findSoftwareModuleWithDetails(final Long id) { + return artifactManagement.findSoftwareModuleWithDetails(id); + } + + @Override + public Page findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) { + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class); + + return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable); + } + + @Override + public Page findSoftwareModuleTypesAll(final String rsqlParam, final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class); + + return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable); + } + + private static Page convertSmTPage(final Page findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + @Override + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + public List findSoftwareModulesById(final Collection ids) { + return new ArrayList<>(softwareModuleRepository.findByIdIn(ids)); + } + + @Override + public Slice findSoftwareModuleByFilters(final Pageable pageable, final String searchText, + final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + if (!Strings.isNullOrEmpty(searchText)) { + spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); + specList.add(spec); + } + + if (null != type) { + spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + } + + spec = (root, query, cb) -> { + if (!query.getResultType().isAssignableFrom(Long.class)) { + root.fetch(JpaSoftwareModule_.type); + } + return cb.conjunction(); + }; + + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + @Override + public Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( + final Pageable pageable, final Long orderByDistributionId, final String searchText, + final SoftwareModuleType ty) { + final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; + + final List resultList = new ArrayList<>(); + final int pageSize = pageable.getPageSize(); + final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); + + // get the assigned software modules + final CriteriaQuery assignedQuery = cb.createQuery(JpaSoftwareModule.class); + final Root assignedRoot = assignedQuery.from(JpaSoftwareModule.class); + assignedQuery.distinct(true); + final ListJoin assignedDsJoin = assignedRoot + .join(JpaSoftwareModule_.assignedTo); + // build the specifications and then to predicates necessary by the + // given filters + final Predicate[] specPredicate = specificationsToPredicate(buildSpecificationList(searchText, type), + assignedRoot, assignedQuery, cb, + cb.equal(assignedDsJoin.get(JpaDistributionSet_.id), orderByDistributionId)); + // if we have some predicates then add it to the where clause of the + // multi select + assignedQuery.where(specPredicate); + assignedQuery.orderBy(cb.asc(assignedRoot.get(JpaSoftwareModule_.name)), + cb.asc(assignedRoot.get(JpaSoftwareModule_.version))); + // don't page the assigned query on database, we need all assigned + // software modules to filter + // them out in the unassigned query + final List assignedSoftwareModules = entityManager.createQuery(assignedQuery) + .getResultList(); + // map result + if (pageable.getOffset() < assignedSoftwareModules.size()) { + assignedSoftwareModules + .subList(pageable.getOffset(), Math.min(assignedSoftwareModules.size(), pageable.getPageSize())) + .forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, true))); + } + + if (assignedSoftwareModules.size() >= pageSize) { + return new SliceImpl<>(resultList); + } + + // get the unassigned software modules + final CriteriaQuery unassignedQuery = cb.createQuery(JpaSoftwareModule.class); + unassignedQuery.distinct(true); + final Root unassignedRoot = unassignedQuery.from(JpaSoftwareModule.class); + + Predicate[] unassignedSpec; + if (!assignedSoftwareModules.isEmpty()) { + unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, + unassignedQuery, cb, cb.not(unassignedRoot.get(JpaSoftwareModule_.id) + .in(assignedSoftwareModules.stream().map(sw -> sw.getId()).collect(Collectors.toList())))); + } else { + unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, + unassignedQuery, cb); + } + + unassignedQuery.where(unassignedSpec); + unassignedQuery.orderBy(cb.asc(unassignedRoot.get(JpaSoftwareModule_.name)), + cb.asc(unassignedRoot.get(JpaSoftwareModule_.version))); + final List unassignedSoftwareModules = entityManager.createQuery(unassignedQuery) + .setFirstResult(Math.max(0, pageable.getOffset() - assignedSoftwareModules.size())) + .setMaxResults(pageSize).getResultList(); + // map result + unassignedSoftwareModules.forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, false))); + + return new SliceImpl<>(resultList); + } + + private static List> buildSpecificationList(final String searchText, + final JpaSoftwareModuleType type) { + final List> specList = new ArrayList<>(); + if (!Strings.isNullOrEmpty(searchText)) { + specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText)); + } + if (type != null) { + specList.add(SoftwareModuleSpecification.equalType(type)); + } + specList.add(SoftwareModuleSpecification.isDeletedFalse()); + return specList; + } + + private Predicate[] specificationsToPredicate(final List> specifications, + final Root root, final CriteriaQuery query, final CriteriaBuilder cb, + final Predicate... additionalPredicates) { + final List predicates = new ArrayList<>(); + specifications.forEach(spec -> predicates.add(spec.toPredicate(root, query, cb))); + for (final Predicate predicate : additionalPredicates) { + predicates.add(predicate); + } + return predicates.toArray(new Predicate[predicates.size()]); + } + + @Override + public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + if (!Strings.isNullOrEmpty(searchText)) { + spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); + specList.add(spec); + } + + if (null != type) { + spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + } + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public Page findSoftwareModuleTypesAll(final Pageable pageable) { + return softwareModuleTypeRepository.findByDeleted(pageable, false); + } + + @Override + public Long countSoftwareModuleTypesAll() { + return softwareModuleTypeRepository.countByDeleted(false); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeByKey(final String key) { + return softwareModuleTypeRepository.findByKey(key); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeById(final Long id) { + return softwareModuleTypeRepository.findOne(id); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeByName(final String name) { + return softwareModuleTypeRepository.findByName(name); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleType type) { + if (type.getId() != null) { + throw new EntityAlreadyExistsException("Given type contains an Id!"); + } + + return softwareModuleTypeRepository.save((JpaSoftwareModuleType) type); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModuleType(final SoftwareModuleType ty) { + final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; + + if (softwareModuleRepository.countByType(type) > 0 + || distributionSetTypeRepository.countByElementsSmType(type) > 0) { + final JpaSoftwareModuleType toDelete = entityManager.merge(type); + toDelete.setDeleted(true); + softwareModuleTypeRepository.save(toDelete); + } else { + softwareModuleTypeRepository.delete(type.getId()); + } + } + + @Override + public Page findSoftwareModuleByAssignedTo(final Pageable pageable, final DistributionSet set) { + return softwareModuleRepository.findByAssignedTo(pageable, (JpaDistributionSet) set); + } + + @Override + public Page findSoftwareModuleByAssignedToAndType(final Pageable pageable, + final DistributionSet set, final SoftwareModuleType type) { + return softwareModuleRepository.findByAssignedToAndType(pageable, (JpaDistributionSet) set, + (JpaSoftwareModuleType) type); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata md) { + final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; + + if (softwareModuleMetadataRepository.exists(metadata.getId())) { + throwMetadataKeyAlreadyExists(metadata.getId().getKey()); + } + // merge base software module so optLockRevision gets updated and audit + // log written because + // modifying metadata is modifying the base software module itself for + // auditing purposes. + entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); + return softwareModuleMetadataRepository.save(metadata); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public List createSoftwareModuleMetadata(final Collection md) { + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection metadata = (Collection) md; + + for (final JpaSoftwareModuleMetadata softwareModuleMetadata : metadata) { + checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId()); + } + metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L)); + return new ArrayList<>(softwareModuleMetadataRepository.save(metadata)); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata md) { + final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; + + // check if exists otherwise throw entity not found exception + findSoftwareModuleMetadata(metadata.getId()); + // touch it to update the lock revision because we are modifying the + // software module + // indirectly + entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); + return softwareModuleMetadataRepository.save(metadata); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public void deleteSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { + softwareModuleMetadataRepository.delete(new SwMetadataCompositeKey(softwareModule, key)); + } + + @Override + public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long swId, + final Pageable pageable) { + return softwareModuleMetadataRepository.findBySoftwareModuleId(swId, pageable); + } + + @Override + public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId, + final String rsqlParam, final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, + SoftwareModuleMetadataFields.class); + return convertSmMdPage( + softwareModuleMetadataRepository + .findAll( + (Specification) (root, query, cb) -> cb.and( + cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) + .get(JpaSoftwareModule_.id), softwareModuleId), + spec.toPredicate(root, query, cb)), + pageable), + pageable); + } + + @Override + public List findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) { + return new ArrayList<> ( softwareModuleMetadataRepository + .findAll( + (Specification) (root, query, cb) -> cb.and( + cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) + .get(JpaSoftwareModule_.id), softwareModuleId)))); + } + + @Override + public SoftwareModuleMetadata findSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { + return findSoftwareModuleMetadata(new SwMetadataCompositeKey(softwareModule, key)); + } + + private SoftwareModuleMetadata findSoftwareModuleMetadata(final SwMetadataCompositeKey id) { + final SoftwareModuleMetadata findOne = softwareModuleMetadataRepository.findOne(id); + if (findOne == null) { + throw new EntityNotFoundException("Metadata with key '" + id.getKey() + "' does not exist"); + } + return findOne; + } + + private void checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(final SwMetadataCompositeKey metadataId) { + if (softwareModuleMetadataRepository.exists(metadataId)) { + throw new EntityAlreadyExistsException( + "Metadata entry with key '" + metadataId.getKey() + "' already exists"); + } + } + + private static void throwMetadataKeyAlreadyExists(final String metadataKey) { + throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists"); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModule(final SoftwareModule bsm) { + deleteSoftwareModules(Sets.newHashSet(bsm.getId())); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public List createSoftwareModuleType(final Collection types) { + + return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java index b6475f647..b96b59f6a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/AbstractTableDetailsLayout.java @@ -222,7 +222,6 @@ public abstract class AbstractTableDetailsLayout extends populateLog(); populateDescription(); populateDetailsWidget(); - populateMetadataDetails(); } protected void populateLog() { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java index d3892a9dc..cf41bdd4f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/DistributionSetMetadatadetailslayout.java @@ -40,38 +40,36 @@ import com.vaadin.ui.themes.ValoTheme; @SpringComponent @VaadinSessionScope -public class DistributionSetMetadatadetailslayout extends Table{ - +public class DistributionSetMetadatadetailslayout extends Table { + private static final long serialVersionUID = 2913758299611837718L; - - - private DistributionSetManagement distributionSetManagement; - + + private DistributionSetManagement distributionSetManagement; + private DsMetadataPopupLayout dsMetadataPopupLayout; private static final String METADATA_KEY = "Key"; - - private static final String VIEW ="view"; + + private static final String VIEW = "view"; private SpPermissionChecker permissionChecker; - + private transient EntityFactory entityFactory; private I18N i18n; - - private Long selectedDistSetId; - - /** - * - * @param i18n - * @param permissionChecker - * @param distributionSetManagement - * @param dsMetadataPopupLayout - */ + + private Long selectedDistSetId; + + /** + * + * @param i18n + * @param permissionChecker + * @param distributionSetManagement + * @param dsMetadataPopupLayout + */ public void init(final I18N i18n, final SpPermissionChecker permissionChecker, - final DistributionSetManagement distributionSetManagement, - final DsMetadataPopupLayout dsMetadataPopupLayout, - final EntityFactory entityFactory) { + final DistributionSetManagement distributionSetManagement, + final DsMetadataPopupLayout dsMetadataPopupLayout, final EntityFactory entityFactory) { this.i18n = i18n; this.permissionChecker = permissionChecker; this.distributionSetManagement = distributionSetManagement; @@ -80,7 +78,6 @@ public class DistributionSetMetadatadetailslayout extends Table{ createDSMetadataTable(); addCustomGeneratedColumns(); } - /** * Populate software module metadata. @@ -90,35 +87,15 @@ public class DistributionSetMetadatadetailslayout extends Table{ public void populateDSMetadata(final DistributionSet distributionSet) { removeAllItems(); if (null == distributionSet) { - return; + return; } selectedDistSetId = distributionSet.getId(); - final List dsMetadataList = distributionSet.getMetadata(); + final List dsMetadataList = distributionSetManagement + .findDistributionSetMetadataByDistributionSetId(selectedDistSetId); if (null != dsMetadataList && !dsMetadataList.isEmpty()) { dsMetadataList.forEach(dsMetadata -> setDSMetadataProperties(dsMetadata)); } - - } - - /** - * Create metadata . - * - * @param metadataKeyName - */ - public void createMetadata(final String metadataKeyName){ - final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource(); - final Item item = metadataContainer.addItem(metadataKeyName); - item.getItemProperty(METADATA_KEY).setValue(metadataKeyName); - } - - /** - * Delete metadata. - * - * @param metadataKeyName - */ - public void deleteMetadata(final String metadataKeyName){ - final IndexedContainer metadataContainer = (IndexedContainer) getContainerDataSource(); - metadataContainer.removeItem(metadataKeyName); + } private void createDSMetadataTable() { @@ -131,9 +108,9 @@ public class DistributionSetMetadatadetailslayout extends Table{ setContainerDataSource(getDistSetContainer()); setColumnHeaderMode(ColumnHeaderMode.EXPLICIT); addDSMetadataTableHeader(); - setSizeFull(); - //same as height of other tabs in details tabsheet - setHeight(116,Unit.PIXELS); + setSizeFull(); + // same as height of other tabs in details tabsheet + setHeight(116, Unit.PIXELS); } private IndexedContainer getDistSetContainer() { @@ -141,7 +118,7 @@ public class DistributionSetMetadatadetailslayout extends Table{ container.addContainerProperty(METADATA_KEY, String.class, ""); setColumnExpandRatio(METADATA_KEY, 0.7f); setColumnAlignment(METADATA_KEY, Align.LEFT); - + if (permissionChecker.hasUpdateDistributionPermission()) { container.addContainerProperty(VIEW, Label.class, ""); setColumnExpandRatio(VIEW, 0.2F); @@ -154,39 +131,36 @@ public class DistributionSetMetadatadetailslayout extends Table{ setColumnHeader(METADATA_KEY, i18n.get("header.key")); } - - private void setDSMetadataProperties(final DistributionSetMetadata dsMetadata){ + private void setDSMetadataProperties(final DistributionSetMetadata dsMetadata) { final Item item = getContainerDataSource().addItem(dsMetadata.getKey()); item.getItemProperty(METADATA_KEY).setValue(dsMetadata.getKey()); - + } - - private void addCustomGeneratedColumns() { - addGeneratedColumn(METADATA_KEY, - (source, itemId, columnId) -> customMetadataDetailButton((String) itemId)); + + private void addCustomGeneratedColumns() { + addGeneratedColumn(METADATA_KEY, (source, itemId, columnId) -> customMetadataDetailButton((String) itemId)); } private Button customMetadataDetailButton(final String metadataKey) { - final Button viewIcon = SPUIComponentProvider.getButton(getDetailLinkId(metadataKey), metadataKey, "View " - + metadataKey + " Metadata details", null, false, null, SPUIButtonStyleSmallNoBorder.class); + final Button viewIcon = SPUIComponentProvider.getButton(getDetailLinkId(metadataKey), metadataKey, + "View " + metadataKey + " Metadata details", null, false, null, SPUIButtonStyleSmallNoBorder.class); viewIcon.setData(metadataKey); viewIcon.addStyleName(ValoTheme.BUTTON_TINY + " " + ValoTheme.BUTTON_LINK + " " + "on-focus-no-border link" + " " + "text-style"); viewIcon.addClickListener(event -> showMetadataDetails(selectedDistSetId, metadataKey)); return viewIcon; } - + private static String getDetailLinkId(final String name) { - return new StringBuilder(SPUIComponentIdProvider.DS_METADATA_DETAIL_LINK).append('.').append(name) - .toString(); + return new StringBuilder(SPUIComponentIdProvider.DS_METADATA_DETAIL_LINK).append('.').append(name).toString(); } - - private void showMetadataDetails(final Long selectedDistSetId , final String metadataKey) { - DistributionSet distSet = distributionSetManagement.findDistributionSetById(selectedDistSetId); - + + private void showMetadataDetails(final Long selectedDistSetId, final String metadataKey) { + final DistributionSet distSet = distributionSetManagement.findDistributionSetById(selectedDistSetId); + /* display the window */ UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(distSet, - entityFactory.generateDistributionSetMetadata(distSet, metadataKey, "") )); + entityFactory.generateDistributionSetMetadata(distSet, metadataKey, ""))); } - + } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java index 854347c11..355080636 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleMetadatadetailslayout.java @@ -80,7 +80,7 @@ public class SoftwareModuleMetadatadetailslayout extends Table { return; } selectedSWModuleId = swModule.getId(); - final List swMetadataList = swModule.getMetadata(); + final List swMetadataList = softwareManagement.findSoftwareModuleMetadataBySoftwareModuleId(selectedSWModuleId); if (null != swMetadataList && !swMetadataList.isEmpty()) { swMetadataList.forEach(swMetadata -> setSWMetadataProperties(swMetadata)); } @@ -160,7 +160,7 @@ public class SoftwareModuleMetadatadetailslayout extends Table { } private void showMetadataDetails(final Long selectedSWModuleId, final String metadataKey) { - SoftwareModule swmodule = softwareManagement.findSoftwareModuleById(selectedSWModuleId); + final SoftwareModule swmodule = softwareManagement.findSoftwareModuleById(selectedSWModuleId); /* display the window */ UI.getCurrent().addWindow( swMetadataPopupLayout.getWindow(swmodule, diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java index 03a86c44d..32deef7a8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetDetails.java @@ -17,7 +17,6 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SoftwareManagement; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleIdName; import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleEvent; @@ -29,7 +28,6 @@ import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsTable; import org.eclipse.hawkbit.ui.common.tagdetails.DistributionTagToken; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.decorators.SPUIButtonStyleSmallNoBorder; -import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent; import org.eclipse.hawkbit.ui.distributions.event.SaveActionWindowEvent; import org.eclipse.hawkbit.ui.distributions.event.SoftwareModuleAssignmentDiscardEvent; import org.eclipse.hawkbit.ui.distributions.state.ManageDistUIState; @@ -68,7 +66,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet private static final String SOFT_MODULE = "softwareModule"; private static final String UNASSIGN_SOFT_MODULE = "unassignSoftModule"; - + @Autowired private ManageDistUIState manageDistUIState; @@ -83,37 +81,20 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet @Autowired private transient DistributionSetManagement distributionSetManagement; - + @Autowired private DsMetadataPopupLayout dsMetadataPopupLayout; - + @Autowired private EntityFactory entityFactory; private SoftwareModuleDetailsTable softwareModuleTable; - + private DistributionSetMetadatadetailslayout dsMetadataTable; private VerticalLayout tagsLayout; - + private final Map assignedSWModule = new HashMap<>(); - - - @EventBusListenerMethod(scope = EventScope.SESSION) - void onEvent(final MetadataEvent event) { - UI.getCurrent() - .access(() -> { - DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); - if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) { - if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey()); - } else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey()); - } - } - }); - } - /** * softwareLayout Initialize the component. @@ -124,8 +105,8 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet softwareModuleTable.init(getI18n(), true, getPermissionChecker(), distributionSetManagement, getEventBus(), manageDistUIState); dsMetadataTable = new DistributionSetMetadatadetailslayout(); - dsMetadataTable.init(getI18n(), getPermissionChecker(),distributionSetManagement, - dsMetadataPopupLayout,entityFactory); + dsMetadataTable.init(getI18n(), getPermissionChecker(), distributionSetManagement, dsMetadataPopupLayout, + entityFactory); super.init(); } @@ -141,7 +122,7 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet populateTags(); populateMetadataDetails(); } - + private void populateModule() { softwareModuleTable.populateModule(getSelectedBaseEntity()); showUnsavedAssignment(); @@ -271,12 +252,12 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet updateDistributionSetDetailsLayout(null, null); } } - + @Override - protected void populateMetadataDetails(){ + protected void populateMetadataDetails() { dsMetadataTable.populateDSMetadata(getSelectedBaseEntity()); - } - + } + private void updateDistributionSetDetailsLayout(final String type, final Boolean isMigrationRequired) { final VerticalLayout detailsTabLayout = getDetailsLayout(); detailsTabLayout.removeAllComponents(); @@ -403,26 +384,26 @@ public class DistributionSetDetails extends AbstractNamedVersionedEntityTableDet protected Boolean isMetadataIconToBeDisplayed() { return true; } - + @Override protected String getShowMetadataButtonId() { - DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() ? manageDistUIState - .getLastSelectedDistribution().get() : null; + final DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() + ? manageDistUIState.getLastSelectedDistribution().get() : null; return SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + lastselectedDistDS.getName() + "." + lastselectedDistDS.getVersion(); } - - private boolean isDistributionSetSelected(DistributionSet ds) { - DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() ? manageDistUIState - .getLastSelectedDistribution().get() : null; + + private boolean isDistributionSetSelected(final DistributionSet ds) { + final DistributionSetIdName lastselectedDistDS = manageDistUIState.getLastSelectedDistribution().isPresent() + ? manageDistUIState.getLastSelectedDistribution().get() : null; return ds != null && lastselectedDistDS != null && lastselectedDistDS.getName().equals(ds.getName()) && lastselectedDistDS.getVersion().endsWith(ds.getVersion()); } - @Override - protected void showMetadata(ClickEvent event) { - DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); - UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null)); + protected void showMetadata(final ClickEvent event) { + final DistributionSet ds = distributionSetManagement + .findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); + UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null)); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java index 2041944d4..0d433d910 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DsMetadataPopupLayout.java @@ -16,8 +16,6 @@ import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.ui.common.AbstractMetadataPopupLayout; -import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent; -import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent.MetadataUIEvent; import org.springframework.beans.factory.annotation.Autowired; import com.vaadin.spring.annotation.SpringComponent; @@ -42,19 +40,19 @@ public class DsMetadataPopupLayout extends AbstractMetadataPopupLayout getMetadataList() { return getSelectedEntity().getMetadata(); } - + /** * Update metadata for DistributionSet. */ @Override - protected void deleteMetadata(DistributionSet entity, String key, String value) { - DistributionSetMetadata dsMetaData = entityFactory.generateDistributionSetMetadata(entity, key, value); + protected void deleteMetadata(final DistributionSet entity, final String key, final String value) { + final DistributionSetMetadata dsMetaData = entityFactory.generateDistributionSetMetadata(entity, key, value); distributionSetManagement.deleteDistributionSetMetadata(entity, key); - eventBus.publish(this, new MetadataEvent(MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA, dsMetaData)); } - + @Override protected boolean hasCreatePermission() { return permChecker.hasCreateDistributionPermission(); } - + @Override protected boolean hasUpdatePermission() { return permChecker.hasUpdateDistributionPermission(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/MetadataEvent.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/MetadataEvent.java index f82bc5c01..2436de9e5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/MetadataEvent.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/event/MetadataEvent.java @@ -10,6 +10,7 @@ package org.eclipse.hawkbit.ui.distributions.event; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; + /** * * Metadata Events. @@ -18,21 +19,21 @@ import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; public class MetadataEvent { public enum MetadataUIEvent { - CREATE_DISTRIBUTION_SET_METADATA, DELETE_DISTRIBUTION_SET_METADATA, DELETE_SOFTWARE_MODULE_METADATA, CREATE_SOFTWARE_MODULE_METADATA; + DELETE_SOFTWARE_MODULE_METADATA, CREATE_SOFTWARE_MODULE_METADATA; } - private MetadataUIEvent metadataUIEvent; + private final MetadataUIEvent metadataUIEvent; private DistributionSetMetadata distributionSetMetadata; private SoftwareModuleMetadata softwareModuleMetadata; - public MetadataEvent(MetadataUIEvent metadataUIEvent, final DistributionSetMetadata distributionSetMetadata) { + public MetadataEvent(final MetadataUIEvent metadataUIEvent, final DistributionSetMetadata distributionSetMetadata) { this.metadataUIEvent = metadataUIEvent; this.distributionSetMetadata = distributionSetMetadata; } - public MetadataEvent(MetadataUIEvent metadataUIEvent, final SoftwareModuleMetadata softwareModuleMetadata) { + public MetadataEvent(final MetadataUIEvent metadataUIEvent, final SoftwareModuleMetadata softwareModuleMetadata) { this.metadataUIEvent = metadataUIEvent; this.softwareModuleMetadata = softwareModuleMetadata; } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java index d83f7b4c8..a4b8c6a86 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionAddUpdateWindowLayout.java @@ -37,6 +37,7 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; +import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.eclipse.hawkbit.ui.utils.UINotification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -84,10 +85,6 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { @Autowired private transient EntityFactory entityFactory; - - @Autowired - private transient DistributionSetTable distributionSetTable; - private TextField distNameTextField; private TextField distVersionTextField; private TextArea descTextArea; @@ -239,9 +236,10 @@ public class DistributionAddUpdateWindowLayout extends CustomComponent { notificationMessage.displaySuccess(i18n.get("message.new.dist.save.success", new Object[] { newDist.getName(), newDist.getVersion() })); - + final Set s = new HashSet<>(); - s.add(new DistributionSetIdName(newDist.getId(),newDist.getName(),newDist.getVersion())); + s.add(new DistributionSetIdName(newDist.getId(), newDist.getName(), newDist.getVersion())); + final DistributionSetTable distributionSetTable = SpringContextHelper.getBean(DistributionSetTable.class); distributionSetTable.setValue(s); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java index e59820e9c..b61cc103c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java @@ -11,7 +11,6 @@ package org.eclipse.hawkbit.ui.management.dstable; import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.ui.common.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.detailslayout.AbstractNamedVersionedEntityTableDetailsLayout; import org.eclipse.hawkbit.ui.common.detailslayout.DistributionSetMetadatadetailslayout; @@ -19,7 +18,6 @@ import org.eclipse.hawkbit.ui.common.detailslayout.SoftwareModuleDetailsTable; import org.eclipse.hawkbit.ui.common.tagdetails.DistributionTagToken; import org.eclipse.hawkbit.ui.components.SPUIComponentProvider; import org.eclipse.hawkbit.ui.distributions.dstable.DsMetadataPopupLayout; -import org.eclipse.hawkbit.ui.distributions.event.MetadataEvent; import org.eclipse.hawkbit.ui.management.event.DistributionTableEvent; import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; @@ -53,48 +51,32 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail @Autowired private DistributionTagToken distributionTagToken; - + @Autowired - private transient DistributionSetManagement distributionSetManagement; - + private transient DistributionSetManagement distributionSetManagement; + @Autowired private DsMetadataPopupLayout dsMetadataPopupLayout; - + @Autowired private EntityFactory entityFactory; private SoftwareModuleDetailsTable softwareModuleTable; private DistributionSetMetadatadetailslayout dsMetadataTable; - + @Override protected void init() { softwareModuleTable = new SoftwareModuleDetailsTable(); softwareModuleTable.init(getI18n(), false, getPermissionChecker(), null, null, null); - + dsMetadataTable = new DistributionSetMetadatadetailslayout(); - dsMetadataTable.init(getI18n(), getPermissionChecker(),distributionSetManagement, - dsMetadataPopupLayout,entityFactory); - + dsMetadataTable.init(getI18n(), getPermissionChecker(), distributionSetManagement, dsMetadataPopupLayout, + entityFactory); + super.init(); } - @EventBusListenerMethod(scope = EventScope.SESSION) - void onEvent(final MetadataEvent event) { - UI.getCurrent() - .access(() -> { - DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); - if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) { - if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey()); - } else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey()); - } - } - }); - } - - @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final DistributionTableEvent distributionTableEvent) { onBaseEntityEvent(distributionTableEvent); @@ -156,12 +138,11 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail populateMetadataDetails(); } - - + @Override - protected void populateMetadataDetails(){ + protected void populateMetadataDetails() { dsMetadataTable.populateDSMetadata(getSelectedBaseEntity()); - } + } private void populateDetails(final DistributionSet ds) { if (ds != null) { @@ -206,30 +187,32 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail protected String getDetailsHeaderCaptionId() { return SPUIComponentIdProvider.DISTRIBUTION_DETAILS_HEADER_LABEL_ID; } - + @Override protected Boolean isMetadataIconToBeDisplayed() { return true; } - + @Override protected String getShowMetadataButtonId() { - DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState - .getLastSelectedDistribution().get() : null; + final DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() + ? managementUIState.getLastSelectedDistribution().get() : null; return SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + lastselectedDistDS.getName() + "." + lastselectedDistDS.getVersion(); } - private boolean isDistributionSetSelected(DistributionSet ds) { - DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState - .getLastSelectedDistribution().get() : null; - return ds!=null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName()) + + private boolean isDistributionSetSelected(final DistributionSet ds) { + final DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() + ? managementUIState.getLastSelectedDistribution().get() : null; + return ds != null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName()) && lastselectedManageDS.getVersion().endsWith(ds.getVersion()); } @Override - protected void showMetadata(ClickEvent event) { - DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); - UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null)); + protected void showMetadata(final ClickEvent event) { + final DistributionSet ds = distributionSetManagement + .findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); + UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null)); } - + } From f2853e6d9fb16be0700c7d3c33ab006c7cf4231d Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 28 Jul 2016 14:24:49 +0200 Subject: [PATCH 032/118] Resolved the conflicts --- .../dstable/DistributionDetails.java | 37 +------------------ 1 file changed, 1 insertion(+), 36 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java index 68a65ab45..6dc1d7a69 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionDetails.java @@ -76,25 +76,6 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail super.init(); } -<<<<<<< HEAD -======= - - @EventBusListenerMethod(scope = EventScope.SESSION) - void onEvent(final MetadataEvent event) { - UI.getCurrent() - .access(() -> { - final DistributionSetMetadata dsMetadata = event.getDistributionSetMetadata(); - if (dsMetadata != null && isDistributionSetSelected(dsMetadata.getDistributionSet())) { - if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.CREATE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.createMetadata(event.getDistributionSetMetadata().getKey()); - } else if (event.getMetadataUIEvent() == MetadataEvent.MetadataUIEvent.DELETE_DISTRIBUTION_SET_METADATA) { - dsMetadataTable.deleteMetadata(event.getDistributionSetMetadata().getKey()); - } - } - }); - } - ->>>>>>> refs/heads/master @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final DistributionTableEvent distributionTableEvent) { @@ -214,41 +195,25 @@ public class DistributionDetails extends AbstractNamedVersionedEntityTableDetail @Override protected String getShowMetadataButtonId() { -<<<<<<< HEAD final DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState.getLastSelectedDistribution().get() : null; -======= - final DistributionSetIdName lastselectedDistDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState - .getLastSelectedDistribution().get() : null; ->>>>>>> refs/heads/master + return SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + lastselectedDistDS.getName() + "." + lastselectedDistDS.getVersion(); } -<<<<<<< HEAD private boolean isDistributionSetSelected(final DistributionSet ds) { final DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState.getLastSelectedDistribution().get() : null; return ds != null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName()) -======= - private boolean isDistributionSetSelected(final DistributionSet ds) { - final DistributionSetIdName lastselectedManageDS = managementUIState.getLastSelectedDistribution().isPresent() ? managementUIState - .getLastSelectedDistribution().get() : null; - return ds!=null && lastselectedManageDS != null && lastselectedManageDS.getName().equals(ds.getName()) ->>>>>>> refs/heads/master && lastselectedManageDS.getVersion().endsWith(ds.getVersion()); } @Override protected void showMetadata(final ClickEvent event) { -<<<<<<< HEAD final DistributionSet ds = distributionSetManagement .findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds, null)); -======= - final DistributionSet ds = distributionSetManagement.findDistributionSetByIdWithDetails(getSelectedBaseEntityId()); - UI.getCurrent().addWindow(dsMetadataPopupLayout.getWindow(ds,null)); ->>>>>>> refs/heads/master } } From 37eea0e16ac1648a42b554e17010f01e3d5e87cd Mon Sep 17 00:00:00 2001 From: SirWayne Date: Thu, 28 Jul 2016 14:51:50 +0200 Subject: [PATCH 033/118] Add test cases refacor after pr review Signed-off-by: SirWayne --- .../jpa/model/EntityInterceptorListener.java | 32 +-- .../model/helper/EntityInterceptorHolder.java | 5 +- .../model/EntityInterceptorListenerTest.java | 188 ++++++++++++++++++ .../test/util/AbstractIntegrationTest.java | 3 + 4 files changed, 210 insertions(+), 18 deletions(-) create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java index 15062f27f..1e9c39237 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.repository.jpa.model; +import java.util.function.Consumer; + import javax.persistence.PostLoad; import javax.persistence.PostPersist; import javax.persistence.PostRemove; @@ -17,53 +19,51 @@ import javax.persistence.PreRemove; import javax.persistence.PreUpdate; import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder; +import org.eclipse.hawkbit.repository.model.EntityInterceptor; /** - * Entity listener which calls all entity interceptor for the lifecyles - * callbacks. + * Entity listener which calls the callback's of all registered entity + * interceptors. */ public class EntityInterceptorListener { @PrePersist protected void prePersist(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.prePersist(entity)); + notifyAll(interceptor -> interceptor.prePersist(entity)); } @PostPersist protected void postPersist(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.postPersist(entity)); + notifyAll(interceptor -> interceptor.postPersist(entity)); } @PostRemove protected void postRemove(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.postRemove(entity)); + notifyAll(interceptor -> interceptor.postRemove(entity)); } @PreRemove protected void preRemove(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.preRemove(entity)); + notifyAll(interceptor -> interceptor.preRemove(entity)); } @PostLoad protected void postLoad(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.postLoad(entity)); + notifyAll(interceptor -> interceptor.postLoad(entity)); } @PreUpdate protected void preUpdate(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.preUpdate(entity)); + notifyAll(interceptor -> interceptor.preUpdate(entity)); } @PostUpdate protected void postUpdate(final Object entity) { - EntityInterceptorHolder.getInstance().getEntityInterceptors() - .forEach(interceptor -> interceptor.postUpdate(entity)); + notifyAll(interceptor -> interceptor.postUpdate(entity)); + } + + private void notifyAll(final Consumer action) { + EntityInterceptorHolder.getInstance().getEntityInterceptors().forEach(action); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java index 8153ddc32..c374f219a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityInterceptorHolder.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa.model.helper; +import java.util.ArrayList; import java.util.List; import org.eclipse.hawkbit.repository.model.EntityInterceptor; @@ -22,8 +23,8 @@ public final class EntityInterceptorHolder { private static final EntityInterceptorHolder SINGLETON = new EntityInterceptorHolder(); - @Autowired - private List entityInterceptors; + @Autowired(required = false) + private final List entityInterceptors = new ArrayList<>(); private EntityInterceptorHolder() { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java new file mode 100644 index 000000000..05e27ae08 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java @@ -0,0 +1,188 @@ +/** + * 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.jpa.model; + +import static org.fest.assertions.Assertions.assertThat; + +import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityInterceptorHolder; +import org.eclipse.hawkbit.repository.model.EntityInterceptor; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.repository.model.Target; +import org.junit.Test; + +import ru.yandex.qatools.allure.annotations.Description; +import ru.yandex.qatools.allure.annotations.Features; +import ru.yandex.qatools.allure.annotations.Stories; + +/** + * Test the entity listener interceptor. + */ +@Features("Component Tests - Repository") +@Stories("Entity Listener Interceptor") +public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest { + + @Test + @Description("Verfies that the pre persist is called after a entity creation.") + public void prePersistIsCalledWhenPersistingATarget() { + executePersistAndAssertCallbackResult(new PrePersistEntityListener()); + } + + @Test + @Description("Verfies that the post persist is called after a entity creation.") + public void postPersistIsCalledWhenPersistingATarget() { + executePersistAndAssertCallbackResult(new PostPersistEntityListener()); + } + + @Test + @Description("Verfies that the post load is called after a entity is loaded.") + public void postLoadIsCalledWhenLoadgATarget() { + final PostLoadEntityListener postLoadEntityListener = new PostLoadEntityListener(); + EntityInterceptorHolder.getInstance().getEntityInterceptors().add(postLoadEntityListener); + + final Target targetToBeCreated = entityFactory.generateTarget("targetToBeCreated"); + + targetManagement.createTarget(targetToBeCreated); + + final Target loadedTarget = targetManagement.findTargetByControllerID(targetToBeCreated.getControllerId()); + EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(postLoadEntityListener); + assertThat(postLoadEntityListener.getEntity()).isNotNull(); + assertThat(postLoadEntityListener.getEntity()).isEqualTo(loadedTarget); + } + + @Test + @Description("Verfies that the pre update is called after a entity update.") + public void preUpdateIsCalledWhenUpdateATarget() { + executeUpdateAndAssertCallbackResult(new PreUpdateEntityListener()); + } + + @Test + @Description("Verfies that the post update is called after a entity update.") + public void postUpdateIsCalledWhenUpdateATarget() { + executeUpdateAndAssertCallbackResult(new PostUpdateEntityListener()); + } + + @Test + @Description("Verfies that the pre remove is called after a entity deletion.") + public void preRemoveIsCalledWhenDeletingATarget() { + executeDeleteAndAssertCallbackResult(new PreRemoveEntityListener()); + } + + @Test + @Description("Verfies that the post remove is called after a entity deletion.") + public void postRemoveIsCalledWhenDeletinggATarget() { + executeDeleteAndAssertCallbackResult(new PostRemoveEntityListener()); + } + + private void executePersistAndAssertCallbackResult(final AbstractEntityListener entityInterceptor) { + final Target targetToBeCreated = entityFactory.generateTarget("targetToBeCreated"); + addListenerAndCreateTarget(entityInterceptor, targetToBeCreated); + + EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(entityInterceptor); + assertThat(entityInterceptor.getEntity()).isNotNull(); + assertThat(entityInterceptor.getEntity()).isEqualTo(targetToBeCreated); + } + + private void executeUpdateAndAssertCallbackResult(final AbstractEntityListener entityInterceptor) { + Target updateTarget = addListenerAndCreateTarget(entityInterceptor, + entityFactory.generateTarget("targetToBeCreated")); + updateTarget.setDescription("New"); + + updateTarget = targetManagement.updateTarget(updateTarget); + + EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(entityInterceptor); + assertThat(entityInterceptor.getEntity()).isNotNull(); + assertThat(entityInterceptor.getEntity()).isEqualTo(updateTarget); + } + + private void executeDeleteAndAssertCallbackResult(final AbstractEntityListener entityInterceptor) { + EntityInterceptorHolder.getInstance().getEntityInterceptors().add(entityInterceptor); + final SoftwareModuleType type = softwareManagement + .createSoftwareModuleType(entityFactory.generateSoftwareModuleType("test", "test", "test", 1)); + + softwareManagement.deleteSoftwareModuleType(type); + EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(entityInterceptor); + + assertThat(entityInterceptor.getEntity()).isNotNull(); + assertThat(entityInterceptor.getEntity()).isEqualTo(type); + } + + private Target addListenerAndCreateTarget(final AbstractEntityListener entityInterceptor, + final Target targetToBeCreated) { + EntityInterceptorHolder.getInstance().getEntityInterceptors().add(entityInterceptor); + + final Target createTarget = targetManagement.createTarget(targetToBeCreated); + + return createTarget; + } + + private static abstract class AbstractEntityListener implements EntityInterceptor { + + private Object entity; + + public Object getEntity() { + return entity; + } + + public void setEntity(final Object entity) { + this.entity = entity; + } + } + + private static class PrePersistEntityListener extends AbstractEntityListener { + @Override + public void prePersist(final Object entity) { + setEntity(entity); + } + } + + private static class PostPersistEntityListener extends AbstractEntityListener { + @Override + public void postPersist(final Object entity) { + setEntity(entity); + } + + } + + private static class PostLoadEntityListener extends AbstractEntityListener { + @Override + public void postLoad(final Object entity) { + setEntity(entity); + } + + } + + private static class PreUpdateEntityListener extends AbstractEntityListener { + @Override + public void preUpdate(final Object entity) { + setEntity(entity); + } + } + + private static class PostUpdateEntityListener extends AbstractEntityListener { + @Override + public void postUpdate(final Object entity) { + setEntity(entity); + } + } + + private static class PreRemoveEntityListener extends AbstractEntityListener { + @Override + public void preRemove(final Object entity) { + setEntity(entity); + } + } + + private static class PostRemoveEntityListener extends AbstractEntityListener { + @Override + public void postRemove(final Object entity) { + setEntity(entity); + } + } +} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index 3d09fabc3..a101ac755 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -182,6 +182,9 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { @After public void after() { testRepositoryManagement.clearTestRepository(); + + targetManagement.findAllTargetIds(); + } protected DefaultMockMvcBuilder createMvcWebAppContext() { From faac47d6e497e0c8d641f5c22c14ebeaee8d6259 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Thu, 28 Jul 2016 14:56:33 +0200 Subject: [PATCH 034/118] Remove useless findAllTargets Signed-off-by: SirWayne --- .../src/main/java/org/eclipse/hawkbit/tenancy/TenantAware.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAware.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAware.java index 689f5b01a..35199774a 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAware.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAware.java @@ -55,7 +55,7 @@ public interface TenantAware { * the return type of the runner */ @FunctionalInterface - interface TenantRunner { + public interface TenantRunner { /** * Called to run specific code and a given tenant. * From a74ec2897c4cc2e02be7fdf409a4acbfb850df33 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Thu, 28 Jul 2016 14:57:56 +0200 Subject: [PATCH 035/118] revert tenantaware remove useless findAlltargets fix typo Signed-off-by: SirWayne --- .../src/main/java/org/eclipse/hawkbit/tenancy/TenantAware.java | 2 +- .../repository/jpa/model/EntityInterceptorListenerTest.java | 2 +- .../hawkbit/repository/test/util/AbstractIntegrationTest.java | 3 --- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAware.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAware.java index 35199774a..689f5b01a 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAware.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/TenantAware.java @@ -55,7 +55,7 @@ public interface TenantAware { * the return type of the runner */ @FunctionalInterface - public interface TenantRunner { + interface TenantRunner { /** * Called to run specific code and a given tenant. * diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java index 05e27ae08..0bad51a3a 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java @@ -76,7 +76,7 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest { @Test @Description("Verfies that the post remove is called after a entity deletion.") - public void postRemoveIsCalledWhenDeletinggATarget() { + public void postRemoveIsCalledWhenDeletingATarget() { executeDeleteAndAssertCallbackResult(new PostRemoveEntityListener()); } diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index a101ac755..3d09fabc3 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -182,9 +182,6 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { @After public void after() { testRepositoryManagement.clearTestRepository(); - - targetManagement.findAllTargetIds(); - } protected DefaultMockMvcBuilder createMvcWebAppContext() { From c4b10982c52f4711e119ad4e489670872229059a Mon Sep 17 00:00:00 2001 From: SirWayne Date: Thu, 28 Jul 2016 15:04:31 +0200 Subject: [PATCH 036/118] Fix clean code Signed-off-by: SirWayne --- .../repository/jpa/model/EntityInterceptorListenerTest.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java index 0bad51a3a..760faa795 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java @@ -116,10 +116,7 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest { private Target addListenerAndCreateTarget(final AbstractEntityListener entityInterceptor, final Target targetToBeCreated) { EntityInterceptorHolder.getInstance().getEntityInterceptors().add(entityInterceptor); - - final Target createTarget = targetManagement.createTarget(targetToBeCreated); - - return createTarget; + return targetManagement.createTarget(targetToBeCreated); } private static abstract class AbstractEntityListener implements EntityInterceptor { From 2c70e7db1fa407964ddac3a81a6aa3ae4acd1a8f Mon Sep 17 00:00:00 2001 From: SirWayne Date: Thu, 28 Jul 2016 15:11:22 +0200 Subject: [PATCH 037/118] Refactor some clean code staff Signed-off-by: SirWayne --- .../jpa/model/EntityInterceptorListenerTest.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java index 760faa795..6dd86b3c4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java @@ -28,6 +28,12 @@ import ru.yandex.qatools.allure.annotations.Stories; @Stories("Entity Listener Interceptor") public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest { + @Override + public void after() { + EntityInterceptorHolder.getInstance().getEntityInterceptors().clear(); + super.after(); + } + @Test @Description("Verfies that the pre persist is called after a entity creation.") public void prePersistIsCalledWhenPersistingATarget() { @@ -51,7 +57,6 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest { targetManagement.createTarget(targetToBeCreated); final Target loadedTarget = targetManagement.findTargetByControllerID(targetToBeCreated.getControllerId()); - EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(postLoadEntityListener); assertThat(postLoadEntityListener.getEntity()).isNotNull(); assertThat(postLoadEntityListener.getEntity()).isEqualTo(loadedTarget); } @@ -84,7 +89,6 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest { final Target targetToBeCreated = entityFactory.generateTarget("targetToBeCreated"); addListenerAndCreateTarget(entityInterceptor, targetToBeCreated); - EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(entityInterceptor); assertThat(entityInterceptor.getEntity()).isNotNull(); assertThat(entityInterceptor.getEntity()).isEqualTo(targetToBeCreated); } @@ -96,7 +100,6 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest { updateTarget = targetManagement.updateTarget(updateTarget); - EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(entityInterceptor); assertThat(entityInterceptor.getEntity()).isNotNull(); assertThat(entityInterceptor.getEntity()).isEqualTo(updateTarget); } From 53136d48fdf3d9798b7f518939782f2258da5aae Mon Sep 17 00:00:00 2001 From: SirWayne Date: Thu, 28 Jul 2016 15:22:52 +0200 Subject: [PATCH 038/118] Refactor some clean code staff Signed-off-by: SirWayne --- .../repository/jpa/model/EntityInterceptorListenerTest.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java index 6dd86b3c4..c3db7ab76 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListenerTest.java @@ -48,7 +48,7 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest { @Test @Description("Verfies that the post load is called after a entity is loaded.") - public void postLoadIsCalledWhenLoadgATarget() { + public void postLoadIsCalledWhenLoadATarget() { final PostLoadEntityListener postLoadEntityListener = new PostLoadEntityListener(); EntityInterceptorHolder.getInstance().getEntityInterceptors().add(postLoadEntityListener); @@ -110,8 +110,6 @@ public class EntityInterceptorListenerTest extends AbstractJpaIntegrationTest { .createSoftwareModuleType(entityFactory.generateSoftwareModuleType("test", "test", "test", 1)); softwareManagement.deleteSoftwareModuleType(type); - EntityInterceptorHolder.getInstance().getEntityInterceptors().remove(entityInterceptor); - assertThat(entityInterceptor.getEntity()).isNotNull(); assertThat(entityInterceptor.getEntity()).isEqualTo(type); } From e32d6b1b3eb866f81f0ec430c4317a1670535af6 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 29 Jul 2016 12:33:10 +0200 Subject: [PATCH 039/118] Modified EOL from windows to unix. --- .../repository/DistributionSetManagement.java | 1216 +++++++-------- .../repository/SoftwareManagement.java | 1008 ++++++------- .../repository/jpa/JpaSoftwareManagement.java | 1344 ++++++++--------- .../repository/jpa/model/JpaAction.java | 398 ++--- .../jpa/model/JpaDistributionSet.java | 640 ++++---- .../repository/jpa/model/JpaRollout.java | 446 +++--- .../repository/jpa/model/JpaRolloutGroup.java | 522 +++---- .../repository/jpa/model/JpaTarget.java | 514 +++---- .../repository/jpa/model/JpaTargetInfo.java | 688 ++++----- 9 files changed, 3388 insertions(+), 3388 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index f7566b86b..b3b4fd86f 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -1,608 +1,608 @@ -/** - * 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; - -import java.util.Collection; -import java.util.List; -import java.util.Set; - -import javax.validation.constraints.NotNull; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.exception.DistributionSetCreationFailedMissingMandatoryModuleException; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetFilter; -import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; -import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; -import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.Tag; -import org.eclipse.hawkbit.repository.model.Target; -import org.hibernate.validator.constraints.NotEmpty; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.security.access.prepost.PreAuthorize; - -/** - * Management service for {@link DistributionSet}s. - * - */ -public interface DistributionSetManagement { - - // TODO rename/document the whole with details thing (document what the - // details are and maybe find a better name, e.g. with dependencies?) - - /** - * Assigns {@link SoftwareModule} to existing {@link DistributionSet}. - * - * @param ds - * to assign and update - * @param softwareModules - * to get assigned - * @return the updated {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet assignSoftwareModules(@NotNull DistributionSet ds, Set softwareModules); - - /** - * Assign a {@link DistributionSetTag} assignment to given - * {@link DistributionSet}s. - * - * @param dsIds - * to assign for - * @param tag - * to assign - * @return list of assigned ds - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List assignTag(@NotEmpty Collection dsIds, @NotNull DistributionSetTag tag); - - /** - * Count all {@link DistributionSet}s in the repository that are not marked - * as deleted. - * - * @return number of {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetsAll(); - - /** - * Count all {@link DistributionSet}s in the repository that are not marked - * as deleted. - * - * @param type - * to look for - * - * @return number of {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetsByType(@NotNull DistributionSetType type); - - /** - * @return number of {@link DistributionSetType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countDistributionSetTypesAll(); - - /** - * Creates a new {@link DistributionSet}. - * - * @param dSet - * {@link DistributionSet} to be created - * @return the new persisted {@link DistributionSet} - * - * @throws EntityAlreadyExistsException - * if a given entity already exists - * @throws DistributionSetCreationFailedMissingMandatoryModuleException - * is {@link DistributionSet} does not contain mandatory - * {@link SoftwareModule}s. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - DistributionSet createDistributionSet(@NotNull DistributionSet dSet); - - /** - * creates a list of distribution set meta data entries. - * - * @param metadata - * the meta data entries to create or update - * @return the updated or created distribution set meta data entries - * @throws EntityAlreadyExistsException - * in case one of the meta data entry already exists for the - * specific key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List createDistributionSetMetadata(@NotEmpty Collection metadata); - - /** - * creates or updates a single distribution set meta data entry. - * - * @param metadata - * the meta data entry to create or update - * @return the updated or created distribution set meta data entry - * @throws EntityAlreadyExistsException - * in case the meta data entry already exists for the specific - * key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetMetadata createDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); - - /** - * Creates multiple {@link DistributionSet}s. - * - * @param distributionSets - * to be created - * @return the new {@link DistributionSet}s - * @throws EntityAlreadyExistsException - * if a given entity already exists - * @throws DistributionSetCreationFailedMissingMandatoryModuleException - * is {@link DistributionSet} does not contain mandatory - * {@link SoftwareModule}s. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createDistributionSets(@NotNull Collection distributionSets); - - /** - * Creates new {@link DistributionSetType}. - * - * @param type - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - DistributionSetType createDistributionSetType(@NotNull DistributionSetType type); - - /** - * Creates multiple {@link DistributionSetType}s. - * - * @param types - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createDistributionSetTypes(@NotNull Collection types); - - /** - *

- * {@link DistributionSet} can be deleted/erased from the repository if they - * have never been assigned to any {@link UpdateAction} or {@link Target}. - *

- * - *

- * If they have been assigned that need to be marked as deleted which as a - * result means that they cannot be assigned anymore to any targets. (define - * e.g. findByDeletedFalse()) - *

- * - * @param set - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSet(@NotNull DistributionSet set); - - /** - * Deleted {@link DistributionSet}s by their IDs. That is either a soft - * delete of the entities have been linked to an {@link UpdateAction} before - * or a hard delete if not. - * - * @param distributionSetIDs - * to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSet(@NotEmpty Long... distributionSetIDs); - - /** - * deletes a distribution set meta data entry. - * - * @param id - * the ID of the distribution set meta data to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - void deleteDistributionSetMetadata(@NotNull final DistributionSet distributionSet, @NotNull final String key); - - /** - * Deletes or mark as delete in case the type is in use. - * - * @param type - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteDistributionSetType(@NotNull DistributionSetType type); - - /** - * retrieves the distribution set for a given action. - * - * @param action - * the action associated with the distribution set - * @return the distribution set which is associated with the action - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByAction(@NotNull Action action); - - /** - * Find {@link DistributionSet} based on given ID without details, e.g. - * {@link DistributionSet#getAgentHub()}. - * - * @param distid - * to look for. - * @return {@link DistributionSet} or null if it does not exist - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetById(@NotNull Long distid); - - /** - * Find {@link DistributionSet} based on given ID including (lazy loaded) - * details, e.g. {@link DistributionSet#getAgentHub()}. - * - * Note: for performance reasons it is recommended to use - * {@link #findDistributionSetById(Long)} if details are not necessary. - * - * @param distid - * to look for. - * @return {@link DistributionSet} or null if it does not exist - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByIdWithDetails(@NotNull Long distid); - - /** - * Find distribution set by name and version. - * - * @param distributionName - * name of {@link DistributionSet}; case insensitive - * @param version - * version of {@link DistributionSet} - * @return the page with the found {@link DistributionSet} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSet findDistributionSetByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version); - - /** - * finds all meta data by the given distribution set id. - * - * @param distributionSetId - * the distribution set id to retrieve the meta data from - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given distribution - * set id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, - @NotNull Pageable pageable); - - /** - * finds all meta data by the given distribution set id. - * - * @param distributionSetId - * the distribution set id to retrieve the meta data from - * @return list of distributionSetMetadata for a given distribution set Id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - List findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId); - - /** - * finds all meta data by the given distribution set id. - * - * @param distributionSetId - * the distribution set id to retrieve the meta data from - * @param rsqlParam - * rsql query string - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given distribution - * set id - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, - @NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Retrieves {@link DistributionSet} List for overview purposes (no - * {@link SoftwareModule}s and {@link DistributionSetTag}s). - * - * Please use {@link #findDistributionSetListWithDetails(Iterable)} if - * details are required. - * - * @param dist - * List of {@link DistributionSet} IDs to be found - * @return the found {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - List findDistributionSetsAll(Collection dist); - - // TODO discuss: use enum instead of the true,false,null switch ? - /** - * finds all {@link DistributionSet}s. - * - * @param pageReq - * the pagination parameter - * @param deleted - * if TRUE, {@link DistributionSet}s marked as deleted are - * returned. If FALSE, on {@link DistributionSet}s with - * {@link DistributionSet#isDeleted()} == FALSE are returned. - * null if both are to be returned - * @param complete - * to true for returning only completed distribution - * sets or false for only incomplete ones nor - * null to return both. - * @param complete - * set to if false incomplete DS should also be - * shown. - * - * - * @return all found {@link DistributionSet}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsByDeletedAndOrCompleted(@NotNull Pageable pageReq, Boolean deleted, - Boolean complete); - - /** - * finds all {@link DistributionSet}s. - * - * @param rsqlParam - * rsql query string - * @param pageReq - * the pagination parameter - * @param deleted - * if TRUE, {@link DistributionSet}s marked as deleted are - * returned. If FALSE, on {@link DistributionSet}s with - * {@link DistributionSet#isDeleted()} == FALSE are returned. - * null if both are to be returned - * @return all found {@link DistributionSet}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsAll(@NotNull String rsqlParam, @NotNull Pageable pageReq, - Boolean deleted); - - /** - * method retrieves all {@link DistributionSet}s from the repository in the - * following order: - *

- * 1) {@link DistributionSet}s which have the given {@link Target} as - * {@link TargetStatus#getInstalledDistributionSet()} - *

- * 2) {@link DistributionSet}s which have the given {@link Target} as - * {@link Target#getAssignedDistributionSet()} - *

- * 3) {@link DistributionSet}s which have no connection to the given - * {@link Target} ordered by ID of the DistributionSet. - * - * @param pageable - * the page request to page the result set * - * @param distributionSetFilterBuilder - * has details of filters to be applied - * @param assignedOrInstalled - * the controllerID of the Target to be ordered by - * @return - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsAllOrderedByLinkTarget(@NotNull Pageable pageable, - @NotNull DistributionSetFilterBuilder distributionSetFilterBuilder, @NotEmpty String assignedOrInstalled); - - /** - * retrieves {@link DistributionSet}s by filtering on the given parameters. - * - * @param pageable - * page parameter - * @param distributionSetFilter - * has details of filters to be applied. - * @return the page of found {@link DistributionSet} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetsByFilters(@NotNull Pageable pageable, - @NotNull DistributionSetFilter distributionSetFilter); - - /** - * @param id - * as {@link DistributionSetType#getId()} - * @return {@link DistributionSetType} if found or null if not - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeById(@NotNull Long id); - - /** - * @param key - * as {@link DistributionSetType#getKey()} - * @return {@link DistributionSetType} if found or null if not - */ - - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeByKey(@NotNull String key); - - /** - * @param name - * as {@link DistributionSetType#getName()} - * @return {@link DistributionSetType} if found or null if not - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetType findDistributionSetTypeByName(@NotEmpty String name); - - /** - * @param pageable - * parameter - * @return all {@link DistributionSetType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetTypesAll(@NotNull Pageable pageable); - - /** - * Generic predicate based query for {@link DistributionSetType}. - * - * @param rsqlParam - * rsql query string - * @param pageable - * parameter for paging - * - * @return the found {@link SoftwareModuleType}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findDistributionSetTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * finds a single distribution set meta data by its id. - * - * @param id - * the id of the distribution set meta data containing the meta - * data key and the ID of the distribution set - * @return the found DistributionSetMetadata or {@code null} if not exits - * @throws EntityNotFoundException - * in case the meta data does not exists for the given key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - DistributionSetMetadata findOne(@NotNull DistributionSet distributionSet, @NotNull String key); - - /** - * Checks if a {@link DistributionSet} is currently in use by a target in - * the repository. - * - * @param distributionSet - * to check - * - * @return true if in use - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - boolean isDistributionSetInUse(@NotNull DistributionSet distributionSet); - - /** - * {@link Entity} based method call for - * {@link #toggleTagAssignment(Collection, String)}. - * - * @param sets - * to toggle for - * @param tag - * to toggle - * @return {@link DistributionSetTagAssignmentResult} with all meta data of - * the assignment outcome. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection sets, - @NotNull DistributionSetTag tag); - - /** - * Toggles {@link DistributionSetTag} assignment to given - * {@link DistributionSet}s by means that if some (or all) of the targets in - * the list have the {@link Tag} not yet assigned, they will be. If all of - * theme have the tag already assigned they will be removed instead. - * - * @param dsIds - * to toggle for - * @param tagName - * to toggle - * @return {@link DistributionSetTagAssignmentResult} with all meta data of - * the assignment outcome. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection dsIds, @NotNull String tagName); - - /** - * Unassign all {@link DistributionSet} from a given - * {@link DistributionSetTag} . - * - * @param tag - * to unassign all ds - * @return list of unassigned ds - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List unAssignAllDistributionSetsByTag(@NotNull DistributionSetTag tag); - - /** - * Unassigns a {@link SoftwareModule} form an existing - * {@link DistributionSet}. - * - * @param ds - * to get unassigned form - * @param softwareModule - * to get unassigned - * @return the updated {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet unassignSoftwareModule(@NotNull DistributionSet ds, @NotNull SoftwareModule softwareModule); - - /** - * Unassign a {@link DistributionSetTag} assignment to given - * {@link DistributionSet}. - * - * @param dsId - * to unassign for - * @param distributionSetTag - * to unassign - * @return the unassigned ds or if no ds is unassigned - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet unAssignTag(@NotNull Long dsId, @NotNull DistributionSetTag distributionSetTag); - - /** - * Updates existing {@link DistributionSet}. - * - * @param ds - * to update - * @return the saved {@link Entity}. - * @throws NullPointerException - * of {@link DistributionSet#getId()} is null - * @throw DataDependencyViolationException in case of illegal update - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSet updateDistributionSet(@NotNull DistributionSet ds); - - /** - * updates a distribution set meta data value if corresponding entry exists. - * - * @param metadata - * the meta data entry to be updated - * @return the updated meta data entry - * @throws EntityNotFoundException - * in case the meta data entry does not exists and cannot be - * updated - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetMetadata updateDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); - - /** - * Updates existing {@link DistributionSetType}. However, keep in mind that - * is not possible to change the {@link DistributionSetTypeElement}s while - * the DS type is already in use. - * - * @param dsType - * to update - * @return updated {@link Entity} - * - * @throws EntityReadOnlyException - * if use tries to change the {@link DistributionSetTypeElement} - * s while the DS type is already in use. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - DistributionSetType updateDistributionSetType(@NotNull DistributionSetType dsType); - -} +/** + * 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; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +import javax.validation.constraints.NotNull; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.exception.DistributionSetCreationFailedMissingMandatoryModuleException; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.exception.EntityReadOnlyException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetFilter; +import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder; +import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.repository.model.Tag; +import org.eclipse.hawkbit.repository.model.Target; +import org.hibernate.validator.constraints.NotEmpty; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.security.access.prepost.PreAuthorize; + +/** + * Management service for {@link DistributionSet}s. + * + */ +public interface DistributionSetManagement { + + // TODO rename/document the whole with details thing (document what the + // details are and maybe find a better name, e.g. with dependencies?) + + /** + * Assigns {@link SoftwareModule} to existing {@link DistributionSet}. + * + * @param ds + * to assign and update + * @param softwareModules + * to get assigned + * @return the updated {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet assignSoftwareModules(@NotNull DistributionSet ds, Set softwareModules); + + /** + * Assign a {@link DistributionSetTag} assignment to given + * {@link DistributionSet}s. + * + * @param dsIds + * to assign for + * @param tag + * to assign + * @return list of assigned ds + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List assignTag(@NotEmpty Collection dsIds, @NotNull DistributionSetTag tag); + + /** + * Count all {@link DistributionSet}s in the repository that are not marked + * as deleted. + * + * @return number of {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetsAll(); + + /** + * Count all {@link DistributionSet}s in the repository that are not marked + * as deleted. + * + * @param type + * to look for + * + * @return number of {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetsByType(@NotNull DistributionSetType type); + + /** + * @return number of {@link DistributionSetType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countDistributionSetTypesAll(); + + /** + * Creates a new {@link DistributionSet}. + * + * @param dSet + * {@link DistributionSet} to be created + * @return the new persisted {@link DistributionSet} + * + * @throws EntityAlreadyExistsException + * if a given entity already exists + * @throws DistributionSetCreationFailedMissingMandatoryModuleException + * is {@link DistributionSet} does not contain mandatory + * {@link SoftwareModule}s. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + DistributionSet createDistributionSet(@NotNull DistributionSet dSet); + + /** + * creates a list of distribution set meta data entries. + * + * @param metadata + * the meta data entries to create or update + * @return the updated or created distribution set meta data entries + * @throws EntityAlreadyExistsException + * in case one of the meta data entry already exists for the + * specific key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List createDistributionSetMetadata(@NotEmpty Collection metadata); + + /** + * creates or updates a single distribution set meta data entry. + * + * @param metadata + * the meta data entry to create or update + * @return the updated or created distribution set meta data entry + * @throws EntityAlreadyExistsException + * in case the meta data entry already exists for the specific + * key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetMetadata createDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); + + /** + * Creates multiple {@link DistributionSet}s. + * + * @param distributionSets + * to be created + * @return the new {@link DistributionSet}s + * @throws EntityAlreadyExistsException + * if a given entity already exists + * @throws DistributionSetCreationFailedMissingMandatoryModuleException + * is {@link DistributionSet} does not contain mandatory + * {@link SoftwareModule}s. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createDistributionSets(@NotNull Collection distributionSets); + + /** + * Creates new {@link DistributionSetType}. + * + * @param type + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + DistributionSetType createDistributionSetType(@NotNull DistributionSetType type); + + /** + * Creates multiple {@link DistributionSetType}s. + * + * @param types + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createDistributionSetTypes(@NotNull Collection types); + + /** + *

+ * {@link DistributionSet} can be deleted/erased from the repository if they + * have never been assigned to any {@link UpdateAction} or {@link Target}. + *

+ * + *

+ * If they have been assigned that need to be marked as deleted which as a + * result means that they cannot be assigned anymore to any targets. (define + * e.g. findByDeletedFalse()) + *

+ * + * @param set + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSet(@NotNull DistributionSet set); + + /** + * Deleted {@link DistributionSet}s by their IDs. That is either a soft + * delete of the entities have been linked to an {@link UpdateAction} before + * or a hard delete if not. + * + * @param distributionSetIDs + * to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSet(@NotEmpty Long... distributionSetIDs); + + /** + * deletes a distribution set meta data entry. + * + * @param id + * the ID of the distribution set meta data to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + void deleteDistributionSetMetadata(@NotNull final DistributionSet distributionSet, @NotNull final String key); + + /** + * Deletes or mark as delete in case the type is in use. + * + * @param type + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteDistributionSetType(@NotNull DistributionSetType type); + + /** + * retrieves the distribution set for a given action. + * + * @param action + * the action associated with the distribution set + * @return the distribution set which is associated with the action + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByAction(@NotNull Action action); + + /** + * Find {@link DistributionSet} based on given ID without details, e.g. + * {@link DistributionSet#getAgentHub()}. + * + * @param distid + * to look for. + * @return {@link DistributionSet} or null if it does not exist + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetById(@NotNull Long distid); + + /** + * Find {@link DistributionSet} based on given ID including (lazy loaded) + * details, e.g. {@link DistributionSet#getAgentHub()}. + * + * Note: for performance reasons it is recommended to use + * {@link #findDistributionSetById(Long)} if details are not necessary. + * + * @param distid + * to look for. + * @return {@link DistributionSet} or null if it does not exist + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByIdWithDetails(@NotNull Long distid); + + /** + * Find distribution set by name and version. + * + * @param distributionName + * name of {@link DistributionSet}; case insensitive + * @param version + * version of {@link DistributionSet} + * @return the page with the found {@link DistributionSet} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSet findDistributionSetByNameAndVersion(@NotEmpty String distributionName, @NotEmpty String version); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given distribution + * set id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, + @NotNull Pageable pageable); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @return list of distributionSetMetadata for a given distribution set Id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId); + + /** + * finds all meta data by the given distribution set id. + * + * @param distributionSetId + * the distribution set id to retrieve the meta data from + * @param rsqlParam + * rsql query string + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given distribution + * set id + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId, + @NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Retrieves {@link DistributionSet} List for overview purposes (no + * {@link SoftwareModule}s and {@link DistributionSetTag}s). + * + * Please use {@link #findDistributionSetListWithDetails(Iterable)} if + * details are required. + * + * @param dist + * List of {@link DistributionSet} IDs to be found + * @return the found {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findDistributionSetsAll(Collection dist); + + // TODO discuss: use enum instead of the true,false,null switch ? + /** + * finds all {@link DistributionSet}s. + * + * @param pageReq + * the pagination parameter + * @param deleted + * if TRUE, {@link DistributionSet}s marked as deleted are + * returned. If FALSE, on {@link DistributionSet}s with + * {@link DistributionSet#isDeleted()} == FALSE are returned. + * null if both are to be returned + * @param complete + * to true for returning only completed distribution + * sets or false for only incomplete ones nor + * null to return both. + * @param complete + * set to if false incomplete DS should also be + * shown. + * + * + * @return all found {@link DistributionSet}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsByDeletedAndOrCompleted(@NotNull Pageable pageReq, Boolean deleted, + Boolean complete); + + /** + * finds all {@link DistributionSet}s. + * + * @param rsqlParam + * rsql query string + * @param pageReq + * the pagination parameter + * @param deleted + * if TRUE, {@link DistributionSet}s marked as deleted are + * returned. If FALSE, on {@link DistributionSet}s with + * {@link DistributionSet#isDeleted()} == FALSE are returned. + * null if both are to be returned + * @return all found {@link DistributionSet}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsAll(@NotNull String rsqlParam, @NotNull Pageable pageReq, + Boolean deleted); + + /** + * method retrieves all {@link DistributionSet}s from the repository in the + * following order: + *

+ * 1) {@link DistributionSet}s which have the given {@link Target} as + * {@link TargetStatus#getInstalledDistributionSet()} + *

+ * 2) {@link DistributionSet}s which have the given {@link Target} as + * {@link Target#getAssignedDistributionSet()} + *

+ * 3) {@link DistributionSet}s which have no connection to the given + * {@link Target} ordered by ID of the DistributionSet. + * + * @param pageable + * the page request to page the result set * + * @param distributionSetFilterBuilder + * has details of filters to be applied + * @param assignedOrInstalled + * the controllerID of the Target to be ordered by + * @return + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsAllOrderedByLinkTarget(@NotNull Pageable pageable, + @NotNull DistributionSetFilterBuilder distributionSetFilterBuilder, @NotEmpty String assignedOrInstalled); + + /** + * retrieves {@link DistributionSet}s by filtering on the given parameters. + * + * @param pageable + * page parameter + * @param distributionSetFilter + * has details of filters to be applied. + * @return the page of found {@link DistributionSet} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetsByFilters(@NotNull Pageable pageable, + @NotNull DistributionSetFilter distributionSetFilter); + + /** + * @param id + * as {@link DistributionSetType#getId()} + * @return {@link DistributionSetType} if found or null if not + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeById(@NotNull Long id); + + /** + * @param key + * as {@link DistributionSetType#getKey()} + * @return {@link DistributionSetType} if found or null if not + */ + + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeByKey(@NotNull String key); + + /** + * @param name + * as {@link DistributionSetType#getName()} + * @return {@link DistributionSetType} if found or null if not + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetType findDistributionSetTypeByName(@NotEmpty String name); + + /** + * @param pageable + * parameter + * @return all {@link DistributionSetType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetTypesAll(@NotNull Pageable pageable); + + /** + * Generic predicate based query for {@link DistributionSetType}. + * + * @param rsqlParam + * rsql query string + * @param pageable + * parameter for paging + * + * @return the found {@link SoftwareModuleType}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findDistributionSetTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * finds a single distribution set meta data by its id. + * + * @param id + * the id of the distribution set meta data containing the meta + * data key and the ID of the distribution set + * @return the found DistributionSetMetadata or {@code null} if not exits + * @throws EntityNotFoundException + * in case the meta data does not exists for the given key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + DistributionSetMetadata findOne(@NotNull DistributionSet distributionSet, @NotNull String key); + + /** + * Checks if a {@link DistributionSet} is currently in use by a target in + * the repository. + * + * @param distributionSet + * to check + * + * @return true if in use + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + boolean isDistributionSetInUse(@NotNull DistributionSet distributionSet); + + /** + * {@link Entity} based method call for + * {@link #toggleTagAssignment(Collection, String)}. + * + * @param sets + * to toggle for + * @param tag + * to toggle + * @return {@link DistributionSetTagAssignmentResult} with all meta data of + * the assignment outcome. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection sets, + @NotNull DistributionSetTag tag); + + /** + * Toggles {@link DistributionSetTag} assignment to given + * {@link DistributionSet}s by means that if some (or all) of the targets in + * the list have the {@link Tag} not yet assigned, they will be. If all of + * theme have the tag already assigned they will be removed instead. + * + * @param dsIds + * to toggle for + * @param tagName + * to toggle + * @return {@link DistributionSetTagAssignmentResult} with all meta data of + * the assignment outcome. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetTagAssignmentResult toggleTagAssignment(@NotEmpty Collection dsIds, @NotNull String tagName); + + /** + * Unassign all {@link DistributionSet} from a given + * {@link DistributionSetTag} . + * + * @param tag + * to unassign all ds + * @return list of unassigned ds + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List unAssignAllDistributionSetsByTag(@NotNull DistributionSetTag tag); + + /** + * Unassigns a {@link SoftwareModule} form an existing + * {@link DistributionSet}. + * + * @param ds + * to get unassigned form + * @param softwareModule + * to get unassigned + * @return the updated {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet unassignSoftwareModule(@NotNull DistributionSet ds, @NotNull SoftwareModule softwareModule); + + /** + * Unassign a {@link DistributionSetTag} assignment to given + * {@link DistributionSet}. + * + * @param dsId + * to unassign for + * @param distributionSetTag + * to unassign + * @return the unassigned ds or if no ds is unassigned + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet unAssignTag(@NotNull Long dsId, @NotNull DistributionSetTag distributionSetTag); + + /** + * Updates existing {@link DistributionSet}. + * + * @param ds + * to update + * @return the saved {@link Entity}. + * @throws NullPointerException + * of {@link DistributionSet#getId()} is null + * @throw DataDependencyViolationException in case of illegal update + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSet updateDistributionSet(@NotNull DistributionSet ds); + + /** + * updates a distribution set meta data value if corresponding entry exists. + * + * @param metadata + * the meta data entry to be updated + * @return the updated meta data entry + * @throws EntityNotFoundException + * in case the meta data entry does not exists and cannot be + * updated + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetMetadata updateDistributionSetMetadata(@NotNull DistributionSetMetadata metadata); + + /** + * Updates existing {@link DistributionSetType}. However, keep in mind that + * is not possible to change the {@link DistributionSetTypeElement}s while + * the DS type is already in use. + * + * @param dsType + * to update + * @return updated {@link Entity} + * + * @throws EntityReadOnlyException + * if use tries to change the {@link DistributionSetTypeElement} + * s while the DS type is already in use. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + DistributionSetType updateDistributionSetType(@NotNull DistributionSetType dsType); + +} diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java index e48aaa3ab..bb73dbb30 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java @@ -1,504 +1,504 @@ -/** - * 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; - -import java.util.Collection; -import java.util.List; - -import javax.validation.constraints.NotNull; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; -import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; -import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.hibernate.validator.constraints.NotEmpty; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.security.access.prepost.PreAuthorize; - -/** - * Service for managing {@link SoftwareModule}s. - * - */ -public interface SoftwareManagement { - - /** - * Counts {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * and {@link SoftwareModule#getType()} that are not marked as deleted. - * - * @param searchText - * to search for in name and version - * @param type - * to filter the result - * @return number of found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModuleByFilters(String searchText, SoftwareModuleType type); - - /** - * Count all {@link SoftwareModule}s in the repository that are not marked - * as deleted. - * - * @return number of {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModulesAll(); - - /** - * Counts {@link SoftwareModule}s with given {@link SoftwareModuleType}. - * - * @param type - * to count - * @return number of found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModulesByType(@NotNull SoftwareModuleType type); - - /** - * @return number of {@link SoftwareModuleType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Long countSoftwareModuleTypesAll(); - - /** - * Create {@link SoftwareModule}s in the repository. - * - * @param swModules - * {@link SoftwareModule}s to create - * @return SoftwareModule - * @throws EntityAlreadyExistsException - * if a given entity already exists - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createSoftwareModule(@NotNull Collection swModules); - - /** - * - * @param swModule - * SoftwareModule to create - * @return SoftwareModule - * @throws EntityAlreadyExistsException - * if a given entity already exists - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - SoftwareModule createSoftwareModule(@NotNull SoftwareModule swModule); - - /** - * creates a list of software module meta data entries. - * - * @param metadata - * the meta data entries to create or update - * @return the updated or created software module meta data entries - * @throws EntityAlreadyExistsException - * in case one of the meta data entry already exists for the - * specific key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - List createSoftwareModuleMetadata(@NotNull Collection metadata); - - /** - * creates or updates a single software module meta data entry. - * - * @param metadata - * the meta data entry to create or update - * @return the updated or created software module meta data entry - * @throws EntityAlreadyExistsException - * in case the meta data entry already exists for the specific - * key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleMetadata createSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); - - /** - * Creates multiple {@link SoftwareModuleType}s. - * - * @param types - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - List createSoftwareModuleType(@NotNull final Collection types); - - /** - * Creates new {@link SoftwareModuleType}. - * - * @param type - * to create - * @return created {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) - SoftwareModuleType createSoftwareModuleType(@NotNull SoftwareModuleType type); - - /** - * Deletes the given {@link SoftwareModule} {@link Entity}. - * - * @param bsm - * is the {@link SoftwareModule} to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModule(@NotNull SoftwareModule bsm); - - /** - * deletes a software module meta data entry. - * - * @param id - * the ID of the software module meta data to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - void deleteSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotNull String key); - - /** - * Deletes {@link SoftwareModule}s which is any if the given ids. - * - * @param ids - * of the Software Modules to be deleted - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModules(@NotNull Collection ids); - - /** - * Deletes or marks as delete in case the type is in use. - * - * @param type - * to delete - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) - void deleteSoftwareModuleType(@NotNull SoftwareModuleType type); - - /** - * @param pageable - * the page request to page the result set - * @param set - * to search for - * @return all {@link SoftwareModule}s that are assigned to given - * {@link DistributionSet}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleByAssignedTo(@NotNull Pageable pageable, @NotNull DistributionSet set); - - /** - * @param pageable - * the page request to page the result set - * @param set - * to search for - * @param type - * to filter - * @return all {@link SoftwareModule}s that are assigned to given - * {@link DistributionSet} filtered by {@link SoftwareModuleType}. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleByAssignedToAndType(@NotNull Pageable pageable, @NotNull DistributionSet set, - @NotNull SoftwareModuleType type); - - /** - * Filter {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * and {@link SoftwareModule#getType()} that are not marked as deleted. - * - * @param pageable - * page parameter - * @param searchText - * to be filtered as "like" on {@link SoftwareModule#getName()} - * @param type - * to be filtered as "like" on {@link SoftwareModule#getType()} - * @return the page of found {@link SoftwareModule} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModuleByFilters(@NotNull Pageable pageable, String searchText, - SoftwareModuleType type); - - /** - * Finds {@link SoftwareModule} by given id. - * - * @param id - * to search for - * @return the found {@link SoftwareModule}s or null if not - * found. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR - + SpringEvalExpressions.IS_CONTROLLER) - SoftwareModule findSoftwareModuleById(@NotNull Long id); - - /** - * retrieves {@link SoftwareModule} by their name AND version AND type.. - * - * @param name - * of the {@link SoftwareModule} - * @param version - * of the {@link SoftwareModule} - * @param type - * of the {@link SoftwareModule} - * @return the found {@link SoftwareModule} or null - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModule findSoftwareModuleByNameAndVersion(@NotEmpty String name, @NotEmpty String version, - @NotNull SoftwareModuleType type); - - /** - * finds a single software module meta data by its id. - * - * @param id - * the id of the software module meta data containing the meta - * data key and the ID of the software module - * @return the found SoftwareModuleMetadata or {@code null} if not exits - * @throws EntityNotFoundException - * in case the meta data does not exists for the given key - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleMetadata findSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotEmpty String key); - - /** - * finds all meta data by the given software module id. - * - * @param swId - * the software module id to retrieve the meta data from - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given software - * module id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long swId, - @NotNull Pageable pageable); - - /** - * finds all meta data by the given software module id. - * - * @param softwareModuleId - * the software module id to retrieve the meta data from - * @param spec - * the specification to filter the result - * @param pageable - * the page request to page the result - * @return a paged result of all meta data entries for a given software - * module id - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long softwareModuleId, - @NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Filter {@link SoftwareModule}s with given - * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} - * search text and {@link SoftwareModule#getType()} that are not marked as - * deleted and sort them by means of given distribution set related modules - * on top of the list. - * - * After that the modules are sorted by {@link SoftwareModule#getName()} and - * {@link SoftwareModule#getVersion()} in ascending order. - * - * @param pageable - * page parameter - * @param orderByDistributionId - * the ID of distribution set to be ordered on top - * @param searchText - * filtered as "like" on {@link SoftwareModule#getName()} - * @param type - * filtered as "equal" on {@link SoftwareModule#getType()} - * @return the page of found {@link SoftwareModule} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( - @NotNull Pageable pageable, @NotNull Long orderByDistributionId, String searchText, - SoftwareModuleType type); - - /** - * Retrieves all software modules. Deleted ones are filtered. - * - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModulesAll(@NotNull Pageable pageable); - - /** - * Retrieves all software modules with a given list of ids - * {@link SoftwareModule#getId()}. - * - * @param ids - * to search for - * @return {@link List} of found {@link SoftwareModule}s - */ - List findSoftwareModulesById(@NotEmpty Collection ids); - - /** - * Retrieves all {@link SoftwareModule}s with a given specification. - * - * @param spec - * the specification to filter the software modules - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModule}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModulesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType} - * . - * - * @param pageable - * page parameters - * @param type - * to be filtered on - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Slice findSoftwareModulesByType(@NotNull Pageable pageable, @NotNull SoftwareModuleType type); - - /** - * - * @param id - * to search for - * @return {@link SoftwareModuleType} in the repository with given - * {@link SoftwareModuleType#getId()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeById(@NotNull Long id); - - /** - * - * @param key - * to search for - * @return {@link SoftwareModuleType} in the repository with given - * {@link SoftwareModuleType#getKey()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeByKey(@NotNull String key); - - /** - * - * @param name - * to search for - * @return all {@link SoftwareModuleType}s in the repository with given - * {@link SoftwareModuleType#getName()} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModuleType findSoftwareModuleTypeByName(@NotNull String name); - - /** - * @param pageable - * parameter - * @return all {@link SoftwareModuleType}s in the repository. - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleTypesAll(@NotNull Pageable pageable); - - /** - * Retrieves all {@link SoftwareModuleType}s with a given specification. - * - * @param spec - * the specification to filter the software modules types - * @param pageable - * pagination parameter - * @return the found {@link SoftwareModuleType}s - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - Page findSoftwareModuleTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); - - /** - * Retrieves software module including details ( - * {@link SoftwareModule#getArtifacts()}). - * - * @param id - * parameter - * @param isDeleted - * parameter - * @return the found {@link SoftwareModule}s - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - SoftwareModule findSoftwareModuleWithDetails(@NotNull Long id); - - /** - * Updates existing {@link SoftwareModule}. Update-able values are - * {@link SoftwareModule#getDescription()} - * {@link SoftwareModule#getVendor()}. - * - * @param sm - * to update - * - * @return the saved {@link Entity}. - * - * @throws NullPointerException - * of {@link SoftwareModule#getId()} is null - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModule updateSoftwareModule(@NotNull SoftwareModule sm); - - /** - * updates a distribution set meta data value if corresponding entry exists. - * - * @param metadata - * the meta data entry to be updated - * @return the updated meta data entry - * @throws EntityNotFoundException - * in case the meta data entry does not exists and cannot be - * updated - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleMetadata updateSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); - - /** - * Updates existing {@link SoftwareModuleType}. Update-able value is - * {@link SoftwareModuleType#getDescription()} and - * {@link SoftwareModuleType#getColour()}. - * - * @param sm - * to update - * @return updated {@link Entity} - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) - SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm); - - /** - * finds all meta data by the given software module id. - * - * @param softwareModuleId - * the software module id to retrieve the meta data from - - * - * @throws RSQLParameterUnsupportedFieldException - * if a field in the RSQL string is used but not provided by the - * given {@code fieldNameProvider} - * @throws RSQLParameterSyntaxException - * if the RSQL syntax is wrong - * @return result of all meta data entries for a given software - * module id - */ - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - List findSoftwareModuleMetadataBySoftwareModuleId(Long softwareModuleId); - -} +/** + * 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; + +import java.util.Collection; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; +import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; +import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.hibernate.validator.constraints.NotEmpty; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.security.access.prepost.PreAuthorize; + +/** + * Service for managing {@link SoftwareModule}s. + * + */ +public interface SoftwareManagement { + + /** + * Counts {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * and {@link SoftwareModule#getType()} that are not marked as deleted. + * + * @param searchText + * to search for in name and version + * @param type + * to filter the result + * @return number of found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModuleByFilters(String searchText, SoftwareModuleType type); + + /** + * Count all {@link SoftwareModule}s in the repository that are not marked + * as deleted. + * + * @return number of {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModulesAll(); + + /** + * Counts {@link SoftwareModule}s with given {@link SoftwareModuleType}. + * + * @param type + * to count + * @return number of found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModulesByType(@NotNull SoftwareModuleType type); + + /** + * @return number of {@link SoftwareModuleType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Long countSoftwareModuleTypesAll(); + + /** + * Create {@link SoftwareModule}s in the repository. + * + * @param swModules + * {@link SoftwareModule}s to create + * @return SoftwareModule + * @throws EntityAlreadyExistsException + * if a given entity already exists + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createSoftwareModule(@NotNull Collection swModules); + + /** + * + * @param swModule + * SoftwareModule to create + * @return SoftwareModule + * @throws EntityAlreadyExistsException + * if a given entity already exists + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + SoftwareModule createSoftwareModule(@NotNull SoftwareModule swModule); + + /** + * creates a list of software module meta data entries. + * + * @param metadata + * the meta data entries to create or update + * @return the updated or created software module meta data entries + * @throws EntityAlreadyExistsException + * in case one of the meta data entry already exists for the + * specific key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + List createSoftwareModuleMetadata(@NotNull Collection metadata); + + /** + * creates or updates a single software module meta data entry. + * + * @param metadata + * the meta data entry to create or update + * @return the updated or created software module meta data entry + * @throws EntityAlreadyExistsException + * in case the meta data entry already exists for the specific + * key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleMetadata createSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); + + /** + * Creates multiple {@link SoftwareModuleType}s. + * + * @param types + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + List createSoftwareModuleType(@NotNull final Collection types); + + /** + * Creates new {@link SoftwareModuleType}. + * + * @param type + * to create + * @return created {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_CREATE_REPOSITORY) + SoftwareModuleType createSoftwareModuleType(@NotNull SoftwareModuleType type); + + /** + * Deletes the given {@link SoftwareModule} {@link Entity}. + * + * @param bsm + * is the {@link SoftwareModule} to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModule(@NotNull SoftwareModule bsm); + + /** + * deletes a software module meta data entry. + * + * @param id + * the ID of the software module meta data to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + void deleteSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotNull String key); + + /** + * Deletes {@link SoftwareModule}s which is any if the given ids. + * + * @param ids + * of the Software Modules to be deleted + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModules(@NotNull Collection ids); + + /** + * Deletes or marks as delete in case the type is in use. + * + * @param type + * to delete + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_DELETE_REPOSITORY) + void deleteSoftwareModuleType(@NotNull SoftwareModuleType type); + + /** + * @param pageable + * the page request to page the result set + * @param set + * to search for + * @return all {@link SoftwareModule}s that are assigned to given + * {@link DistributionSet}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleByAssignedTo(@NotNull Pageable pageable, @NotNull DistributionSet set); + + /** + * @param pageable + * the page request to page the result set + * @param set + * to search for + * @param type + * to filter + * @return all {@link SoftwareModule}s that are assigned to given + * {@link DistributionSet} filtered by {@link SoftwareModuleType}. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleByAssignedToAndType(@NotNull Pageable pageable, @NotNull DistributionSet set, + @NotNull SoftwareModuleType type); + + /** + * Filter {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * and {@link SoftwareModule#getType()} that are not marked as deleted. + * + * @param pageable + * page parameter + * @param searchText + * to be filtered as "like" on {@link SoftwareModule#getName()} + * @param type + * to be filtered as "like" on {@link SoftwareModule#getType()} + * @return the page of found {@link SoftwareModule} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModuleByFilters(@NotNull Pageable pageable, String searchText, + SoftwareModuleType type); + + /** + * Finds {@link SoftwareModule} by given id. + * + * @param id + * to search for + * @return the found {@link SoftwareModule}s or null if not + * found. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.IS_CONTROLLER) + SoftwareModule findSoftwareModuleById(@NotNull Long id); + + /** + * retrieves {@link SoftwareModule} by their name AND version AND type.. + * + * @param name + * of the {@link SoftwareModule} + * @param version + * of the {@link SoftwareModule} + * @param type + * of the {@link SoftwareModule} + * @return the found {@link SoftwareModule} or null + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModule findSoftwareModuleByNameAndVersion(@NotEmpty String name, @NotEmpty String version, + @NotNull SoftwareModuleType type); + + /** + * finds a single software module meta data by its id. + * + * @param id + * the id of the software module meta data containing the meta + * data key and the ID of the software module + * @return the found SoftwareModuleMetadata or {@code null} if not exits + * @throws EntityNotFoundException + * in case the meta data does not exists for the given key + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleMetadata findSoftwareModuleMetadata(@NotNull SoftwareModule softwareModule, @NotEmpty String key); + + /** + * finds all meta data by the given software module id. + * + * @param swId + * the software module id to retrieve the meta data from + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given software + * module id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long swId, + @NotNull Pageable pageable); + + /** + * finds all meta data by the given software module id. + * + * @param softwareModuleId + * the software module id to retrieve the meta data from + * @param spec + * the specification to filter the result + * @param pageable + * the page request to page the result + * @return a paged result of all meta data entries for a given software + * module id + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleMetadataBySoftwareModuleId(@NotNull Long softwareModuleId, + @NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Filter {@link SoftwareModule}s with given + * {@link SoftwareModule#getName()} or {@link SoftwareModule#getVersion()} + * search text and {@link SoftwareModule#getType()} that are not marked as + * deleted and sort them by means of given distribution set related modules + * on top of the list. + * + * After that the modules are sorted by {@link SoftwareModule#getName()} and + * {@link SoftwareModule#getVersion()} in ascending order. + * + * @param pageable + * page parameter + * @param orderByDistributionId + * the ID of distribution set to be ordered on top + * @param searchText + * filtered as "like" on {@link SoftwareModule#getName()} + * @param type + * filtered as "equal" on {@link SoftwareModule#getType()} + * @return the page of found {@link SoftwareModule} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( + @NotNull Pageable pageable, @NotNull Long orderByDistributionId, String searchText, + SoftwareModuleType type); + + /** + * Retrieves all software modules. Deleted ones are filtered. + * + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModulesAll(@NotNull Pageable pageable); + + /** + * Retrieves all software modules with a given list of ids + * {@link SoftwareModule#getId()}. + * + * @param ids + * to search for + * @return {@link List} of found {@link SoftwareModule}s + */ + List findSoftwareModulesById(@NotEmpty Collection ids); + + /** + * Retrieves all {@link SoftwareModule}s with a given specification. + * + * @param spec + * the specification to filter the software modules + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModule}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModulesByPredicate(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * retrieves the {@link SoftwareModule}s by their {@link SoftwareModuleType} + * . + * + * @param pageable + * page parameters + * @param type + * to be filtered on + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Slice findSoftwareModulesByType(@NotNull Pageable pageable, @NotNull SoftwareModuleType type); + + /** + * + * @param id + * to search for + * @return {@link SoftwareModuleType} in the repository with given + * {@link SoftwareModuleType#getId()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeById(@NotNull Long id); + + /** + * + * @param key + * to search for + * @return {@link SoftwareModuleType} in the repository with given + * {@link SoftwareModuleType#getKey()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeByKey(@NotNull String key); + + /** + * + * @param name + * to search for + * @return all {@link SoftwareModuleType}s in the repository with given + * {@link SoftwareModuleType#getName()} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModuleType findSoftwareModuleTypeByName(@NotNull String name); + + /** + * @param pageable + * parameter + * @return all {@link SoftwareModuleType}s in the repository. + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleTypesAll(@NotNull Pageable pageable); + + /** + * Retrieves all {@link SoftwareModuleType}s with a given specification. + * + * @param spec + * the specification to filter the software modules types + * @param pageable + * pagination parameter + * @return the found {@link SoftwareModuleType}s + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + Page findSoftwareModuleTypesAll(@NotNull String rsqlParam, @NotNull Pageable pageable); + + /** + * Retrieves software module including details ( + * {@link SoftwareModule#getArtifacts()}). + * + * @param id + * parameter + * @param isDeleted + * parameter + * @return the found {@link SoftwareModule}s + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + SoftwareModule findSoftwareModuleWithDetails(@NotNull Long id); + + /** + * Updates existing {@link SoftwareModule}. Update-able values are + * {@link SoftwareModule#getDescription()} + * {@link SoftwareModule#getVendor()}. + * + * @param sm + * to update + * + * @return the saved {@link Entity}. + * + * @throws NullPointerException + * of {@link SoftwareModule#getId()} is null + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModule updateSoftwareModule(@NotNull SoftwareModule sm); + + /** + * updates a distribution set meta data value if corresponding entry exists. + * + * @param metadata + * the meta data entry to be updated + * @return the updated meta data entry + * @throws EntityNotFoundException + * in case the meta data entry does not exists and cannot be + * updated + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleMetadata updateSoftwareModuleMetadata(@NotNull SoftwareModuleMetadata metadata); + + /** + * Updates existing {@link SoftwareModuleType}. Update-able value is + * {@link SoftwareModuleType#getDescription()} and + * {@link SoftwareModuleType#getColour()}. + * + * @param sm + * to update + * @return updated {@link Entity} + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_UPDATE_REPOSITORY) + SoftwareModuleType updateSoftwareModuleType(@NotNull SoftwareModuleType sm); + + /** + * finds all meta data by the given software module id. + * + * @param softwareModuleId + * the software module id to retrieve the meta data from + + * + * @throws RSQLParameterUnsupportedFieldException + * if a field in the RSQL string is used but not provided by the + * given {@code fieldNameProvider} + * @throws RSQLParameterSyntaxException + * if the RSQL syntax is wrong + * @return result of all meta data entries for a given software + * module id + */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + List findSoftwareModuleMetadataBySoftwareModuleId(Long softwareModuleId); + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index afe1a1e02..31b222051 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -1,672 +1,672 @@ -/** - * 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.jpa; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -import javax.persistence.EntityManager; -import javax.persistence.criteria.CriteriaBuilder; -import javax.persistence.criteria.CriteriaQuery; -import javax.persistence.criteria.ListJoin; -import javax.persistence.criteria.Predicate; -import javax.persistence.criteria.Root; - -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; -import org.eclipse.hawkbit.repository.ArtifactManagement; -import org.eclipse.hawkbit.repository.SoftwareManagement; -import org.eclipse.hawkbit.repository.SoftwareModuleFields; -import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; -import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; -import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; -import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata_; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; -import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_; -import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; -import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; -import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification; -import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; -import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.LocalArtifact; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.AuditorAware; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageImpl; -import org.springframework.data.domain.Pageable; -import org.springframework.data.domain.Slice; -import org.springframework.data.domain.SliceImpl; -import org.springframework.data.jpa.domain.Specification; -import org.springframework.data.jpa.repository.Modifying; -import org.springframework.security.access.prepost.PreAuthorize; -import org.springframework.transaction.annotation.Isolation; -import org.springframework.transaction.annotation.Transactional; -import org.springframework.validation.annotation.Validated; - -import com.google.common.base.Strings; -import com.google.common.collect.Sets; - -/** - * JPA implementation of {@link SoftwareManagement}. - * - */ -@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) -@Validated -public class JpaSoftwareManagement implements SoftwareManagement { - - @Autowired - private EntityManager entityManager; - - @Autowired - private DistributionSetRepository distributionSetRepository; - - @Autowired - private DistributionSetTypeRepository distributionSetTypeRepository; - - @Autowired - private SoftwareModuleRepository softwareModuleRepository; - - @Autowired - private SoftwareModuleMetadataRepository softwareModuleMetadataRepository; - - @Autowired - private SoftwareModuleTypeRepository softwareModuleTypeRepository; - - @Autowired - private NoCountPagingRepository criteriaNoCountDao; - - @Autowired - private AuditorAware auditorProvider; - - @Autowired - private ArtifactManagement artifactManagement; - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModule updateSoftwareModule(final SoftwareModule sm) { - checkNotNull(sm.getId()); - - final JpaSoftwareModule module = softwareModuleRepository.findOne(sm.getId()); - - boolean updated = false; - if (null == sm.getDescription() || !sm.getDescription().equals(module.getDescription())) { - module.setDescription(sm.getDescription()); - updated = true; - } - if (null == sm.getVendor() || !sm.getVendor().equals(module.getVendor())) { - module.setVendor(sm.getVendor()); - updated = true; - } - - return updated ? softwareModuleRepository.save(module) : module; - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleType sm) { - checkNotNull(sm.getId()); - - final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); - - boolean updated = false; - if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) { - type.setDescription(sm.getDescription()); - updated = true; - } - if (sm.getColour() != null && !sm.getColour().equals(type.getColour())) { - type.setColour(sm.getColour()); - updated = true; - } - return updated ? softwareModuleTypeRepository.save(type) : type; - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModule createSoftwareModule(final SoftwareModule swModule) { - if (null != swModule.getId()) { - throw new EntityAlreadyExistsException(); - } - return softwareModuleRepository.save((JpaSoftwareModule) swModule); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List createSoftwareModule(final Collection swModules) { - swModules.forEach(swModule -> { - if (null != swModule.getId()) { - throw new EntityAlreadyExistsException(); - } - }); - - @SuppressWarnings({ "unchecked", "rawtypes" }) - final Collection jpaCast = (Collection) swModules; - - return new ArrayList<>(softwareModuleRepository.save(jpaCast)); - } - - @Override - public Slice findSoftwareModulesByType(final Pageable pageable, final SoftwareModuleType type) { - - final List> specList = new LinkedList<>(); - - Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - - spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - private static Slice convertSmPage(final Slice findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, 0); - } - - private static Page convertSmPage(final Page findAll, final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - private static Page convertSmMdPage(final Page findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - @Override - public Long countSoftwareModulesByType(final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - - spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public SoftwareModule findSoftwareModuleById(final Long id) { - return artifactManagement.findSoftwareModuleById(id); - } - - @Override - public SoftwareModule findSoftwareModuleByNameAndVersion(final String name, final String version, - final SoftwareModuleType type) { - - return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, (JpaSoftwareModuleType) type); - } - - private boolean isUnassigned(final JpaSoftwareModule bsmMerged) { - return distributionSetRepository.findByModules(bsmMerged).isEmpty(); - } - - private Slice findSwModuleByCriteriaAPI(final Pageable pageable, - final List> specList) { - return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, - JpaSoftwareModule.class); - } - - private Long countSwModuleByCriteriaAPI(final List> specList) { - return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList)); - } - - private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) { - for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) { - artifactManagement.deleteLocalArtifact(localArtifact); - } - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModules(final Collection ids) { - final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); - final Set assignedModuleIds = new HashSet<>(); - swModulesToDelete.forEach(swModule -> { - - // delete binary data of artifacts - deleteGridFsArtifacts(swModule); - - if (isUnassigned(swModule)) { - - softwareModuleRepository.delete(swModule); - - } else { - - assignedModuleIds.add(swModule.getId()); - } - }); - - if (!assignedModuleIds.isEmpty()) { - String currentUser = null; - if (auditorProvider != null) { - currentUser = auditorProvider.getCurrentAuditor(); - } - softwareModuleRepository.deleteSoftwareModule(System.currentTimeMillis(), currentUser, - assignedModuleIds.toArray(new Long[0])); - } - } - - @Override - public Slice findSoftwareModulesAll(final Pageable pageable) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - spec = (root, query, cb) -> { - if (!query.getResultType().isAssignableFrom(Long.class)) { - root.fetch(JpaSoftwareModule_.type); - } - return cb.conjunction(); - }; - - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - @Override - public Long countSoftwareModulesAll() { - - final List> specList = new ArrayList<>(); - - final Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public SoftwareModule findSoftwareModuleWithDetails(final Long id) { - return artifactManagement.findSoftwareModuleWithDetails(id); - } - - @Override - public Page findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) { - final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class); - - return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable); - } - - @Override - public Page findSoftwareModuleTypesAll(final String rsqlParam, final Pageable pageable) { - - final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class); - - return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable); - } - - private static Page convertSmTPage(final Page findAll, - final Pageable pageable) { - return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); - } - - @Override - @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) - public List findSoftwareModulesById(final Collection ids) { - return new ArrayList<>(softwareModuleRepository.findByIdIn(ids)); - } - - @Override - public Slice findSoftwareModuleByFilters(final Pageable pageable, final String searchText, - final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - if (!Strings.isNullOrEmpty(searchText)) { - spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); - specList.add(spec); - } - - if (null != type) { - spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - } - - spec = (root, query, cb) -> { - if (!query.getResultType().isAssignableFrom(Long.class)) { - root.fetch(JpaSoftwareModule_.type); - } - return cb.conjunction(); - }; - - specList.add(spec); - - return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); - } - - @Override - public Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( - final Pageable pageable, final Long orderByDistributionId, final String searchText, - final SoftwareModuleType ty) { - final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; - - final List resultList = new ArrayList<>(); - final int pageSize = pageable.getPageSize(); - final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); - - // get the assigned software modules - final CriteriaQuery assignedQuery = cb.createQuery(JpaSoftwareModule.class); - final Root assignedRoot = assignedQuery.from(JpaSoftwareModule.class); - assignedQuery.distinct(true); - final ListJoin assignedDsJoin = assignedRoot - .join(JpaSoftwareModule_.assignedTo); - // build the specifications and then to predicates necessary by the - // given filters - final Predicate[] specPredicate = specificationsToPredicate(buildSpecificationList(searchText, type), - assignedRoot, assignedQuery, cb, - cb.equal(assignedDsJoin.get(JpaDistributionSet_.id), orderByDistributionId)); - // if we have some predicates then add it to the where clause of the - // multi select - assignedQuery.where(specPredicate); - assignedQuery.orderBy(cb.asc(assignedRoot.get(JpaSoftwareModule_.name)), - cb.asc(assignedRoot.get(JpaSoftwareModule_.version))); - // don't page the assigned query on database, we need all assigned - // software modules to filter - // them out in the unassigned query - final List assignedSoftwareModules = entityManager.createQuery(assignedQuery) - .getResultList(); - // map result - if (pageable.getOffset() < assignedSoftwareModules.size()) { - assignedSoftwareModules - .subList(pageable.getOffset(), Math.min(assignedSoftwareModules.size(), pageable.getPageSize())) - .forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, true))); - } - - if (assignedSoftwareModules.size() >= pageSize) { - return new SliceImpl<>(resultList); - } - - // get the unassigned software modules - final CriteriaQuery unassignedQuery = cb.createQuery(JpaSoftwareModule.class); - unassignedQuery.distinct(true); - final Root unassignedRoot = unassignedQuery.from(JpaSoftwareModule.class); - - Predicate[] unassignedSpec; - if (!assignedSoftwareModules.isEmpty()) { - unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, - unassignedQuery, cb, cb.not(unassignedRoot.get(JpaSoftwareModule_.id) - .in(assignedSoftwareModules.stream().map(sw -> sw.getId()).collect(Collectors.toList())))); - } else { - unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, - unassignedQuery, cb); - } - - unassignedQuery.where(unassignedSpec); - unassignedQuery.orderBy(cb.asc(unassignedRoot.get(JpaSoftwareModule_.name)), - cb.asc(unassignedRoot.get(JpaSoftwareModule_.version))); - final List unassignedSoftwareModules = entityManager.createQuery(unassignedQuery) - .setFirstResult(Math.max(0, pageable.getOffset() - assignedSoftwareModules.size())) - .setMaxResults(pageSize).getResultList(); - // map result - unassignedSoftwareModules.forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, false))); - - return new SliceImpl<>(resultList); - } - - private static List> buildSpecificationList(final String searchText, - final JpaSoftwareModuleType type) { - final List> specList = new ArrayList<>(); - if (!Strings.isNullOrEmpty(searchText)) { - specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText)); - } - if (type != null) { - specList.add(SoftwareModuleSpecification.equalType(type)); - } - specList.add(SoftwareModuleSpecification.isDeletedFalse()); - return specList; - } - - private Predicate[] specificationsToPredicate(final List> specifications, - final Root root, final CriteriaQuery query, final CriteriaBuilder cb, - final Predicate... additionalPredicates) { - final List predicates = new ArrayList<>(); - specifications.forEach(spec -> predicates.add(spec.toPredicate(root, query, cb))); - for (final Predicate predicate : additionalPredicates) { - predicates.add(predicate); - } - return predicates.toArray(new Predicate[predicates.size()]); - } - - @Override - public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) { - - final List> specList = new ArrayList<>(); - - Specification spec = SoftwareModuleSpecification.isDeletedFalse(); - specList.add(spec); - - if (!Strings.isNullOrEmpty(searchText)) { - spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); - specList.add(spec); - } - - if (null != type) { - spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); - specList.add(spec); - } - - return countSwModuleByCriteriaAPI(specList); - } - - @Override - public Page findSoftwareModuleTypesAll(final Pageable pageable) { - return softwareModuleTypeRepository.findByDeleted(pageable, false); - } - - @Override - public Long countSoftwareModuleTypesAll() { - return softwareModuleTypeRepository.countByDeleted(false); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeByKey(final String key) { - return softwareModuleTypeRepository.findByKey(key); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeById(final Long id) { - return softwareModuleTypeRepository.findOne(id); - } - - @Override - public SoftwareModuleType findSoftwareModuleTypeByName(final String name) { - return softwareModuleTypeRepository.findByName(name); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleType type) { - if (type.getId() != null) { - throw new EntityAlreadyExistsException("Given type contains an Id!"); - } - - return softwareModuleTypeRepository.save((JpaSoftwareModuleType) type); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModuleType(final SoftwareModuleType ty) { - final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; - - if (softwareModuleRepository.countByType(type) > 0 - || distributionSetTypeRepository.countByElementsSmType(type) > 0) { - final JpaSoftwareModuleType toDelete = entityManager.merge(type); - toDelete.setDeleted(true); - softwareModuleTypeRepository.save(toDelete); - } else { - softwareModuleTypeRepository.delete(type.getId()); - } - } - - @Override - public Page findSoftwareModuleByAssignedTo(final Pageable pageable, final DistributionSet set) { - return softwareModuleRepository.findByAssignedTo(pageable, (JpaDistributionSet) set); - } - - @Override - public Page findSoftwareModuleByAssignedToAndType(final Pageable pageable, - final DistributionSet set, final SoftwareModuleType type) { - return softwareModuleRepository.findByAssignedToAndType(pageable, (JpaDistributionSet) set, - (JpaSoftwareModuleType) type); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata md) { - final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; - - if (softwareModuleMetadataRepository.exists(metadata.getId())) { - throwMetadataKeyAlreadyExists(metadata.getId().getKey()); - } - // merge base software module so optLockRevision gets updated and audit - // log written because - // modifying metadata is modifying the base software module itself for - // auditing purposes. - entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); - return softwareModuleMetadataRepository.save(metadata); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public List createSoftwareModuleMetadata(final Collection md) { - @SuppressWarnings({ "unchecked", "rawtypes" }) - final Collection metadata = (Collection) md; - - for (final JpaSoftwareModuleMetadata softwareModuleMetadata : metadata) { - checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId()); - } - metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L)); - return new ArrayList<>(softwareModuleMetadataRepository.save(metadata)); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata md) { - final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; - - // check if exists otherwise throw entity not found exception - findSoftwareModuleMetadata(metadata.getId()); - // touch it to update the lock revision because we are modifying the - // software module - // indirectly - entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); - return softwareModuleMetadataRepository.save(metadata); - } - - @Override - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - @Modifying - public void deleteSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { - softwareModuleMetadataRepository.delete(new SwMetadataCompositeKey(softwareModule, key)); - } - - @Override - public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long swId, - final Pageable pageable) { - return softwareModuleMetadataRepository.findBySoftwareModuleId(swId, pageable); - } - - @Override - public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId, - final String rsqlParam, final Pageable pageable) { - - final Specification spec = RSQLUtility.parse(rsqlParam, - SoftwareModuleMetadataFields.class); - return convertSmMdPage( - softwareModuleMetadataRepository - .findAll( - (Specification) (root, query, cb) -> cb.and( - cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) - .get(JpaSoftwareModule_.id), softwareModuleId), - spec.toPredicate(root, query, cb)), - pageable), - pageable); - } - - @Override - public List findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) { - return new ArrayList<> ( softwareModuleMetadataRepository - .findAll( - (Specification) (root, query, cb) -> cb.and( - cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) - .get(JpaSoftwareModule_.id), softwareModuleId)))); - } - - @Override - public SoftwareModuleMetadata findSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { - return findSoftwareModuleMetadata(new SwMetadataCompositeKey(softwareModule, key)); - } - - private SoftwareModuleMetadata findSoftwareModuleMetadata(final SwMetadataCompositeKey id) { - final SoftwareModuleMetadata findOne = softwareModuleMetadataRepository.findOne(id); - if (findOne == null) { - throw new EntityNotFoundException("Metadata with key '" + id.getKey() + "' does not exist"); - } - return findOne; - } - - private void checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(final SwMetadataCompositeKey metadataId) { - if (softwareModuleMetadataRepository.exists(metadataId)) { - throw new EntityAlreadyExistsException( - "Metadata entry with key '" + metadataId.getKey() + "' already exists"); - } - } - - private static void throwMetadataKeyAlreadyExists(final String metadataKey) { - throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists"); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public void deleteSoftwareModule(final SoftwareModule bsm) { - deleteSoftwareModules(Sets.newHashSet(bsm.getId())); - } - - @Override - @Modifying - @Transactional(isolation = Isolation.READ_UNCOMMITTED) - public List createSoftwareModuleType(final Collection types) { - - return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); - } - -} +/** + * 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.jpa; + +import static com.google.common.base.Preconditions.checkNotNull; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +import javax.persistence.EntityManager; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaQuery; +import javax.persistence.criteria.ListJoin; +import javax.persistence.criteria.Predicate; +import javax.persistence.criteria.Root; + +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; +import org.eclipse.hawkbit.repository.ArtifactManagement; +import org.eclipse.hawkbit.repository.SoftwareManagement; +import org.eclipse.hawkbit.repository.SoftwareModuleFields; +import org.eclipse.hawkbit.repository.SoftwareModuleMetadataFields; +import org.eclipse.hawkbit.repository.SoftwareModuleTypeFields; +import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; +import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; +import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleMetadata_; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModuleType; +import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule_; +import org.eclipse.hawkbit.repository.jpa.model.SwMetadataCompositeKey; +import org.eclipse.hawkbit.repository.jpa.rsql.RSQLUtility; +import org.eclipse.hawkbit.repository.jpa.specifications.SoftwareModuleSpecification; +import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; +import org.eclipse.hawkbit.repository.model.AssignedSoftwareModule; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.LocalArtifact; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleMetadata; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.AuditorAware; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; + +import com.google.common.base.Strings; +import com.google.common.collect.Sets; + +/** + * JPA implementation of {@link SoftwareManagement}. + * + */ +@Transactional(readOnly = true, isolation = Isolation.READ_UNCOMMITTED) +@Validated +public class JpaSoftwareManagement implements SoftwareManagement { + + @Autowired + private EntityManager entityManager; + + @Autowired + private DistributionSetRepository distributionSetRepository; + + @Autowired + private DistributionSetTypeRepository distributionSetTypeRepository; + + @Autowired + private SoftwareModuleRepository softwareModuleRepository; + + @Autowired + private SoftwareModuleMetadataRepository softwareModuleMetadataRepository; + + @Autowired + private SoftwareModuleTypeRepository softwareModuleTypeRepository; + + @Autowired + private NoCountPagingRepository criteriaNoCountDao; + + @Autowired + private AuditorAware auditorProvider; + + @Autowired + private ArtifactManagement artifactManagement; + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModule updateSoftwareModule(final SoftwareModule sm) { + checkNotNull(sm.getId()); + + final JpaSoftwareModule module = softwareModuleRepository.findOne(sm.getId()); + + boolean updated = false; + if (null == sm.getDescription() || !sm.getDescription().equals(module.getDescription())) { + module.setDescription(sm.getDescription()); + updated = true; + } + if (null == sm.getVendor() || !sm.getVendor().equals(module.getVendor())) { + module.setVendor(sm.getVendor()); + updated = true; + } + + return updated ? softwareModuleRepository.save(module) : module; + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModuleType updateSoftwareModuleType(final SoftwareModuleType sm) { + checkNotNull(sm.getId()); + + final JpaSoftwareModuleType type = softwareModuleTypeRepository.findOne(sm.getId()); + + boolean updated = false; + if (sm.getDescription() == null || !sm.getDescription().equals(type.getDescription())) { + type.setDescription(sm.getDescription()); + updated = true; + } + if (sm.getColour() != null && !sm.getColour().equals(type.getColour())) { + type.setColour(sm.getColour()); + updated = true; + } + return updated ? softwareModuleTypeRepository.save(type) : type; + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModule createSoftwareModule(final SoftwareModule swModule) { + if (null != swModule.getId()) { + throw new EntityAlreadyExistsException(); + } + return softwareModuleRepository.save((JpaSoftwareModule) swModule); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public List createSoftwareModule(final Collection swModules) { + swModules.forEach(swModule -> { + if (null != swModule.getId()) { + throw new EntityAlreadyExistsException(); + } + }); + + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection jpaCast = (Collection) swModules; + + return new ArrayList<>(softwareModuleRepository.save(jpaCast)); + } + + @Override + public Slice findSoftwareModulesByType(final Pageable pageable, final SoftwareModuleType type) { + + final List> specList = new LinkedList<>(); + + Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + + spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + private static Slice convertSmPage(final Slice findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, 0); + } + + private static Page convertSmPage(final Page findAll, final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + private static Page convertSmMdPage(final Page findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + @Override + public Long countSoftwareModulesByType(final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + + spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public SoftwareModule findSoftwareModuleById(final Long id) { + return artifactManagement.findSoftwareModuleById(id); + } + + @Override + public SoftwareModule findSoftwareModuleByNameAndVersion(final String name, final String version, + final SoftwareModuleType type) { + + return softwareModuleRepository.findOneByNameAndVersionAndType(name, version, (JpaSoftwareModuleType) type); + } + + private boolean isUnassigned(final JpaSoftwareModule bsmMerged) { + return distributionSetRepository.findByModules(bsmMerged).isEmpty(); + } + + private Slice findSwModuleByCriteriaAPI(final Pageable pageable, + final List> specList) { + return criteriaNoCountDao.findAll(SpecificationsBuilder.combineWithAnd(specList), pageable, + JpaSoftwareModule.class); + } + + private Long countSwModuleByCriteriaAPI(final List> specList) { + return softwareModuleRepository.count(SpecificationsBuilder.combineWithAnd(specList)); + } + + private void deleteGridFsArtifacts(final JpaSoftwareModule swModule) { + for (final LocalArtifact localArtifact : swModule.getLocalArtifacts()) { + artifactManagement.deleteLocalArtifact(localArtifact); + } + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModules(final Collection ids) { + final List swModulesToDelete = softwareModuleRepository.findByIdIn(ids); + final Set assignedModuleIds = new HashSet<>(); + swModulesToDelete.forEach(swModule -> { + + // delete binary data of artifacts + deleteGridFsArtifacts(swModule); + + if (isUnassigned(swModule)) { + + softwareModuleRepository.delete(swModule); + + } else { + + assignedModuleIds.add(swModule.getId()); + } + }); + + if (!assignedModuleIds.isEmpty()) { + String currentUser = null; + if (auditorProvider != null) { + currentUser = auditorProvider.getCurrentAuditor(); + } + softwareModuleRepository.deleteSoftwareModule(System.currentTimeMillis(), currentUser, + assignedModuleIds.toArray(new Long[0])); + } + } + + @Override + public Slice findSoftwareModulesAll(final Pageable pageable) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + spec = (root, query, cb) -> { + if (!query.getResultType().isAssignableFrom(Long.class)) { + root.fetch(JpaSoftwareModule_.type); + } + return cb.conjunction(); + }; + + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + @Override + public Long countSoftwareModulesAll() { + + final List> specList = new ArrayList<>(); + + final Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public SoftwareModule findSoftwareModuleWithDetails(final Long id) { + return artifactManagement.findSoftwareModuleWithDetails(id); + } + + @Override + public Page findSoftwareModulesByPredicate(final String rsqlParam, final Pageable pageable) { + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleFields.class); + + return convertSmPage(softwareModuleRepository.findAll(spec, pageable), pageable); + } + + @Override + public Page findSoftwareModuleTypesAll(final String rsqlParam, final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, SoftwareModuleTypeFields.class); + + return convertSmTPage(softwareModuleTypeRepository.findAll(spec, pageable), pageable); + } + + private static Page convertSmTPage(final Page findAll, + final Pageable pageable) { + return new PageImpl<>(new ArrayList<>(findAll.getContent()), pageable, findAll.getTotalElements()); + } + + @Override + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) + public List findSoftwareModulesById(final Collection ids) { + return new ArrayList<>(softwareModuleRepository.findByIdIn(ids)); + } + + @Override + public Slice findSoftwareModuleByFilters(final Pageable pageable, final String searchText, + final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + if (!Strings.isNullOrEmpty(searchText)) { + spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); + specList.add(spec); + } + + if (null != type) { + spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + } + + spec = (root, query, cb) -> { + if (!query.getResultType().isAssignableFrom(Long.class)) { + root.fetch(JpaSoftwareModule_.type); + } + return cb.conjunction(); + }; + + specList.add(spec); + + return convertSmPage(findSwModuleByCriteriaAPI(pageable, specList), pageable); + } + + @Override + public Slice findSoftwareModuleOrderBySetAssignmentAndModuleNameAscModuleVersionAsc( + final Pageable pageable, final Long orderByDistributionId, final String searchText, + final SoftwareModuleType ty) { + final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; + + final List resultList = new ArrayList<>(); + final int pageSize = pageable.getPageSize(); + final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); + + // get the assigned software modules + final CriteriaQuery assignedQuery = cb.createQuery(JpaSoftwareModule.class); + final Root assignedRoot = assignedQuery.from(JpaSoftwareModule.class); + assignedQuery.distinct(true); + final ListJoin assignedDsJoin = assignedRoot + .join(JpaSoftwareModule_.assignedTo); + // build the specifications and then to predicates necessary by the + // given filters + final Predicate[] specPredicate = specificationsToPredicate(buildSpecificationList(searchText, type), + assignedRoot, assignedQuery, cb, + cb.equal(assignedDsJoin.get(JpaDistributionSet_.id), orderByDistributionId)); + // if we have some predicates then add it to the where clause of the + // multi select + assignedQuery.where(specPredicate); + assignedQuery.orderBy(cb.asc(assignedRoot.get(JpaSoftwareModule_.name)), + cb.asc(assignedRoot.get(JpaSoftwareModule_.version))); + // don't page the assigned query on database, we need all assigned + // software modules to filter + // them out in the unassigned query + final List assignedSoftwareModules = entityManager.createQuery(assignedQuery) + .getResultList(); + // map result + if (pageable.getOffset() < assignedSoftwareModules.size()) { + assignedSoftwareModules + .subList(pageable.getOffset(), Math.min(assignedSoftwareModules.size(), pageable.getPageSize())) + .forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, true))); + } + + if (assignedSoftwareModules.size() >= pageSize) { + return new SliceImpl<>(resultList); + } + + // get the unassigned software modules + final CriteriaQuery unassignedQuery = cb.createQuery(JpaSoftwareModule.class); + unassignedQuery.distinct(true); + final Root unassignedRoot = unassignedQuery.from(JpaSoftwareModule.class); + + Predicate[] unassignedSpec; + if (!assignedSoftwareModules.isEmpty()) { + unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, + unassignedQuery, cb, cb.not(unassignedRoot.get(JpaSoftwareModule_.id) + .in(assignedSoftwareModules.stream().map(sw -> sw.getId()).collect(Collectors.toList())))); + } else { + unassignedSpec = specificationsToPredicate(buildSpecificationList(searchText, type), unassignedRoot, + unassignedQuery, cb); + } + + unassignedQuery.where(unassignedSpec); + unassignedQuery.orderBy(cb.asc(unassignedRoot.get(JpaSoftwareModule_.name)), + cb.asc(unassignedRoot.get(JpaSoftwareModule_.version))); + final List unassignedSoftwareModules = entityManager.createQuery(unassignedQuery) + .setFirstResult(Math.max(0, pageable.getOffset() - assignedSoftwareModules.size())) + .setMaxResults(pageSize).getResultList(); + // map result + unassignedSoftwareModules.forEach(sw -> resultList.add(new AssignedSoftwareModule(sw, false))); + + return new SliceImpl<>(resultList); + } + + private static List> buildSpecificationList(final String searchText, + final JpaSoftwareModuleType type) { + final List> specList = new ArrayList<>(); + if (!Strings.isNullOrEmpty(searchText)) { + specList.add(SoftwareModuleSpecification.likeNameOrVersion(searchText)); + } + if (type != null) { + specList.add(SoftwareModuleSpecification.equalType(type)); + } + specList.add(SoftwareModuleSpecification.isDeletedFalse()); + return specList; + } + + private Predicate[] specificationsToPredicate(final List> specifications, + final Root root, final CriteriaQuery query, final CriteriaBuilder cb, + final Predicate... additionalPredicates) { + final List predicates = new ArrayList<>(); + specifications.forEach(spec -> predicates.add(spec.toPredicate(root, query, cb))); + for (final Predicate predicate : additionalPredicates) { + predicates.add(predicate); + } + return predicates.toArray(new Predicate[predicates.size()]); + } + + @Override + public Long countSoftwareModuleByFilters(final String searchText, final SoftwareModuleType type) { + + final List> specList = new ArrayList<>(); + + Specification spec = SoftwareModuleSpecification.isDeletedFalse(); + specList.add(spec); + + if (!Strings.isNullOrEmpty(searchText)) { + spec = SoftwareModuleSpecification.likeNameOrVersion(searchText); + specList.add(spec); + } + + if (null != type) { + spec = SoftwareModuleSpecification.equalType((JpaSoftwareModuleType) type); + specList.add(spec); + } + + return countSwModuleByCriteriaAPI(specList); + } + + @Override + public Page findSoftwareModuleTypesAll(final Pageable pageable) { + return softwareModuleTypeRepository.findByDeleted(pageable, false); + } + + @Override + public Long countSoftwareModuleTypesAll() { + return softwareModuleTypeRepository.countByDeleted(false); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeByKey(final String key) { + return softwareModuleTypeRepository.findByKey(key); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeById(final Long id) { + return softwareModuleTypeRepository.findOne(id); + } + + @Override + public SoftwareModuleType findSoftwareModuleTypeByName(final String name) { + return softwareModuleTypeRepository.findByName(name); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public SoftwareModuleType createSoftwareModuleType(final SoftwareModuleType type) { + if (type.getId() != null) { + throw new EntityAlreadyExistsException("Given type contains an Id!"); + } + + return softwareModuleTypeRepository.save((JpaSoftwareModuleType) type); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModuleType(final SoftwareModuleType ty) { + final JpaSoftwareModuleType type = (JpaSoftwareModuleType) ty; + + if (softwareModuleRepository.countByType(type) > 0 + || distributionSetTypeRepository.countByElementsSmType(type) > 0) { + final JpaSoftwareModuleType toDelete = entityManager.merge(type); + toDelete.setDeleted(true); + softwareModuleTypeRepository.save(toDelete); + } else { + softwareModuleTypeRepository.delete(type.getId()); + } + } + + @Override + public Page findSoftwareModuleByAssignedTo(final Pageable pageable, final DistributionSet set) { + return softwareModuleRepository.findByAssignedTo(pageable, (JpaDistributionSet) set); + } + + @Override + public Page findSoftwareModuleByAssignedToAndType(final Pageable pageable, + final DistributionSet set, final SoftwareModuleType type) { + return softwareModuleRepository.findByAssignedToAndType(pageable, (JpaDistributionSet) set, + (JpaSoftwareModuleType) type); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public SoftwareModuleMetadata createSoftwareModuleMetadata(final SoftwareModuleMetadata md) { + final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; + + if (softwareModuleMetadataRepository.exists(metadata.getId())) { + throwMetadataKeyAlreadyExists(metadata.getId().getKey()); + } + // merge base software module so optLockRevision gets updated and audit + // log written because + // modifying metadata is modifying the base software module itself for + // auditing purposes. + entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); + return softwareModuleMetadataRepository.save(metadata); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public List createSoftwareModuleMetadata(final Collection md) { + @SuppressWarnings({ "unchecked", "rawtypes" }) + final Collection metadata = (Collection) md; + + for (final JpaSoftwareModuleMetadata softwareModuleMetadata : metadata) { + checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(softwareModuleMetadata.getId()); + } + metadata.forEach(m -> entityManager.merge((JpaSoftwareModule) m.getSoftwareModule()).setLastModifiedAt(-1L)); + return new ArrayList<>(softwareModuleMetadataRepository.save(metadata)); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public SoftwareModuleMetadata updateSoftwareModuleMetadata(final SoftwareModuleMetadata md) { + final JpaSoftwareModuleMetadata metadata = (JpaSoftwareModuleMetadata) md; + + // check if exists otherwise throw entity not found exception + findSoftwareModuleMetadata(metadata.getId()); + // touch it to update the lock revision because we are modifying the + // software module + // indirectly + entityManager.merge((JpaSoftwareModule) metadata.getSoftwareModule()).setLastModifiedAt(-1L); + return softwareModuleMetadataRepository.save(metadata); + } + + @Override + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + @Modifying + public void deleteSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { + softwareModuleMetadataRepository.delete(new SwMetadataCompositeKey(softwareModule, key)); + } + + @Override + public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long swId, + final Pageable pageable) { + return softwareModuleMetadataRepository.findBySoftwareModuleId(swId, pageable); + } + + @Override + public Page findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId, + final String rsqlParam, final Pageable pageable) { + + final Specification spec = RSQLUtility.parse(rsqlParam, + SoftwareModuleMetadataFields.class); + return convertSmMdPage( + softwareModuleMetadataRepository + .findAll( + (Specification) (root, query, cb) -> cb.and( + cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) + .get(JpaSoftwareModule_.id), softwareModuleId), + spec.toPredicate(root, query, cb)), + pageable), + pageable); + } + + @Override + public List findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) { + return new ArrayList<> ( softwareModuleMetadataRepository + .findAll( + (Specification) (root, query, cb) -> cb.and( + cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) + .get(JpaSoftwareModule_.id), softwareModuleId)))); + } + + @Override + public SoftwareModuleMetadata findSoftwareModuleMetadata(final SoftwareModule softwareModule, final String key) { + return findSoftwareModuleMetadata(new SwMetadataCompositeKey(softwareModule, key)); + } + + private SoftwareModuleMetadata findSoftwareModuleMetadata(final SwMetadataCompositeKey id) { + final SoftwareModuleMetadata findOne = softwareModuleMetadataRepository.findOne(id); + if (findOne == null) { + throw new EntityNotFoundException("Metadata with key '" + id.getKey() + "' does not exist"); + } + return findOne; + } + + private void checkAndThrowAlreadyExistsIfSoftwareModuleMetadataExists(final SwMetadataCompositeKey metadataId) { + if (softwareModuleMetadataRepository.exists(metadataId)) { + throw new EntityAlreadyExistsException( + "Metadata entry with key '" + metadataId.getKey() + "' already exists"); + } + } + + private static void throwMetadataKeyAlreadyExists(final String metadataKey) { + throw new EntityAlreadyExistsException("Metadata entry with key '" + metadataKey + "' already exists"); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public void deleteSoftwareModule(final SoftwareModule bsm) { + deleteSoftwareModules(Sets.newHashSet(bsm.getId())); + } + + @Override + @Modifying + @Transactional(isolation = Isolation.READ_UNCOMMITTED) + public List createSoftwareModuleType(final Collection types) { + + return types.stream().map(this::createSoftwareModuleType).collect(Collectors.toList()); + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java index fc879aa87..5bda8f63b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java @@ -1,199 +1,199 @@ -/** - * 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.jpa.model; - -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.NamedEntityGraphs; -import javax.persistence.NamedSubgraph; -import javax.persistence.OneToMany; -import javax.persistence.Table; - -import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.ActionStatus; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.eclipse.persistence.descriptors.DescriptorEvent; - -/** - * JPA implementation of {@link Action}. - */ -@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"), - @Index(name = "sp_idx_action_02", columnList = "tenant,target,active"), - @Index(name = "sp_idx_action_prim", columnList = "tenant,id") }) -@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }), - @NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"), - @NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) }) -@Entity -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action,EventAwareEntity { - private static final long serialVersionUID = 1L; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds")) - private JpaDistributionSet distributionSet; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target")) - private JpaTarget target; - - @Column(name = "active") - private boolean active; - - @Column(name = "action_type", nullable = false) - @Enumerated(EnumType.STRING) - private ActionType actionType; - - @Column(name = "forced_time") - private long forcedTime; - - @Column(name = "status") - private Status status; - - @CascadeOnDelete - @OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = { - CascadeType.REMOVE }) - private List actionStatus; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup")) - private JpaRolloutGroup rolloutGroup; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) - private JpaRollout rollout; - - @Override - public DistributionSet getDistributionSet() { - return distributionSet; - } - - @Override - public void setDistributionSet(final DistributionSet distributionSet) { - this.distributionSet = (JpaDistributionSet) distributionSet; - } - - public void setActive(final boolean active) { - this.active = active; - } - - @Override - public Status getStatus() { - return status; - } - - @Override - public void setStatus(final Status status) { - this.status = status; - } - - @Override - public boolean isActive() { - return active; - } - - public void setActionType(final ActionType actionType) { - this.actionType = actionType; - } - - @Override - public ActionType getActionType() { - return actionType; - } - - @Override - public List getActionStatus() { - return actionStatus; - } - - @Override - public void setTarget(final Target target) { - this.target = (JpaTarget) target; - } - - @Override - public Target getTarget() { - return target; - } - - @Override - public long getForcedTime() { - return forcedTime; - } - - public void setForcedTime(final long forcedTime) { - this.forcedTime = forcedTime; - } - - @Override - public RolloutGroup getRolloutGroup() { - return rolloutGroup; - } - - public void setRolloutGroup(final RolloutGroup rolloutGroup) { - this.rolloutGroup = (JpaRolloutGroup) rolloutGroup; - } - - @Override - public Rollout getRollout() { - return rollout; - } - - public void setRollout(final Rollout rollout) { - this.rollout = (JpaRollout) rollout; - } - - @Override - public String toString() { - return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]"; - } - - @Override - public void fireCreateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); - - } - - @Override - public void fireUpdateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus(). - post(new ActionPropertyChangeEvent(jpaAction, EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); - - } - - - @Override - public void fireDeleteEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - - } - -} +/** + * 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.jpa.model; + +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.NamedEntityGraphs; +import javax.persistence.NamedSubgraph; +import javax.persistence.OneToMany; +import javax.persistence.Table; + +import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.ActionStatus; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA implementation of {@link Action}. + */ +@Table(name = "sp_action", indexes = { @Index(name = "sp_idx_action_01", columnList = "tenant,distribution_set"), + @Index(name = "sp_idx_action_02", columnList = "tenant,target,active"), + @Index(name = "sp_idx_action_prim", columnList = "tenant,id") }) +@NamedEntityGraphs({ @NamedEntityGraph(name = "Action.ds", attributeNodes = { @NamedAttributeNode("distributionSet") }), + @NamedEntityGraph(name = "Action.all", attributeNodes = { @NamedAttributeNode("distributionSet"), + @NamedAttributeNode(value = "target", subgraph = "target.ds") }, subgraphs = @NamedSubgraph(name = "target.ds", attributeNodes = @NamedAttributeNode("assignedDistributionSet"))) }) +@Entity +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action,EventAwareEntity { + private static final long serialVersionUID = 1L; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_ds")) + private JpaDistributionSet distributionSet; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_target")) + private JpaTarget target; + + @Column(name = "active") + private boolean active; + + @Column(name = "action_type", nullable = false) + @Enumerated(EnumType.STRING) + private ActionType actionType; + + @Column(name = "forced_time") + private long forcedTime; + + @Column(name = "status") + private Status status; + + @CascadeOnDelete + @OneToMany(mappedBy = "action", targetEntity = JpaActionStatus.class, fetch = FetchType.LAZY, cascade = { + CascadeType.REMOVE }) + private List actionStatus; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rolloutgroup", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rolloutgroup")) + private JpaRolloutGroup rolloutGroup; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_action_rollout")) + private JpaRollout rollout; + + @Override + public DistributionSet getDistributionSet() { + return distributionSet; + } + + @Override + public void setDistributionSet(final DistributionSet distributionSet) { + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + public void setActive(final boolean active) { + this.active = active; + } + + @Override + public Status getStatus() { + return status; + } + + @Override + public void setStatus(final Status status) { + this.status = status; + } + + @Override + public boolean isActive() { + return active; + } + + public void setActionType(final ActionType actionType) { + this.actionType = actionType; + } + + @Override + public ActionType getActionType() { + return actionType; + } + + @Override + public List getActionStatus() { + return actionStatus; + } + + @Override + public void setTarget(final Target target) { + this.target = (JpaTarget) target; + } + + @Override + public Target getTarget() { + return target; + } + + @Override + public long getForcedTime() { + return forcedTime; + } + + public void setForcedTime(final long forcedTime) { + this.forcedTime = forcedTime; + } + + @Override + public RolloutGroup getRolloutGroup() { + return rolloutGroup; + } + + public void setRolloutGroup(final RolloutGroup rolloutGroup) { + this.rolloutGroup = (JpaRolloutGroup) rolloutGroup; + } + + @Override + public Rollout getRollout() { + return rollout; + } + + public void setRollout(final Rollout rollout) { + this.rollout = (JpaRollout) rollout; + } + + @Override + public String toString() { + return "Action [distributionSet=" + distributionSet + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); + + } + + @Override + public void fireUpdateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus(). + post(new ActionPropertyChangeEvent(jpaAction, EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); + + } + + + @Override + public void fireDeleteEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index af8984286..77a5f88fd 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -1,320 +1,320 @@ -/** - * 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.jpa.model; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; -import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; -import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; -import org.eclipse.hawkbit.repository.model.DistributionSetTag; -import org.eclipse.hawkbit.repository.model.DistributionSetType; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.SoftwareModuleType; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.eclipse.persistence.descriptors.DescriptorEvent; - -/** - * Jpa implementation of {@link DistributionSet}. - * - */ -@Entity -@Table(name = "sp_distribution_set", uniqueConstraints = { - @UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = { - @Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"), - @Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"), - @Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") }) -@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"), - @NamedAttributeNode("tags"), @NamedAttributeNode("type") }) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet,EventAwareEntity { - private static final long serialVersionUID = 1L; - - private static final String COMPLETE = "complete"; - - @Column(name = "required_migration_step") - private boolean requiredMigrationStep; - - @ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY) - @JoinTable(name = "sp_ds_module", joinColumns = { - @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = { - @JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) }) - private final Set modules = new HashSet<>(); - - @ManyToMany(targetEntity = JpaDistributionSetTag.class) - @JoinTable(name = "sp_ds_dstag", joinColumns = { - @JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = { - @JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) }) - private Set tags = new HashSet<>(); - - @Column(name = "deleted") - private boolean deleted; - - @OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY) - private List assignedToTargets; - - @OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY) - private List installedAtTargets; - - @OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY) - private List actions; - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = { - CascadeType.REMOVE }) - @JoinColumn(name = "ds_id", insertable = false, updatable = false) - private final List metadata = new ArrayList<>(); - - @ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class) - @JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) - private DistributionSetType type; - - @Column(name = "complete") - private boolean complete; - - /** - * Default constructor. - */ - public JpaDistributionSet() { - super(); - } - - /** - * Parameterized constructor. - * - * @param name - * of the {@link DistributionSet} - * @param version - * of the {@link DistributionSet} - * @param description - * of the {@link DistributionSet} - * @param type - * of the {@link DistributionSet} - * @param moduleList - * {@link SoftwareModule}s of the {@link DistributionSet} - */ - public JpaDistributionSet(final String name, final String version, final String description, - final DistributionSetType type, final Collection moduleList) { - super(name, version, description); - - this.type = type; - if (moduleList != null) { - moduleList.forEach(this::addModule); - } - if (this.type != null) { - complete = this.type.checkComplete(this); - } - } - - @Override - public Set getTags() { - return tags; - } - - @Override - public boolean isDeleted() { - return deleted; - } - - @Override - public List getMetadata() { - return Collections.unmodifiableList(metadata); - } - - public List getActions() { - return actions; - } - - @Override - public boolean isRequiredMigrationStep() { - return requiredMigrationStep; - } - - @Override - public DistributionSet setDeleted(final boolean deleted) { - this.deleted = deleted; - return this; - } - - @Override - public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) { - requiredMigrationStep = isRequiredMigrationStep; - return this; - } - - public DistributionSet setTags(final Set tags) { - this.tags = tags; - return this; - } - - @Override - public List getAssignedTargets() { - return assignedToTargets; - } - - @Override - public List getInstalledTargets() { - return installedAtTargets; - } - - @Override - public String toString() { - return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision() - + ", getId()=" + getId() + "]"; - } - - @Override - public Set getModules() { - return Collections.unmodifiableSet(modules); - } - - @Override - public boolean addModule(final SoftwareModule softwareModule) { - - // we cannot allow that modules are added without a type defined - if (type == null) { - throw new DistributionSetTypeUndefinedException(); - } - - // check if it is allowed to such a module to this DS type - if (!type.containsModuleType(softwareModule.getType())) { - throw new UnsupportedSoftwareModuleForThisDistributionSetException(); - } - - final Optional found = modules.stream() - .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); - - if (found.isPresent()) { - return false; - } - - final long allready = modules.stream() - .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count(); - - if (allready >= softwareModule.getType().getMaxAssignments()) { - final Optional sameKey = modules.stream() - .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst(); - modules.remove(sameKey.get()); - } - - if (modules.add(softwareModule)) { - complete = type.checkComplete(this); - return true; - } - - return false; - } - - @Override - public boolean removeModule(final SoftwareModule softwareModule) { - final Optional found = modules.stream() - .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); - - if (found.isPresent()) { - modules.remove(found.get()); - complete = type.checkComplete(this); - return true; - } - - return false; - - } - - @Override - public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) { - final Optional result = modules.stream().filter(module -> module.getType().equals(type)) - .findFirst(); - - if (result.isPresent()) { - return result.get(); - } - - return null; - } - - @Override - public DistributionSetType getType() { - return type; - } - - @Override - public void setType(final DistributionSetType type) { - this.type = type; - } - - @Override - public boolean isComplete() { - return complete; - } - - @Override - public void fireCreateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); - - } - - @Override - public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - final Map.Values> changeSet = EntityPropertyChangeHelper.getChangeSet( - JpaDistributionSet.class, descriptorEvent); - if (changeSet.containsKey(COMPLETE) - && changeSet.get(COMPLETE).getOldValue().equals(false) - && changeSet.get(COMPLETE).getNewValue().equals(true)) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post( - new DistributionCreatedEvent(jpaDistributionSet))); - } - - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); - - } - - @Override - public void fireDeleteEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - - } - -} +/** + * 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.jpa.model; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; +import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; +import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; +import org.eclipse.hawkbit.repository.model.DistributionSetTag; +import org.eclipse.hawkbit.repository.model.DistributionSetType; +import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.repository.model.SoftwareModuleType; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * Jpa implementation of {@link DistributionSet}. + * + */ +@Entity +@Table(name = "sp_distribution_set", uniqueConstraints = { + @UniqueConstraint(columnNames = { "name", "version", "tenant" }, name = "uk_distrib_set") }, indexes = { + @Index(name = "sp_idx_distribution_set_01", columnList = "tenant,deleted,name,complete"), + @Index(name = "sp_idx_distribution_set_02", columnList = "tenant,required_migration_step"), + @Index(name = "sp_idx_distribution_set_prim", columnList = "tenant,id") }) +@NamedEntityGraph(name = "DistributionSet.detail", attributeNodes = { @NamedAttributeNode("modules"), + @NamedAttributeNode("tags"), @NamedAttributeNode("type") }) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet,EventAwareEntity { + private static final long serialVersionUID = 1L; + + private static final String COMPLETE = "complete"; + + @Column(name = "required_migration_step") + private boolean requiredMigrationStep; + + @ManyToMany(targetEntity = JpaSoftwareModule.class, fetch = FetchType.LAZY) + @JoinTable(name = "sp_ds_module", joinColumns = { + @JoinColumn(name = "ds_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_ds")) }, inverseJoinColumns = { + @JoinColumn(name = "module_id", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_module_module")) }) + private final Set modules = new HashSet<>(); + + @ManyToMany(targetEntity = JpaDistributionSetTag.class) + @JoinTable(name = "sp_ds_dstag", joinColumns = { + @JoinColumn(name = "ds", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_ds")) }, inverseJoinColumns = { + @JoinColumn(name = "TAG", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstag_tag")) }) + private Set tags = new HashSet<>(); + + @Column(name = "deleted") + private boolean deleted; + + @OneToMany(mappedBy = "assignedDistributionSet", targetEntity = JpaTarget.class, fetch = FetchType.LAZY) + private List assignedToTargets; + + @OneToMany(mappedBy = "installedDistributionSet", targetEntity = JpaTargetInfo.class, fetch = FetchType.LAZY) + private List installedAtTargets; + + @OneToMany(mappedBy = "distributionSet", targetEntity = JpaAction.class, fetch = FetchType.LAZY) + private List actions; + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetMetadata.class, cascade = { + CascadeType.REMOVE }) + @JoinColumn(name = "ds_id", insertable = false, updatable = false) + private final List metadata = new ArrayList<>(); + + @ManyToOne(fetch = FetchType.LAZY, targetEntity = JpaDistributionSetType.class) + @JoinColumn(name = "ds_id", nullable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_ds_dstype_ds")) + private DistributionSetType type; + + @Column(name = "complete") + private boolean complete; + + /** + * Default constructor. + */ + public JpaDistributionSet() { + super(); + } + + /** + * Parameterized constructor. + * + * @param name + * of the {@link DistributionSet} + * @param version + * of the {@link DistributionSet} + * @param description + * of the {@link DistributionSet} + * @param type + * of the {@link DistributionSet} + * @param moduleList + * {@link SoftwareModule}s of the {@link DistributionSet} + */ + public JpaDistributionSet(final String name, final String version, final String description, + final DistributionSetType type, final Collection moduleList) { + super(name, version, description); + + this.type = type; + if (moduleList != null) { + moduleList.forEach(this::addModule); + } + if (this.type != null) { + complete = this.type.checkComplete(this); + } + } + + @Override + public Set getTags() { + return tags; + } + + @Override + public boolean isDeleted() { + return deleted; + } + + @Override + public List getMetadata() { + return Collections.unmodifiableList(metadata); + } + + public List getActions() { + return actions; + } + + @Override + public boolean isRequiredMigrationStep() { + return requiredMigrationStep; + } + + @Override + public DistributionSet setDeleted(final boolean deleted) { + this.deleted = deleted; + return this; + } + + @Override + public DistributionSet setRequiredMigrationStep(final boolean isRequiredMigrationStep) { + requiredMigrationStep = isRequiredMigrationStep; + return this; + } + + public DistributionSet setTags(final Set tags) { + this.tags = tags; + return this; + } + + @Override + public List getAssignedTargets() { + return assignedToTargets; + } + + @Override + public List getInstalledTargets() { + return installedAtTargets; + } + + @Override + public String toString() { + return "DistributionSet [getName()=" + getName() + ", getOptLockRevision()=" + getOptLockRevision() + + ", getId()=" + getId() + "]"; + } + + @Override + public Set getModules() { + return Collections.unmodifiableSet(modules); + } + + @Override + public boolean addModule(final SoftwareModule softwareModule) { + + // we cannot allow that modules are added without a type defined + if (type == null) { + throw new DistributionSetTypeUndefinedException(); + } + + // check if it is allowed to such a module to this DS type + if (!type.containsModuleType(softwareModule.getType())) { + throw new UnsupportedSoftwareModuleForThisDistributionSetException(); + } + + final Optional found = modules.stream() + .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); + + if (found.isPresent()) { + return false; + } + + final long allready = modules.stream() + .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).count(); + + if (allready >= softwareModule.getType().getMaxAssignments()) { + final Optional sameKey = modules.stream() + .filter(module -> module.getType().getKey().equals(softwareModule.getType().getKey())).findFirst(); + modules.remove(sameKey.get()); + } + + if (modules.add(softwareModule)) { + complete = type.checkComplete(this); + return true; + } + + return false; + } + + @Override + public boolean removeModule(final SoftwareModule softwareModule) { + final Optional found = modules.stream() + .filter(module -> module.getId().equals(softwareModule.getId())).findFirst(); + + if (found.isPresent()) { + modules.remove(found.get()); + complete = type.checkComplete(this); + return true; + } + + return false; + + } + + @Override + public SoftwareModule findFirstModuleByType(final SoftwareModuleType type) { + final Optional result = modules.stream().filter(module -> module.getType().equals(type)) + .findFirst(); + + if (result.isPresent()) { + return result.get(); + } + + return null; + } + + @Override + public DistributionSetType getType() { + return type; + } + + @Override + public void setType(final DistributionSetType type) { + this.type = type; + } + + @Override + public boolean isComplete() { + return complete; + } + + @Override + public void fireCreateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); + + } + + @Override + public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + final Map.Values> changeSet = EntityPropertyChangeHelper.getChangeSet( + JpaDistributionSet.class, descriptorEvent); + if (changeSet.containsKey(COMPLETE) + && changeSet.get(COMPLETE).getOldValue().equals(false) + && changeSet.get(COMPLETE).getNewValue().equals(true)) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post( + new DistributionCreatedEvent(jpaDistributionSet))); + } + + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); + + } + + @Override + public void fireDeleteEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java index 73d19086d..1cf1ccb77 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java @@ -1,223 +1,223 @@ -/** - * 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.jpa.model; - -import java.util.List; - -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.cache.CacheField; -import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Action.ActionType; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; -import org.eclipse.persistence.descriptors.DescriptorEvent; - -/** - * JPA implementation of a {@link Rollout}. - * - */ -@Entity -@Table(name = "sp_rollout", indexes = { - @Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "tenant" }, name = "uk_rollout")) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaRollout extends AbstractJpaNamedEntity implements Rollout,EventAwareEntity { - - private static final long serialVersionUID = 1L; - - @OneToMany(targetEntity = JpaRolloutGroup.class) - @JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup")) - private List rolloutGroups; - - @Column(name = "target_filter", length = 1024, nullable = false) - private String targetFilterQuery; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds")) - private JpaDistributionSet distributionSet; - - @Column(name = "status") - private RolloutStatus status = RolloutStatus.CREATING; - - @Column(name = "last_check") - private long lastCheck; - - @Column(name = "action_type", nullable = false) - @Enumerated(EnumType.STRING) - private ActionType actionType = ActionType.FORCED; - - @Column(name = "forced_time") - private long forcedTime; - - @Column(name = "total_targets") - private long totalTargets; - - @Transient - @CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL) - private int rolloutGroupsTotal; - - @Transient - @CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED) - private int rolloutGroupsCreated; - - @Transient - private transient TotalTargetCountStatus totalTargetCountStatus; - - @Override - public DistributionSet getDistributionSet() { - return distributionSet; - } - - @Override - public void setDistributionSet(final DistributionSet distributionSet) { - this.distributionSet = (JpaDistributionSet) distributionSet; - } - - @Override - public List getRolloutGroups() { - return rolloutGroups; - } - - public void setRolloutGroups(final List rolloutGroups) { - this.rolloutGroups = rolloutGroups; - } - - @Override - public String getTargetFilterQuery() { - return targetFilterQuery; - } - - @Override - public void setTargetFilterQuery(final String targetFilterQuery) { - this.targetFilterQuery = targetFilterQuery; - } - - @Override - public RolloutStatus getStatus() { - return status; - } - - public void setStatus(final RolloutStatus status) { - this.status = status; - } - - public long getLastCheck() { - return lastCheck; - } - - public void setLastCheck(final long lastCheck) { - this.lastCheck = lastCheck; - } - - @Override - public ActionType getActionType() { - return actionType; - } - - @Override - public void setActionType(final ActionType actionType) { - this.actionType = actionType; - } - - @Override - public long getForcedTime() { - return forcedTime; - } - - @Override - public void setForcedTime(final long forcedTime) { - this.forcedTime = forcedTime; - } - - @Override - public long getTotalTargets() { - return totalTargets; - } - - public void setTotalTargets(final long totalTargets) { - this.totalTargets = totalTargets; - } - - public int getRolloutGroupsTotal() { - return rolloutGroupsTotal; - } - - public void setRolloutGroupsTotal(final int rolloutGroupsTotal) { - this.rolloutGroupsTotal = rolloutGroupsTotal; - } - - @Override - public int getRolloutGroupsCreated() { - return rolloutGroupsCreated; - } - - public void setRolloutGroupsCreated(final int rolloutGroupsCreated) { - this.rolloutGroupsCreated = rolloutGroupsCreated; - } - - @Override - public TotalTargetCountStatus getTotalTargetCountStatus() { - if (totalTargetCountStatus == null) { - totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); - } - return totalTargetCountStatus; - } - - public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { - this.totalTargetCountStatus = totalTargetCountStatus; - } - - @Override - public String toString() { - return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery - + ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck - + ", getName()=" + getName() + ", getId()=" + getId() + "]"; - } - - @Override - public void fireCreateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - - } - - @Override - public void fireUpdateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). - post(new RolloutPropertyChangeEvent(jpaRollout, EntityPropertyChangeHelper.getChangeSet( - Rollout.class, descriptorEvent)))); - - } - - @Override - public void fireDeleteEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - - } - -} +/** + * 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.jpa.model; + +import java.util.List; + +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.cache.CacheField; +import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Action.ActionType; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA implementation of a {@link Rollout}. + * + */ +@Entity +@Table(name = "sp_rollout", indexes = { + @Index(name = "sp_idx_rollout_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "tenant" }, name = "uk_rollout")) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaRollout extends AbstractJpaNamedEntity implements Rollout,EventAwareEntity { + + private static final long serialVersionUID = 1L; + + @OneToMany(targetEntity = JpaRolloutGroup.class) + @JoinColumn(name = "rollout", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rollout_rolloutgroup")) + private List rolloutGroups; + + @Column(name = "target_filter", length = 1024, nullable = false) + private String targetFilterQuery; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "distribution_set", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolltout_ds")) + private JpaDistributionSet distributionSet; + + @Column(name = "status") + private RolloutStatus status = RolloutStatus.CREATING; + + @Column(name = "last_check") + private long lastCheck; + + @Column(name = "action_type", nullable = false) + @Enumerated(EnumType.STRING) + private ActionType actionType = ActionType.FORCED; + + @Column(name = "forced_time") + private long forcedTime; + + @Column(name = "total_targets") + private long totalTargets; + + @Transient + @CacheField(key = CacheKeys.ROLLOUT_GROUP_TOTAL) + private int rolloutGroupsTotal; + + @Transient + @CacheField(key = CacheKeys.ROLLOUT_GROUP_CREATED) + private int rolloutGroupsCreated; + + @Transient + private transient TotalTargetCountStatus totalTargetCountStatus; + + @Override + public DistributionSet getDistributionSet() { + return distributionSet; + } + + @Override + public void setDistributionSet(final DistributionSet distributionSet) { + this.distributionSet = (JpaDistributionSet) distributionSet; + } + + @Override + public List getRolloutGroups() { + return rolloutGroups; + } + + public void setRolloutGroups(final List rolloutGroups) { + this.rolloutGroups = rolloutGroups; + } + + @Override + public String getTargetFilterQuery() { + return targetFilterQuery; + } + + @Override + public void setTargetFilterQuery(final String targetFilterQuery) { + this.targetFilterQuery = targetFilterQuery; + } + + @Override + public RolloutStatus getStatus() { + return status; + } + + public void setStatus(final RolloutStatus status) { + this.status = status; + } + + public long getLastCheck() { + return lastCheck; + } + + public void setLastCheck(final long lastCheck) { + this.lastCheck = lastCheck; + } + + @Override + public ActionType getActionType() { + return actionType; + } + + @Override + public void setActionType(final ActionType actionType) { + this.actionType = actionType; + } + + @Override + public long getForcedTime() { + return forcedTime; + } + + @Override + public void setForcedTime(final long forcedTime) { + this.forcedTime = forcedTime; + } + + @Override + public long getTotalTargets() { + return totalTargets; + } + + public void setTotalTargets(final long totalTargets) { + this.totalTargets = totalTargets; + } + + public int getRolloutGroupsTotal() { + return rolloutGroupsTotal; + } + + public void setRolloutGroupsTotal(final int rolloutGroupsTotal) { + this.rolloutGroupsTotal = rolloutGroupsTotal; + } + + @Override + public int getRolloutGroupsCreated() { + return rolloutGroupsCreated; + } + + public void setRolloutGroupsCreated(final int rolloutGroupsCreated) { + this.rolloutGroupsCreated = rolloutGroupsCreated; + } + + @Override + public TotalTargetCountStatus getTotalTargetCountStatus() { + if (totalTargetCountStatus == null) { + totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); + } + return totalTargetCountStatus; + } + + public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { + this.totalTargetCountStatus = totalTargetCountStatus; + } + + @Override + public String toString() { + return "Rollout [rolloutGroups=" + rolloutGroups + ", targetFilterQuery=" + targetFilterQuery + + ", distributionSet=" + distributionSet + ", status=" + status + ", lastCheck=" + lastCheck + + ", getName()=" + getName() + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + + } + + @Override + public void fireUpdateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). + post(new RolloutPropertyChangeEvent(jpaRollout, EntityPropertyChangeHelper.getChangeSet( + Rollout.class, descriptorEvent)))); + + } + + @Override + public void fireDeleteEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java index 6456a3e93..225fd458e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java @@ -1,261 +1,261 @@ -/** - * 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.jpa.model; - -import java.util.ArrayList; -import java.util.List; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.OneToMany; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; - -import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.model.Rollout; -import org.eclipse.hawkbit.repository.model.RolloutGroup; -import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; -import org.eclipse.persistence.descriptors.DescriptorEvent; - -/** - * JPA entity definition of persisting a group of an rollout. - * - */ -@Entity -@Table(name = "sp_rolloutgroup", indexes = { - @Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "name", "rollout", "tenant" }, name = "uk_rolloutgroup")) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup,EventAwareEntity { - - private static final long serialVersionUID = 1L; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout")) - private JpaRollout rollout; - - @Column(name = "status") - private RolloutGroupStatus status = RolloutGroupStatus.READY; - - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class) - @JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false) - private final List rolloutTargetGroup = new ArrayList<>(); - - @ManyToOne(fetch = FetchType.LAZY) - private JpaRolloutGroup parent; - - @Column(name = "success_condition", nullable = false) - private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD; - - @Column(name = "success_condition_exp", length = 512, nullable = false) - private String successConditionExp; - - @Column(name = "success_action", nullable = false) - private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP; - - @Column(name = "success_action_exp", length = 512, nullable = false) - private String successActionExp; - - @Column(name = "error_condition") - private RolloutGroupErrorCondition errorCondition; - - @Column(name = "error_condition_exp", length = 512) - private String errorConditionExp; - - @Column(name = "error_action") - private RolloutGroupErrorAction errorAction; - - @Column(name = "error_action_exp", length = 512) - private String errorActionExp; - - @Column(name = "total_targets") - private long totalTargets; - - @Transient - private transient TotalTargetCountStatus totalTargetCountStatus; - - @Override - public Rollout getRollout() { - return rollout; - } - - @Override - public void setRollout(final Rollout rollout) { - this.rollout = (JpaRollout) rollout; - } - - @Override - public RolloutGroupStatus getStatus() { - return status; - } - - @Override - public void setStatus(final RolloutGroupStatus status) { - this.status = status; - } - - public List getRolloutTargetGroup() { - return rolloutTargetGroup; - } - - @Override - public RolloutGroup getParent() { - return parent; - } - - public void setParent(final RolloutGroup parent) { - this.parent = (JpaRolloutGroup) parent; - } - - @Override - public RolloutGroupSuccessCondition getSuccessCondition() { - return successCondition; - } - - @Override - public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { - successCondition = finishCondition; - } - - @Override - public String getSuccessConditionExp() { - return successConditionExp; - } - - @Override - public void setSuccessConditionExp(final String finishExp) { - successConditionExp = finishExp; - } - - @Override - public RolloutGroupErrorCondition getErrorCondition() { - return errorCondition; - } - - @Override - public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { - this.errorCondition = errorCondition; - } - - @Override - public String getErrorConditionExp() { - return errorConditionExp; - } - - @Override - public void setErrorConditionExp(final String errorExp) { - errorConditionExp = errorExp; - } - - @Override - public RolloutGroupErrorAction getErrorAction() { - return errorAction; - } - - @Override - public void setErrorAction(final RolloutGroupErrorAction errorAction) { - this.errorAction = errorAction; - } - - @Override - public String getErrorActionExp() { - return errorActionExp; - } - - @Override - public void setErrorActionExp(final String errorActionExp) { - this.errorActionExp = errorActionExp; - } - - @Override - public RolloutGroupSuccessAction getSuccessAction() { - return successAction; - } - - @Override - public String getSuccessActionExp() { - return successActionExp; - } - - @Override - public long getTotalTargets() { - return totalTargets; - } - - public void setTotalTargets(final long totalTargets) { - this.totalTargets = totalTargets; - } - - public void setSuccessAction(final RolloutGroupSuccessAction successAction) { - this.successAction = successAction; - } - - public void setSuccessActionExp(final String successActionExp) { - this.successActionExp = successActionExp; - } - - /** - * @return the totalTargetCountStatus - */ - @Override - public TotalTargetCountStatus getTotalTargetCountStatus() { - if (totalTargetCountStatus == null) { - totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); - } - return totalTargetCountStatus; - } - - /** - * @param totalTargetCountStatus - * the totalTargetCountStatus to set - */ - @Override - public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { - this.totalTargetCountStatus = totalTargetCountStatus; - } - - @Override - public String toString() { - return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup - + ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp - + ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName() - + ", getId()=" + getId() + "]"; - } - - @Override - public void fireCreateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - - } - - @Override - public void fireUpdateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). - post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, - EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); - } - - @Override - public void fireDeleteEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - - } - -} +/** + * 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.jpa.model; + +import java.util.ArrayList; +import java.util.List; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.OneToMany; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; + +import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.model.Rollout; +import org.eclipse.hawkbit.repository.model.RolloutGroup; +import org.eclipse.hawkbit.repository.model.TotalTargetCountStatus; +import org.eclipse.persistence.descriptors.DescriptorEvent; + +/** + * JPA entity definition of persisting a group of an rollout. + * + */ +@Entity +@Table(name = "sp_rolloutgroup", indexes = { + @Index(name = "sp_idx_rolloutgroup_01", columnList = "tenant,name") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "name", "rollout", "tenant" }, name = "uk_rolloutgroup")) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup,EventAwareEntity { + + private static final long serialVersionUID = 1L; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "rollout", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_rolloutgroup_rollout")) + private JpaRollout rollout; + + @Column(name = "status") + private RolloutGroupStatus status = RolloutGroupStatus.READY; + + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST }, targetEntity = RolloutTargetGroup.class) + @JoinColumn(name = "rolloutGroup_Id", insertable = false, updatable = false) + private final List rolloutTargetGroup = new ArrayList<>(); + + @ManyToOne(fetch = FetchType.LAZY) + private JpaRolloutGroup parent; + + @Column(name = "success_condition", nullable = false) + private RolloutGroupSuccessCondition successCondition = RolloutGroupSuccessCondition.THRESHOLD; + + @Column(name = "success_condition_exp", length = 512, nullable = false) + private String successConditionExp; + + @Column(name = "success_action", nullable = false) + private RolloutGroupSuccessAction successAction = RolloutGroupSuccessAction.NEXTGROUP; + + @Column(name = "success_action_exp", length = 512, nullable = false) + private String successActionExp; + + @Column(name = "error_condition") + private RolloutGroupErrorCondition errorCondition; + + @Column(name = "error_condition_exp", length = 512) + private String errorConditionExp; + + @Column(name = "error_action") + private RolloutGroupErrorAction errorAction; + + @Column(name = "error_action_exp", length = 512) + private String errorActionExp; + + @Column(name = "total_targets") + private long totalTargets; + + @Transient + private transient TotalTargetCountStatus totalTargetCountStatus; + + @Override + public Rollout getRollout() { + return rollout; + } + + @Override + public void setRollout(final Rollout rollout) { + this.rollout = (JpaRollout) rollout; + } + + @Override + public RolloutGroupStatus getStatus() { + return status; + } + + @Override + public void setStatus(final RolloutGroupStatus status) { + this.status = status; + } + + public List getRolloutTargetGroup() { + return rolloutTargetGroup; + } + + @Override + public RolloutGroup getParent() { + return parent; + } + + public void setParent(final RolloutGroup parent) { + this.parent = (JpaRolloutGroup) parent; + } + + @Override + public RolloutGroupSuccessCondition getSuccessCondition() { + return successCondition; + } + + @Override + public void setSuccessCondition(final RolloutGroupSuccessCondition finishCondition) { + successCondition = finishCondition; + } + + @Override + public String getSuccessConditionExp() { + return successConditionExp; + } + + @Override + public void setSuccessConditionExp(final String finishExp) { + successConditionExp = finishExp; + } + + @Override + public RolloutGroupErrorCondition getErrorCondition() { + return errorCondition; + } + + @Override + public void setErrorCondition(final RolloutGroupErrorCondition errorCondition) { + this.errorCondition = errorCondition; + } + + @Override + public String getErrorConditionExp() { + return errorConditionExp; + } + + @Override + public void setErrorConditionExp(final String errorExp) { + errorConditionExp = errorExp; + } + + @Override + public RolloutGroupErrorAction getErrorAction() { + return errorAction; + } + + @Override + public void setErrorAction(final RolloutGroupErrorAction errorAction) { + this.errorAction = errorAction; + } + + @Override + public String getErrorActionExp() { + return errorActionExp; + } + + @Override + public void setErrorActionExp(final String errorActionExp) { + this.errorActionExp = errorActionExp; + } + + @Override + public RolloutGroupSuccessAction getSuccessAction() { + return successAction; + } + + @Override + public String getSuccessActionExp() { + return successActionExp; + } + + @Override + public long getTotalTargets() { + return totalTargets; + } + + public void setTotalTargets(final long totalTargets) { + this.totalTargets = totalTargets; + } + + public void setSuccessAction(final RolloutGroupSuccessAction successAction) { + this.successAction = successAction; + } + + public void setSuccessActionExp(final String successActionExp) { + this.successActionExp = successActionExp; + } + + /** + * @return the totalTargetCountStatus + */ + @Override + public TotalTargetCountStatus getTotalTargetCountStatus() { + if (totalTargetCountStatus == null) { + totalTargetCountStatus = new TotalTargetCountStatus(totalTargets); + } + return totalTargetCountStatus; + } + + /** + * @param totalTargetCountStatus + * the totalTargetCountStatus to set + */ + @Override + public void setTotalTargetCountStatus(final TotalTargetCountStatus totalTargetCountStatus) { + this.totalTargetCountStatus = totalTargetCountStatus; + } + + @Override + public String toString() { + return "RolloutGroup [rollout=" + rollout + ", status=" + status + ", rolloutTargetGroup=" + rolloutTargetGroup + + ", parent=" + parent + ", finishCondition=" + successCondition + ", finishExp=" + successConditionExp + + ", errorCondition=" + errorCondition + ", errorExp=" + errorConditionExp + ", getName()=" + getName() + + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + + } + + @Override + public void fireUpdateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). + post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, + EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); + } + + @Override + public void fireDeleteEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index f6a2b8346..431ebb102 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -1,257 +1,257 @@ -/** - * 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.jpa.model; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.persistence.CascadeType; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.Entity; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.JoinTable; -import javax.persistence.ManyToMany; -import javax.persistence.ManyToOne; -import javax.persistence.NamedAttributeNode; -import javax.persistence.NamedEntityGraph; -import javax.persistence.OneToMany; -import javax.persistence.OneToOne; -import javax.persistence.PrimaryKeyJoinColumn; -import javax.persistence.Table; -import javax.persistence.Transient; -import javax.persistence.UniqueConstraint; -import javax.validation.constraints.NotNull; -import javax.validation.constraints.Size; - -import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; -import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker; -import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetTag; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.eclipse.persistence.descriptors.DescriptorEvent; -import org.springframework.data.domain.Persistable; - -/** - * JPA implementation of {@link Target}. - * - */ -@Entity -@Table(name = "sp_target", indexes = { - @Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"), - @Index(name = "sp_idx_target_02", columnList = "tenant,name"), - @Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"), - @Index(name = "sp_idx_target_04", columnList = "tenant,created_at"), - @Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { - "controller_id", "tenant" }, name = "uk_tenant_controller_id")) -@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"), - @NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") }) -// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for -// sub entities -@SuppressWarnings("squid:S2160") -public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target, EventAwareEntity { - private static final long serialVersionUID = 1L; - - @Column(name = "controller_id", length = 64) - @Size(min = 1) - @NotNull - private String controllerId; - - @Transient - private boolean entityNew; - - @ManyToMany(targetEntity = JpaTargetTag.class) - @JoinTable(name = "sp_target_target_tag", joinColumns = { - @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { - @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) - private Set tags = new HashSet<>(); - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { - CascadeType.REMOVE }, targetEntity = JpaAction.class) - @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) - private final List actions = new ArrayList<>(); - - @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class) - @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) - private JpaDistributionSet assignedDistributionSet; - - @CascadeOnDelete - @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class) - @PrimaryKeyJoinColumn - private JpaTargetInfo targetInfo; - - /** - * the security token of the target which allows if enabled to authenticate - * with this security token. - */ - @Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128) - private String securityToken; - - @CascadeOnDelete - @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) - @JoinColumn(name = "target_Id", insertable = false, updatable = false) - private final List rolloutTargetGroup = new ArrayList<>(); - - /** - * Constructor. - * - * @param controllerId - * controller ID of the {@link Target} - */ - public JpaTarget(final String controllerId) { - this(controllerId, SecurityTokenGeneratorHolder.getInstance().generateToken()); - } - - /** - * Constructor. - * - * @param controllerId - * controller ID of the {@link Target} - * @param securityToken - * for target authentication if enabled - */ - public JpaTarget(final String controllerId, final String securityToken) { - this.controllerId = controllerId; - setName(controllerId); - this.securityToken = securityToken; - targetInfo = new JpaTargetInfo(this); - } - - /** - * empty constructor for JPA. - */ - JpaTarget() { - controllerId = null; - securityToken = null; - } - - @Override - public DistributionSet getAssignedDistributionSet() { - return assignedDistributionSet; - } - - @Override - public String getControllerId() { - return controllerId; - } - - @Override - public Set getTags() { - return tags; - } - - public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) { - this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet; - } - - public void setControllerId(final String controllerId) { - this.controllerId = controllerId; - } - - public void setTags(final Set tags) { - this.tags = tags; - } - - @Override - public List getActions() { - return actions; - } - - @Override - @Transient - public boolean isNew() { - return entityNew; - } - - /** - * @param isNew - * the isNew to set - */ - public void setNew(final boolean entityNew) { - this.entityNew = entityNew; - } - - /** - * @return the targetInfo - */ - @Override - public TargetInfo getTargetInfo() { - return targetInfo; - } - - /** - * @param targetInfo - * the targetInfo to set - */ - public void setTargetInfo(final TargetInfo targetInfo) { - this.targetInfo = (JpaTargetInfo) targetInfo; - } - - /** - * @return the securityToken if the current security context contains the - * necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN} - * or the current context is executed as system code, otherwise - * {@code null}. - */ - @Override - public String getSecurityToken() { - if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode() - || SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { - return securityToken; - } - return null; - } - - /** - * @param securityToken - * the securityToken to set - */ - @Override - public void setSecurityToken(final String securityToken) { - this.securityToken = securityToken; - } - - @Override - public String toString() { - return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]"; - } - - @Override - public void fireCreateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); - } - - @Override - public void fireUpdateEvent(final JpaTarget jpaTarget,final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); - - } - - @Override - public void fireDeleteEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - - - } - -} +/** + * 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.jpa.model; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import javax.persistence.CascadeType; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.ManyToMany; +import javax.persistence.ManyToOne; +import javax.persistence.NamedAttributeNode; +import javax.persistence.NamedEntityGraph; +import javax.persistence.OneToMany; +import javax.persistence.OneToOne; +import javax.persistence.PrimaryKeyJoinColumn; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.UniqueConstraint; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; + +import org.eclipse.hawkbit.im.authentication.SpPermission; +import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker; +import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.repository.model.Action; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.hawkbit.repository.model.TargetTag; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.springframework.data.domain.Persistable; + +/** + * JPA implementation of {@link Target}. + * + */ +@Entity +@Table(name = "sp_target", indexes = { + @Index(name = "sp_idx_target_01", columnList = "tenant,name,assigned_distribution_set"), + @Index(name = "sp_idx_target_02", columnList = "tenant,name"), + @Index(name = "sp_idx_target_03", columnList = "tenant,controller_id,assigned_distribution_set"), + @Index(name = "sp_idx_target_04", columnList = "tenant,created_at"), + @Index(name = "sp_idx_target_prim", columnList = "tenant,id") }, uniqueConstraints = @UniqueConstraint(columnNames = { + "controller_id", "tenant" }, name = "uk_tenant_controller_id")) +@NamedEntityGraph(name = "Target.detail", attributeNodes = { @NamedAttributeNode("tags"), + @NamedAttributeNode(value = "assignedDistributionSet"), @NamedAttributeNode(value = "targetInfo") }) +// exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for +// sub entities +@SuppressWarnings("squid:S2160") +public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target, EventAwareEntity { + private static final long serialVersionUID = 1L; + + @Column(name = "controller_id", length = 64) + @Size(min = 1) + @NotNull + private String controllerId; + + @Transient + private boolean entityNew; + + @ManyToMany(targetEntity = JpaTargetTag.class) + @JoinTable(name = "sp_target_target_tag", joinColumns = { + @JoinColumn(name = "target", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_target")) }, inverseJoinColumns = { + @JoinColumn(name = "tag", foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_targtag_tag")) }) + private Set tags = new HashSet<>(); + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, orphanRemoval = true, cascade = { + CascadeType.REMOVE }, targetEntity = JpaAction.class) + @JoinColumn(name = "target", insertable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_act_hist_targ")) + private final List actions = new ArrayList<>(); + + @ManyToOne(optional = true, fetch = FetchType.LAZY, targetEntity = JpaDistributionSet.class) + @JoinColumn(name = "assigned_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_assign_ds")) + private JpaDistributionSet assignedDistributionSet; + + @CascadeOnDelete + @OneToOne(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY, targetEntity = JpaTargetInfo.class) + @PrimaryKeyJoinColumn + private JpaTargetInfo targetInfo; + + /** + * the security token of the target which allows if enabled to authenticate + * with this security token. + */ + @Column(name = "sec_token", insertable = true, updatable = true, nullable = false, length = 128) + private String securityToken; + + @CascadeOnDelete + @OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE, CascadeType.PERSIST }) + @JoinColumn(name = "target_Id", insertable = false, updatable = false) + private final List rolloutTargetGroup = new ArrayList<>(); + + /** + * Constructor. + * + * @param controllerId + * controller ID of the {@link Target} + */ + public JpaTarget(final String controllerId) { + this(controllerId, SecurityTokenGeneratorHolder.getInstance().generateToken()); + } + + /** + * Constructor. + * + * @param controllerId + * controller ID of the {@link Target} + * @param securityToken + * for target authentication if enabled + */ + public JpaTarget(final String controllerId, final String securityToken) { + this.controllerId = controllerId; + setName(controllerId); + this.securityToken = securityToken; + targetInfo = new JpaTargetInfo(this); + } + + /** + * empty constructor for JPA. + */ + JpaTarget() { + controllerId = null; + securityToken = null; + } + + @Override + public DistributionSet getAssignedDistributionSet() { + return assignedDistributionSet; + } + + @Override + public String getControllerId() { + return controllerId; + } + + @Override + public Set getTags() { + return tags; + } + + public void setAssignedDistributionSet(final DistributionSet assignedDistributionSet) { + this.assignedDistributionSet = (JpaDistributionSet) assignedDistributionSet; + } + + public void setControllerId(final String controllerId) { + this.controllerId = controllerId; + } + + public void setTags(final Set tags) { + this.tags = tags; + } + + @Override + public List getActions() { + return actions; + } + + @Override + @Transient + public boolean isNew() { + return entityNew; + } + + /** + * @param isNew + * the isNew to set + */ + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; + } + + /** + * @return the targetInfo + */ + @Override + public TargetInfo getTargetInfo() { + return targetInfo; + } + + /** + * @param targetInfo + * the targetInfo to set + */ + public void setTargetInfo(final TargetInfo targetInfo) { + this.targetInfo = (JpaTargetInfo) targetInfo; + } + + /** + * @return the securityToken if the current security context contains the + * necessary permission {@link SpPermission#READ_TARGET_SEC_TOKEN} + * or the current context is executed as system code, otherwise + * {@code null}. + */ + @Override + public String getSecurityToken() { + if (SystemSecurityContextHolder.getInstance().getSystemSecurityContext().isCurrentThreadSystemCode() + || SecurityChecker.hasPermission(SpPermission.READ_TARGET_SEC_TOKEN)) { + return securityToken; + } + return null; + } + + /** + * @param securityToken + * the securityToken to set + */ + @Override + public void setSecurityToken(final String securityToken) { + this.securityToken = securityToken; + } + + @Override + public String toString() { + return "Target [controllerId=" + controllerId + ", getId()=" + getId() + "]"; + } + + @Override + public void fireCreateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); + } + + @Override + public void fireUpdateEvent(final JpaTarget jpaTarget,final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); + + } + + @Override + public void fireDeleteEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { + + + } + +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java index a21c7547f..bfae18248 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java @@ -1,344 +1,344 @@ -/** - * 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.jpa.model; - -import java.net.URI; -import java.time.Duration; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import javax.persistence.CascadeType; -import javax.persistence.CollectionTable; -import javax.persistence.Column; -import javax.persistence.ConstraintMode; -import javax.persistence.ElementCollection; -import javax.persistence.Entity; -import javax.persistence.EntityListeners; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.FetchType; -import javax.persistence.ForeignKey; -import javax.persistence.Id; -import javax.persistence.Index; -import javax.persistence.JoinColumn; -import javax.persistence.ManyToOne; -import javax.persistence.MapKeyColumn; -import javax.persistence.MapsId; -import javax.persistence.OneToOne; -import javax.persistence.Table; -import javax.persistence.Transient; - -import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; -import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.PollStatus; -import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TargetInfo; -import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; -import org.eclipse.persistence.annotations.CascadeOnDelete; -import org.eclipse.persistence.descriptors.DescriptorEvent; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.data.domain.Persistable; - -/** - * A table which contains all the information inserted, updated by the - * controller itself. So this entity does not provide audit information because - * changes on this entity are mostly only done by controller requests. That's - * the reason that we store these information in a separated table so we don't - * modifying the {@link Target} itself when a controller reports it's - * {@link #lastTargetQuery} for example. - * - */ -@Table(name = "sp_target_info", indexes = { - @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) -@Entity -@EntityListeners(EntityPropertyChangeListener.class) -public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareEntity { - private static final long serialVersionUID = 1L; - - private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); - - @Id - private Long targetId; - - @Transient - private boolean entityNew; - - @CascadeOnDelete - @OneToOne(cascade = { CascadeType.MERGE, - CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class) - @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ")) - @MapsId - private JpaTarget target; - - @Column(name = "address", length = 512) - private String address; - - @Column(name = "last_target_query") - private Long lastTargetQuery; - - @Column(name = "install_date") - private Long installationDate; - - @Column(name = "update_status", nullable = false, length = 255) - @Enumerated(EnumType.STRING) - private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN; - - @ManyToOne(optional = true, fetch = FetchType.LAZY) - @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) - private JpaDistributionSet installedDistributionSet; - - /** - * Read only on management API. Are commited by controller. - */ - @ElementCollection - @Column(name = "attribute_value", length = 128) - @MapKeyColumn(name = "attribute_key", nullable = false, length = 32) - @CollectionTable(name = "sp_target_attributes", joinColumns = { - @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) - - private final Map controllerAttributes = Collections.synchronizedMap(new HashMap()); - - // set default request controller attributes to true, because we want to - // request them the first - // time - @Column(name = "request_controller_attributes", nullable = false) - private boolean requestControllerAttributes = true; - - /** - * Constructor for {@link TargetStatus}. - * - * @param target - * related to this status. - */ - public JpaTargetInfo(final JpaTarget target) { - this.target = target; - targetId = target.getId(); - } - - JpaTargetInfo() { - target = null; - targetId = null; - } - - @Override - public Long getId() { - return targetId; - } - - @Override - @Transient - public boolean isNew() { - return entityNew; - } - - /** - * @param isNew - * the isNew to set - */ - public void setNew(final boolean entityNew) { - this.entityNew = entityNew; - } - - /** - * @return the ipAddress - */ - @Override - public URI getAddress() { - if (address == null) { - return null; - } - try { - return URI.create(address); - } catch (final IllegalArgumentException e) { - LOG.warn("Invalid address provided. Cloud not be configured to URI", e); - return null; - } - } - - /** - * @param address - * the target address to set - * - * @throws IllegalArgumentException - * If the given string violates RFC 2396 - */ - @Override - public void setAddress(final String address) { - // check if this is a real URI - if (address != null) { - try { - URI.create(address); - } catch (final IllegalArgumentException e) { - throw new InvalidTargetAddressException( - "The given address " + address + " violates the RFC-2396 specification", e); - } - } - - this.address = address; - } - - public Long getTargetId() { - return targetId; - } - - public void setTargetId(final Long targetId) { - this.targetId = targetId; - } - - @Override - public Target getTarget() { - return target; - } - - public void setTarget(final JpaTarget target) { - this.target = target; - } - - @Override - public Long getLastTargetQuery() { - return lastTargetQuery; - } - - public void setLastTargetQuery(final Long lastTargetQuery) { - this.lastTargetQuery = lastTargetQuery; - } - - public void setRequestControllerAttributes(final boolean requestControllerAttributes) { - this.requestControllerAttributes = requestControllerAttributes; - } - - @Override - public Map getControllerAttributes() { - return controllerAttributes; - } - - @Override - public boolean isRequestControllerAttributes() { - return requestControllerAttributes; - } - - @Override - public Long getInstallationDate() { - return installationDate; - } - - public void setInstallationDate(final Long installationDate) { - this.installationDate = installationDate; - } - - @Override - public TargetUpdateStatus getUpdateStatus() { - return updateStatus; - } - - public void setUpdateStatus(final TargetUpdateStatus updateStatus) { - this.updateStatus = updateStatus; - } - - @Override - public DistributionSet getInstalledDistributionSet() { - return installedDistributionSet; - } - - public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) { - this.installedDistributionSet = installedDistributionSet; - } - - /** - * @return the poll time which holds the last poll time of the target, the - * next poll time and the overdue time. In case the - * {@link #lastTargetQuery} is not set e.g. the target never polled - * before this method returns {@code null} - */ - @Override - public PollStatus getPollStatus() { - if (lastTargetQuery == null) { - return null; - } - return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> { - final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder - .getInstance().getTenantConfigurationManagement() - .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); - final Duration overdueTime = DurationHelper.formattedStringToDuration( - TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement() - .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) - .getValue()); - final LocalDateTime currentDate = LocalDateTime.now(); - final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), - ZoneId.systemDefault()); - final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); - final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); - return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); - }); - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((target == null) ? 0 : target.hashCode()); - result = prime * result + ((targetId == null) ? 0 : targetId.hashCode()); - return result; - } - - @Override - public boolean equals(final Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof TargetInfo)) { - return false; - } - final JpaTargetInfo other = (JpaTargetInfo) obj; - if (target == null) { - if (other.target != null) { - return false; - } - } else if (!target.equals(other.target)) { - return false; - } - if (targetId == null) { - if (other.targetId != null) { - return false; - } - } else if (!targetId.equals(other.targetId)) { - return false; - } - return true; - } - - @Override - public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo,final DescriptorEvent descriptorEvent) { - // there is no target info created event - } - - @Override - public void fireUpdateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); - } - - @Override - public void fireDeleteEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { - } -} +/** + * 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.jpa.model; + +import java.net.URI; +import java.time.Duration; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.persistence.CascadeType; +import javax.persistence.CollectionTable; +import javax.persistence.Column; +import javax.persistence.ConstraintMode; +import javax.persistence.ElementCollection; +import javax.persistence.Entity; +import javax.persistence.EntityListeners; +import javax.persistence.EnumType; +import javax.persistence.Enumerated; +import javax.persistence.FetchType; +import javax.persistence.ForeignKey; +import javax.persistence.Id; +import javax.persistence.Index; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.MapKeyColumn; +import javax.persistence.MapsId; +import javax.persistence.OneToOne; +import javax.persistence.Table; +import javax.persistence.Transient; + +import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; +import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; +import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.PollStatus; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetInfo; +import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.tenancy.configuration.DurationHelper; +import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; +import org.eclipse.persistence.annotations.CascadeOnDelete; +import org.eclipse.persistence.descriptors.DescriptorEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.data.domain.Persistable; + +/** + * A table which contains all the information inserted, updated by the + * controller itself. So this entity does not provide audit information because + * changes on this entity are mostly only done by controller requests. That's + * the reason that we store these information in a separated table so we don't + * modifying the {@link Target} itself when a controller reports it's + * {@link #lastTargetQuery} for example. + * + */ +@Table(name = "sp_target_info", indexes = { + @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) +@Entity +@EntityListeners(EntityPropertyChangeListener.class) +public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareEntity { + private static final long serialVersionUID = 1L; + + private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); + + @Id + private Long targetId; + + @Transient + private boolean entityNew; + + @CascadeOnDelete + @OneToOne(cascade = { CascadeType.MERGE, + CascadeType.REMOVE }, fetch = FetchType.LAZY, targetEntity = JpaTarget.class) + @JoinColumn(name = "target_id", nullable = false, updatable = false, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_stat_targ")) + @MapsId + private JpaTarget target; + + @Column(name = "address", length = 512) + private String address; + + @Column(name = "last_target_query") + private Long lastTargetQuery; + + @Column(name = "install_date") + private Long installationDate; + + @Column(name = "update_status", nullable = false, length = 255) + @Enumerated(EnumType.STRING) + private TargetUpdateStatus updateStatus = TargetUpdateStatus.UNKNOWN; + + @ManyToOne(optional = true, fetch = FetchType.LAZY) + @JoinColumn(name = "installed_distribution_set", nullable = true, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_target_inst_ds")) + private JpaDistributionSet installedDistributionSet; + + /** + * Read only on management API. Are commited by controller. + */ + @ElementCollection + @Column(name = "attribute_value", length = 128) + @MapKeyColumn(name = "attribute_key", nullable = false, length = 32) + @CollectionTable(name = "sp_target_attributes", joinColumns = { + @JoinColumn(name = "target_id") }, foreignKey = @ForeignKey(value = ConstraintMode.CONSTRAINT, name = "fk_targ_attrib_target")) + + private final Map controllerAttributes = Collections.synchronizedMap(new HashMap()); + + // set default request controller attributes to true, because we want to + // request them the first + // time + @Column(name = "request_controller_attributes", nullable = false) + private boolean requestControllerAttributes = true; + + /** + * Constructor for {@link TargetStatus}. + * + * @param target + * related to this status. + */ + public JpaTargetInfo(final JpaTarget target) { + this.target = target; + targetId = target.getId(); + } + + JpaTargetInfo() { + target = null; + targetId = null; + } + + @Override + public Long getId() { + return targetId; + } + + @Override + @Transient + public boolean isNew() { + return entityNew; + } + + /** + * @param isNew + * the isNew to set + */ + public void setNew(final boolean entityNew) { + this.entityNew = entityNew; + } + + /** + * @return the ipAddress + */ + @Override + public URI getAddress() { + if (address == null) { + return null; + } + try { + return URI.create(address); + } catch (final IllegalArgumentException e) { + LOG.warn("Invalid address provided. Cloud not be configured to URI", e); + return null; + } + } + + /** + * @param address + * the target address to set + * + * @throws IllegalArgumentException + * If the given string violates RFC 2396 + */ + @Override + public void setAddress(final String address) { + // check if this is a real URI + if (address != null) { + try { + URI.create(address); + } catch (final IllegalArgumentException e) { + throw new InvalidTargetAddressException( + "The given address " + address + " violates the RFC-2396 specification", e); + } + } + + this.address = address; + } + + public Long getTargetId() { + return targetId; + } + + public void setTargetId(final Long targetId) { + this.targetId = targetId; + } + + @Override + public Target getTarget() { + return target; + } + + public void setTarget(final JpaTarget target) { + this.target = target; + } + + @Override + public Long getLastTargetQuery() { + return lastTargetQuery; + } + + public void setLastTargetQuery(final Long lastTargetQuery) { + this.lastTargetQuery = lastTargetQuery; + } + + public void setRequestControllerAttributes(final boolean requestControllerAttributes) { + this.requestControllerAttributes = requestControllerAttributes; + } + + @Override + public Map getControllerAttributes() { + return controllerAttributes; + } + + @Override + public boolean isRequestControllerAttributes() { + return requestControllerAttributes; + } + + @Override + public Long getInstallationDate() { + return installationDate; + } + + public void setInstallationDate(final Long installationDate) { + this.installationDate = installationDate; + } + + @Override + public TargetUpdateStatus getUpdateStatus() { + return updateStatus; + } + + public void setUpdateStatus(final TargetUpdateStatus updateStatus) { + this.updateStatus = updateStatus; + } + + @Override + public DistributionSet getInstalledDistributionSet() { + return installedDistributionSet; + } + + public void setInstalledDistributionSet(final JpaDistributionSet installedDistributionSet) { + this.installedDistributionSet = installedDistributionSet; + } + + /** + * @return the poll time which holds the last poll time of the target, the + * next poll time and the overdue time. In case the + * {@link #lastTargetQuery} is not set e.g. the target never polled + * before this method returns {@code null} + */ + @Override + public PollStatus getPollStatus() { + if (lastTargetQuery == null) { + return null; + } + return SystemSecurityContextHolder.getInstance().getSystemSecurityContext().runAsSystem(() -> { + final Duration pollTime = DurationHelper.formattedStringToDuration(TenantConfigurationManagementHolder + .getInstance().getTenantConfigurationManagement() + .getConfigurationValue(TenantConfigurationKey.POLLING_TIME_INTERVAL, String.class).getValue()); + final Duration overdueTime = DurationHelper.formattedStringToDuration( + TenantConfigurationManagementHolder.getInstance().getTenantConfigurationManagement() + .getConfigurationValue(TenantConfigurationKey.POLLING_OVERDUE_TIME_INTERVAL, String.class) + .getValue()); + final LocalDateTime currentDate = LocalDateTime.now(); + final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), + ZoneId.systemDefault()); + final LocalDateTime nextPollDate = lastPollDate.plus(pollTime); + final LocalDateTime overdueDate = nextPollDate.plus(overdueTime); + return new PollStatus(lastPollDate, nextPollDate, overdueDate, currentDate); + }); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((target == null) ? 0 : target.hashCode()); + result = prime * result + ((targetId == null) ? 0 : targetId.hashCode()); + return result; + } + + @Override + public boolean equals(final Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (!(obj instanceof TargetInfo)) { + return false; + } + final JpaTargetInfo other = (JpaTargetInfo) obj; + if (target == null) { + if (other.target != null) { + return false; + } + } else if (!target.equals(other.target)) { + return false; + } + if (targetId == null) { + if (other.targetId != null) { + return false; + } + } else if (!targetId.equals(other.targetId)) { + return false; + } + return true; + } + + @Override + public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo,final DescriptorEvent descriptorEvent) { + // there is no target info created event + } + + @Override + public void fireUpdateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); + } + + @Override + public void fireDeleteEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + } +} From 9c468c76f04b385ba9fbf28dd44cd80edc2d3b05 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 29 Jul 2016 13:12:51 +0200 Subject: [PATCH 040/118] Fix for EOL. --- .../eclipse/hawkbit/repository/DistributionSetManagement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index b3b4fd86f..c405dccf4 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -289,7 +289,7 @@ public interface DistributionSetManagement { * * @param distributionSetId * the distribution set id to retrieve the meta data from - * @return list of distributionSetMetadata for a given distribution set Id + * @return list of distributionSetMetadata for a given distribution set Id. */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) List findDistributionSetMetadataByDistributionSetId(@NotNull Long distributionSetId); From dfd449592cded96d177c1c04deb046c7dd7a3b80 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 29 Jul 2016 13:22:38 +0200 Subject: [PATCH 041/118] Fix for EOL from widows EOL to unix EOL --- .../repository/SoftwareManagement.java | 2 +- .../repository/jpa/JpaSoftwareManagement.java | 13 ++++---- .../repository/jpa/model/JpaAction.java | 17 ++++++----- .../jpa/model/JpaDistributionSet.java | 30 +++++++++---------- .../repository/jpa/model/JpaRollout.java | 14 ++++----- .../repository/jpa/model/JpaRolloutGroup.java | 13 ++++---- .../repository/jpa/model/JpaTarget.java | 16 +++++----- .../repository/jpa/model/JpaTargetInfo.java | 5 ++-- 8 files changed, 58 insertions(+), 52 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java index bb73dbb30..9b4426ff2 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java @@ -496,7 +496,7 @@ public interface SoftwareManagement { * @throws RSQLParameterSyntaxException * if the RSQL syntax is wrong * @return result of all meta data entries for a given software - * module id + * module id. */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) List findSoftwareModuleMetadataBySoftwareModuleId(Long softwareModuleId); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java index 31b222051..3f8c1a54b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaSoftwareManagement.java @@ -620,14 +620,15 @@ public class JpaSoftwareManagement implements SoftwareManagement { pageable), pageable); } - + @Override public List findSoftwareModuleMetadataBySoftwareModuleId(final Long softwareModuleId) { - return new ArrayList<> ( softwareModuleMetadataRepository - .findAll( - (Specification) (root, query, cb) -> cb.and( - cb.equal(root.get(JpaSoftwareModuleMetadata_.softwareModule) - .get(JpaSoftwareModule_.id), softwareModuleId)))); + return new ArrayList<>( + softwareModuleMetadataRepository + .findAll((Specification) (root, query, + cb) -> cb.and(cb.equal( + root.get(JpaSoftwareModuleMetadata_.softwareModule).get(JpaSoftwareModule_.id), + softwareModuleId)))); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java index 5bda8f63b..e7bb04c04 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java @@ -55,7 +55,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action,EventAwareEntity { +public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action, EventAwareEntity { private static final long serialVersionUID = 1L; @ManyToOne(fetch = FetchType.LAZY) @@ -179,21 +179,22 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio @Override public void fireCreateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); - + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() + .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); + } @Override public void fireUpdateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () ->EventBusHolder.getInstance().getEventBus(). - post(new ActionPropertyChangeEvent(jpaAction, EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post(new ActionPropertyChangeEvent(jpaAction, + EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); } - - + @Override public void fireDeleteEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index 77a5f88fd..afbddbade 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -69,9 +69,10 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet,EventAwareEntity { +public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity + implements DistributionSet, EventAwareEntity { private static final long serialVersionUID = 1L; - + private static final String COMPLETE = "complete"; @Column(name = "required_migration_step") @@ -291,30 +292,29 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implemen @Override public void fireCreateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); - + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder + .getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); + } @Override public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - final Map.Values> changeSet = EntityPropertyChangeHelper.getChangeSet( - JpaDistributionSet.class, descriptorEvent); - if (changeSet.containsKey(COMPLETE) - && changeSet.get(COMPLETE).getOldValue().equals(false) + final Map.Values> changeSet = EntityPropertyChangeHelper + .getChangeSet(JpaDistributionSet.class, descriptorEvent); + if (changeSet.containsKey(COMPLETE) && changeSet.get(COMPLETE).getOldValue().equals(false) && changeSet.get(COMPLETE).getNewValue().equals(true)) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post( - new DistributionCreatedEvent(jpaDistributionSet))); + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder + .getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); } - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); - + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder + .getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); + } @Override public void fireDeleteEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java index 1cf1ccb77..57c4d8a69 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java @@ -49,7 +49,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaRollout extends AbstractJpaNamedEntity implements Rollout,EventAwareEntity { +public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, EventAwareEntity { private static final long serialVersionUID = 1L; @@ -204,20 +204,20 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout,EventA @Override public void fireCreateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - + } @Override public void fireUpdateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). - post(new RolloutPropertyChangeEvent(jpaRollout, EntityPropertyChangeHelper.getChangeSet( - Rollout.class, descriptorEvent)))); - + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post(new RolloutPropertyChangeEvent(jpaRollout, + EntityPropertyChangeHelper.getChangeSet(Rollout.class, descriptorEvent)))); + } @Override public void fireDeleteEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java index 225fd458e..0b7a23985 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java @@ -45,7 +45,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup,EventAwareEntity { +public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup, EventAwareEntity { private static final long serialVersionUID = 1L; @@ -243,19 +243,20 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr @Override public void fireCreateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - + } @Override public void fireUpdateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder.getInstance().getEventBus(). - post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, - EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() + .afterCommit(() -> EventBusHolder.getInstance().getEventBus() + .post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, + EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); } @Override public void fireDeleteEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index 431ebb102..d67d8e9d1 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -69,7 +69,8 @@ import org.springframework.data.domain.Persistable; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target, EventAwareEntity { +public class JpaTarget extends AbstractJpaNamedEntity + implements Persistable, Target, EventAwareEntity { private static final long serialVersionUID = 1L; @Column(name = "controller_id", length = 64) @@ -239,19 +240,20 @@ public class JpaTarget extends AbstractJpaNamedEntity implements PersistableEventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() + .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); } @Override - public void fireUpdateEvent(final JpaTarget jpaTarget,final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); - + public void fireUpdateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() + .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); + } @Override public void fireDeleteEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - - + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java index bfae18248..59cff35c8 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java @@ -329,13 +329,14 @@ public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareE } @Override - public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo,final DescriptorEvent descriptorEvent) { + public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { // there is no target info created event } @Override public void fireUpdateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( + () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); } @Override From e7e77cbb86bbe4acb9e183fab704cd4fc6909095 Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Fri, 29 Jul 2016 13:50:30 +0200 Subject: [PATCH 042/118] Extended method signature to allow to set a error handler and created the default one as bean Signed-off-by: Jonathan Philip Knoblauch --- .../hawkbit/amqp/AmqpConfiguration.java | 20 +++++++++++++++++-- ...gurableRabbitListenerContainerFactory.java | 4 +++- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index 11f892654..bee9b2364 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -26,6 +26,7 @@ import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; 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.listener.ConditionalRejectingErrorHandler; import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; @@ -37,7 +38,8 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.retry.backoff.ExponentialBackOffPolicy; -import org.springframework.retry.support.RetryTemplate;; +import org.springframework.retry.support.RetryTemplate; +import org.springframework.util.ErrorHandler;; /** * The spring AMQP configuration which is enabled by using the profile @@ -58,6 +60,9 @@ public class AmqpConfiguration { @Autowired private ConnectionFactory rabbitConnectionFactory; + @Autowired + private ErrorHandler errorHandler; + @Configuration @ConditionalOnMissingBean(ConnectionFactory.class) protected static class RabbitConnectionFactoryCreator { @@ -269,7 +274,7 @@ public class AmqpConfiguration { */ @Bean(name = { "listenerContainerFactory" }) public RabbitListenerContainerFactory listenerContainerFactory() { - return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory); + return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory, errorHandler); } private static Map getTTLMaxArgsAuthenticationQueue() { @@ -279,4 +284,15 @@ public class AmqpConfiguration { return args; } + /** + * Create default error handler bean. + * + * @return the default error handler bean + */ + @Bean + @ConditionalOnMissingBean + public ErrorHandler errorHandler() { + return new ConditionalRejectingErrorHandler(); + } + } diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java index 14e6f8fcb..e792db696 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java @@ -12,6 +12,7 @@ import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFacto import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; +import org.springframework.util.ErrorHandler; /** * {@link RabbitListenerContainerFactory} that can be configured through @@ -30,8 +31,9 @@ public class ConfigurableRabbitListenerContainerFactory extends SimpleRabbitList * to configure the container factory */ public ConfigurableRabbitListenerContainerFactory(final AmqpProperties amqpProperties, - final ConnectionFactory rabbitConnectionFactory) { + final ConnectionFactory rabbitConnectionFactory, final ErrorHandler errorHandler) { this.amqpProperties = amqpProperties; + setErrorHandler(errorHandler); setDefaultRequeueRejected(true); setConnectionFactory(rabbitConnectionFactory); setMissingQueuesFatal(amqpProperties.isMissingQueuesFatal()); From 27019b9e4c8b2d43530b892f223ec17e0f0d729e Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 28 Jul 2016 15:23:56 +0200 Subject: [PATCH 043/118] Beautify error notification. Signed-off-by: Melanie Retter --- .../org/eclipse/hawkbit/ui/ErrorView.java | 3 - .../org/eclipse/hawkbit/ui/HawkbitUI.java | 7 +- ...e.java => HawkbitNotificationMessage.java} | 30 +------ .../ui/components/HawkbitUIErrorHandler.java | 84 +++++++++++++++++++ .../ui/components/SPUIErrorHandler.java | 65 -------------- .../hawkbit/ui/utils/HawkbitCommonUtil.java | 18 ---- .../ui/utils/SPUILabelDefinitions.java | 8 +- .../hawkbit/ui/utils/UINotification.java | 16 ++-- 8 files changed, 103 insertions(+), 128 deletions(-) rename hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/{SPNotificationMessage.java => HawkbitNotificationMessage.java} (61%) create mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java delete mode 100644 hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIErrorHandler.java diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/ErrorView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/ErrorView.java index 4e4cb05a6..710d6d97c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/ErrorView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/ErrorView.java @@ -30,10 +30,7 @@ import com.vaadin.ui.VerticalLayout; * View class that is instantiated when no other view matches the navigation * state. * - * - * * @see Navigator#setErrorView(Class) - * */ @SuppressWarnings("serial") @SpringComponent diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java index f4c26a960..2a56adf28 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/HawkbitUI.java @@ -14,7 +14,7 @@ import java.util.Set; import javax.servlet.http.Cookie; -import org.eclipse.hawkbit.ui.components.SPUIErrorHandler; +import org.eclipse.hawkbit.ui.components.HawkbitUIErrorHandler; import org.eclipse.hawkbit.ui.menu.DashboardEvent.PostViewChangeEvent; import org.eclipse.hawkbit.ui.menu.DashboardMenu; import org.eclipse.hawkbit.ui.menu.DashboardMenuItem; @@ -180,7 +180,10 @@ public class HawkbitUI extends DefaultHawkbitUI implements DetachListener { final String locale = getLocaleId(SPUIDefinitions.getAvailableLocales()); setLocale(new Locale(locale)); - UI.getCurrent().setErrorHandler(new SPUIErrorHandler()); + if (UI.getCurrent().getErrorHandler() == null) { + UI.getCurrent().setErrorHandler(new HawkbitUIErrorHandler()); + } + LOG.info("Current locale of the application is : {}", i18n.getLocale()); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPNotificationMessage.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitNotificationMessage.java similarity index 61% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPNotificationMessage.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitNotificationMessage.java index 2685d2097..b0561dbb5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPNotificationMessage.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitNotificationMessage.java @@ -10,17 +10,13 @@ package org.eclipse.hawkbit.ui.components; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import com.vaadin.server.Page; import com.vaadin.shared.Position; import com.vaadin.ui.Notification; /** * Notification message component. - * - * - * */ -public class SPNotificationMessage extends Notification { +public class HawkbitNotificationMessage extends Notification { /** * ID. @@ -30,30 +26,10 @@ public class SPNotificationMessage extends Notification { /** * Constructor. */ - public SPNotificationMessage() { + public HawkbitNotificationMessage() { super(""); } - /** - * Notification message component. - * - * @param styleName - * style name of message - * @param caption - * message caption - * @param description - * message description - * @param autoClose - * flag to indicate enable close option - * @param page - * current {@link Page} - */ - public void showNotification(final String styleName, final String caption, final String description, - final Boolean autoClose, final Page page) { - decorate(styleName, caption, description, autoClose); - this.show(page); - } - /** * Decorate. * @@ -66,7 +42,7 @@ public class SPNotificationMessage extends Notification { * @param autoClose * flag to indicate enable close option */ - private void decorate(final String styleName, final String caption, final String description, + public void decorateWith(final String styleName, final String caption, final String description, final Boolean autoClose) { setCaption(caption); setDescription(description); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java new file mode 100644 index 000000000..54552d4da --- /dev/null +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -0,0 +1,84 @@ +/** + * 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.ui.components; + +import static com.vaadin.ui.themes.ValoTheme.NOTIFICATION_CLOSABLE; +import static com.vaadin.ui.themes.ValoTheme.NOTIFICATION_FAILURE; +import static com.vaadin.ui.themes.ValoTheme.NOTIFICATION_SMALL; + +import org.eclipse.hawkbit.ui.utils.I18N; +import org.eclipse.hawkbit.ui.utils.SpringContextHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.base.Optional; +import com.vaadin.server.DefaultErrorHandler; +import com.vaadin.server.ErrorEvent; +import com.vaadin.server.Page; +import com.vaadin.ui.Component; + +/** + * Default handler for SP UI. + */ +public class HawkbitUIErrorHandler extends DefaultErrorHandler { + + private static final long serialVersionUID = 1L; + private static final Logger LOG = LoggerFactory.getLogger(HawkbitUIErrorHandler.class); + + private static final String STYLE = NOTIFICATION_FAILURE + " " + NOTIFICATION_SMALL + " " + NOTIFICATION_CLOSABLE; + + @Override + public void error(final ErrorEvent event) { + + LOG.error("Error in UI: ", event.getThrowable()); + + final Optional originError = getPageOriginError(event); + + if (originError.isPresent()) { + final HawkbitNotificationMessage message = buildNotification(getRootExceptionFrom(event)); + message.show(originError.get()); + } + } + + private Throwable getRootExceptionFrom(final ErrorEvent event) { + + return getRootCauseOf(event.getThrowable()); + } + + private Throwable getRootCauseOf(final Throwable exception) { + + if (exception.getCause() != null) { + return getRootCauseOf(exception.getCause()); + } + + return exception; + } + + private Optional getPageOriginError(final ErrorEvent event) { + + final Component errorOrigin = findAbstractComponent(event); + + if (errorOrigin != null && errorOrigin.getUI() != null) { + return Optional.fromNullable(errorOrigin.getUI().getPage()); + } + + return Optional.absent(); + } + + protected HawkbitNotificationMessage buildNotification(final Throwable exception) { + + final HawkbitNotificationMessage notification = new HawkbitNotificationMessage(); + final I18N i18n = SpringContextHelper.getBean(I18N.class); + notification.decorateWith(STYLE, i18n.get("caption.error"), + i18n.get("message.error.temp", exception.getClass().getSimpleName()), false); + + return notification; + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIErrorHandler.java deleted file mode 100644 index e3d4881f0..000000000 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIErrorHandler.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * 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.ui.components; - -import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.I18N; -import org.eclipse.hawkbit.ui.utils.SpringContextHelper; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.vaadin.server.DefaultErrorHandler; -import com.vaadin.server.ErrorEvent; -import com.vaadin.ui.Component; -import com.vaadin.ui.themes.ValoTheme; - -/** - * - * Default handler for SP UI. - * - * - * - * - * - */ -public class SPUIErrorHandler extends DefaultErrorHandler { - - /** - * Comment for serialVersionUID. - */ - private static final long serialVersionUID = 1877326479308824191L; - /** - * logger. - */ - private static final Logger LOG = LoggerFactory.getLogger(SPUIErrorHandler.class); - - @Override - public void error(final ErrorEvent event) { - final SPNotificationMessage notification = new SPNotificationMessage(); - // Build error style - final StringBuilder style = new StringBuilder(ValoTheme.NOTIFICATION_FAILURE); - style.append(' '); - style.append(ValoTheme.NOTIFICATION_SMALL); - style.append(' '); - style.append(ValoTheme.NOTIFICATION_CLOSABLE); - final I18N i18n = SpringContextHelper.getBean(I18N.class); - String exceptionName = null; - // From the exception trace we get the expected exception class name - for (Throwable error = event.getThrowable(); error != null; error = error.getCause()) { - exceptionName = HawkbitCommonUtil.getLastSequenceBySplitByDot(error.getClass().getName()); - LOG.error("Error in SP-UI:", error); - } - final Component errorOrgin = findAbstractComponent(event); - if (null != errorOrgin && errorOrgin.getUI() != null) { - notification.showNotification(style.toString(), i18n.get("caption.error"), - i18n.get("message.error.temp", new Object[] { exceptionName }), false, - errorOrgin.getUI().getPage()); - } - } -} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java index 217a84a30..b5ac26d11 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/HawkbitCommonUtil.java @@ -590,24 +590,6 @@ public final class HawkbitCommonUtil { return requiredExtraWidth + minTableWidth; } - /** - * get the Last sequence of string which is after last dot in String. - * - * @param name - * dotted String name - * @return String name - */ - public static String getLastSequenceBySplitByDot(final String name) { - String lastSequence = null; - if (null != name) { - final String[] strArray = name.split("\\."); - if (strArray.length > 0) { - lastSequence = strArray[strArray.length - 1]; - } - } - return lastSequence; - } - /** * Remove the prefix from text. * diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java index d930b89ea..22d680872 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/SPUILabelDefinitions.java @@ -54,6 +54,7 @@ public final class SPUILabelDefinitions { */ public static final String SP_NOTIFICATION_ERROR_MESSAGE_STYLE = ValoTheme.NOTIFICATION_ERROR + " " + ValoTheme.NOTIFICATION_TRAY; + /** * Style - Warning. */ @@ -539,13 +540,12 @@ public final class SPUILabelDefinitions { * Total target coulmn property name. */ public static final String VAR_TOTAL_TARGETS = "totalTargetsCount"; - - + /** * Total target count status coulmn property name. */ public static final String VAR_TOTAL_TARGETS_COUNT_STATUS = "totalTargetCountStatus"; - + /** * Rollout group started date column property. */ @@ -560,7 +560,7 @@ public final class SPUILabelDefinitions { * Rollout group installed percentage column property. */ public static final String ROLLOUT_GROUP_INSTALLED_PERCENTAGE = "finishedPercentage"; - + /** * Add metadata icon. */ diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java index a1982d625..4822af570 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java @@ -18,8 +18,6 @@ import com.vaadin.spring.annotation.ViewScope; /** * Show success and error messages. - * - * */ @ViewScope @SpringComponent @@ -33,8 +31,6 @@ public class UINotification implements Serializable { /** * Display success type of notification message. * - * @param notificationMessage - * as reference * @param message * is the message to displayed as success. */ @@ -46,8 +42,6 @@ public class UINotification implements Serializable { /** * Display error type of notification message. * - * @param notificationMessage - * as reference * @param message * as message. */ @@ -62,9 +56,13 @@ public class UINotification implements Serializable { /** * Display error type of notification message. * - * @param message. - * @param caption. - * @param autoClose. + * @param message + * errorMessage + * @param caption + * caption of the errorMessage + * @param autoClose + * boolean, if errorMessage should be closed by clicking on the + * error (false) or by clicking anywhere (true) */ public void displayError(final String message, final String caption, final Boolean autoClose) { final StringBuilder updatedMsg = new StringBuilder(FontAwesome.EXCLAMATION_TRIANGLE.getHtml()); From 26c376e22ea7078ee14e8357aea4196ced0d0640 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Mon, 1 Aug 2016 10:13:45 +0200 Subject: [PATCH 044/118] Refactor HawkbitNotificationMessage Signed-off-by: Melanie Retter --- ...a => HawkbitErrorNotificationMessage.java} | 32 +++++-------------- .../ui/components/HawkbitUIErrorHandler.java | 9 ++---- .../hawkbit/ui/utils/NotificationMessage.java | 4 --- 3 files changed, 11 insertions(+), 34 deletions(-) rename hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/{HawkbitNotificationMessage.java => HawkbitErrorNotificationMessage.java} (59%) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitNotificationMessage.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitErrorNotificationMessage.java similarity index 59% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitNotificationMessage.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitErrorNotificationMessage.java index b0561dbb5..e7199c04f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitNotificationMessage.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitErrorNotificationMessage.java @@ -16,7 +16,7 @@ import com.vaadin.ui.Notification; /** * Notification message component. */ -public class HawkbitNotificationMessage extends Notification { +public class HawkbitErrorNotificationMessage extends Notification { /** * ID. @@ -26,34 +26,18 @@ public class HawkbitNotificationMessage extends Notification { /** * Constructor. */ - public HawkbitNotificationMessage() { - super(""); - } - - /** - * Decorate. - * - * @param styleName - * style name of message - * @param caption - * message caption - * @param description - * message description - * @param autoClose - * flag to indicate enable close option - */ - public void decorateWith(final String styleName, final String caption, final String description, - final Boolean autoClose) { - setCaption(caption); - setDescription(description); - setStyleName(styleName); - setHtmlContentAllowed(true); - setPosition(Position.BOTTOM_RIGHT); + public HawkbitErrorNotificationMessage(final String style, final String caption, final String description, + final boolean autoClose) { + super(caption); + setStyleName(style); if (autoClose) { setDelayMsec(SPUILabelDefinitions.SP_DELAY); } else { setDelayMsec(-1); } + setHtmlContentAllowed(true); + setPosition(Position.BOTTOM_RIGHT); + setDescription(description); } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index 54552d4da..aa7e979f9 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -41,7 +41,7 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { final Optional originError = getPageOriginError(event); if (originError.isPresent()) { - final HawkbitNotificationMessage message = buildNotification(getRootExceptionFrom(event)); + final HawkbitErrorNotificationMessage message = buildNotification(getRootExceptionFrom(event)); message.show(originError.get()); } } @@ -71,14 +71,11 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { return Optional.absent(); } - protected HawkbitNotificationMessage buildNotification(final Throwable exception) { + protected HawkbitErrorNotificationMessage buildNotification(final Throwable exception) { - final HawkbitNotificationMessage notification = new HawkbitNotificationMessage(); final I18N i18n = SpringContextHelper.getBean(I18N.class); - notification.decorateWith(STYLE, i18n.get("caption.error"), + return new HawkbitErrorNotificationMessage(STYLE, i18n.get("caption.error"), i18n.get("message.error.temp", exception.getClass().getSimpleName()), false); - - return notification; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/NotificationMessage.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/NotificationMessage.java index edfb99f22..1e2dbcf07 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/NotificationMessage.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/NotificationMessage.java @@ -16,8 +16,6 @@ import com.vaadin.ui.Notification; /** * Show notification messages. - * - * */ @UIScope @SpringComponent @@ -27,8 +25,6 @@ public class NotificationMessage extends Notification { /** * Default constructor of notification message. - * - * @param caption */ public NotificationMessage() { super(""); From 5be513422de8c89fc52781976f023c677a45f869 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 1 Aug 2016 10:24:09 +0200 Subject: [PATCH 045/118] remove notification of target deletion from management layer Signed-off-by: Michael Hirsch --- .../repository/jpa/JpaTargetManagement.java | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 30a5dd5d9..1cd2ffc3c 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -29,7 +29,6 @@ import javax.persistence.criteria.Root; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetManagement; -import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.jpa.configuration.Constants; @@ -49,7 +48,6 @@ import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; -import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.domain.Page; @@ -98,10 +96,6 @@ public class JpaTargetManagement implements TargetManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; - - - @Autowired - private TenantAware tenantAware; @Override public Target findTargetByControllerID(final String controllerId) { @@ -208,14 +202,12 @@ public class JpaTargetManagement implements TargetManagement { // hibernate session. final List targetsForCurrentTenant = targetRepository.findAll(Lists.newArrayList(targetIDs)).stream() .map(Target::getId).collect(Collectors.toList()); - if (!targetsForCurrentTenant.isEmpty()) { - targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant); - targetRepository.deleteByIdIn(targetsForCurrentTenant); - targetsForCurrentTenant.forEach(targetId -> notifyTargetDeleted( - tenantAware.getCurrentTenant(), targetId)); - } + if (!targetsForCurrentTenant.isEmpty()) { + targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant); + targetRepository.deleteByIdIn(targetsForCurrentTenant); + } } - + @Override public Page findTargetByAssignedDistributionSet(final Long distributionSetID, final Pageable pageReq) { return targetRepository.findByAssignedDistributionSetId(pageReq, distributionSetID); @@ -659,9 +651,5 @@ public class JpaTargetManagement implements TargetManagement { } return resultList; } - - private void notifyTargetDeleted(final String tenant, final Long targetId) { - afterCommit.afterCommit(() -> eventBus.post(new TargetDeletedEvent(tenant, targetId))); - } } From 72899df4a46cb6b5304857d96972a793bd7a7768 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 1 Aug 2016 10:30:45 +0200 Subject: [PATCH 046/118] remove notification of distribution set deletion from management layer Signed-off-by: Michael Hirsch --- .../repository/jpa/JpaDistributionSetManagement.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index 306b9bd80..84c81966f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -28,7 +28,6 @@ import org.eclipse.hawkbit.repository.DistributionSetMetadataFields; import org.eclipse.hawkbit.repository.DistributionSetTypeFields; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TagManagement; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityLockedException; @@ -55,7 +54,6 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -104,9 +102,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; - @Autowired - private TenantAware tenantAware; - @Override public DistributionSet findDistributionSetByIdWithDetails(final Long distid) { return distributionSetRepository.findOne(DistributionSetSpecification.byId(distid)); @@ -198,10 +193,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { // handle the empty list distributionSetRepository.deleteByIdIn(toHardDelete); } - - afterCommit.afterCommit( - () -> eventBus.post(new DistributionDeletedEvent(tenantAware.getCurrentTenant(), distributionSetIDs))); - } @Override @@ -527,14 +518,12 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying public void deleteDistributionSetMetadata(final DistributionSet distributionSet, final String key) { - entityManager.merge((JpaDistributionSet) distributionSet).setLastModifiedAt(0L); distributionSetMetadataRepository.delete(new DsMetadataCompositeKey(distributionSet, key)); } @Override public Page findDistributionSetMetadataByDistributionSetId(final Long distributionSetId, final Pageable pageable) { - return convertMdPage(distributionSetMetadataRepository .findAll((Specification) (root, query, cb) -> cb.equal( root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id), @@ -544,7 +533,6 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Override public List findDistributionSetMetadataByDistributionSetId(final Long distributionSetId) { - return new ArrayList(distributionSetMetadataRepository .findAll((Specification) (root, query, cb) -> cb.equal( root.get(JpaDistributionSetMetadata_.distributionSet).get(JpaDistributionSet_.id), From 87dc8b8964da8b2437db11cf7eb3b96c8cf86ebf Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Mon, 1 Aug 2016 10:38:28 +0200 Subject: [PATCH 047/118] Set the errorHandler as parameter in method Signed-off-by: Jonathan Philip Knoblauch --- .../java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index bee9b2364..9979e9a90 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -60,8 +60,8 @@ public class AmqpConfiguration { @Autowired private ConnectionFactory rabbitConnectionFactory; - @Autowired - private ErrorHandler errorHandler; + // @Autowired + // private ErrorHandler errorHandler; @Configuration @ConditionalOnMissingBean(ConnectionFactory.class) @@ -273,7 +273,8 @@ public class AmqpConfiguration { * AMQP messages */ @Bean(name = { "listenerContainerFactory" }) - public RabbitListenerContainerFactory listenerContainerFactory() { + public RabbitListenerContainerFactory listenerContainerFactory( + final ErrorHandler errorHandler) { return new ConfigurableRabbitListenerContainerFactory(amqpProperties, rabbitConnectionFactory, errorHandler); } From 1a1d3746df58762c1a4c2813d3b632089e03a8a4 Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Mon, 1 Aug 2016 10:47:36 +0200 Subject: [PATCH 048/118] Moved errorHandler to to autoconfig Signed-off-by: Jonathan Philip Knoblauch --- .../autoconfigure/amqp/AmqpAutoConfiguration.java | 15 +++++++++++++++ .../eclipse/hawkbit/amqp/AmqpConfiguration.java | 12 ------------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/amqp/AmqpAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/amqp/AmqpAutoConfiguration.java index 681e485fc..3e1f48c27 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/amqp/AmqpAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/amqp/AmqpAutoConfiguration.java @@ -10,8 +10,12 @@ package org.eclipse.hawkbit.autoconfigure.amqp; import org.eclipse.hawkbit.amqp.AmqpConfiguration; import org.eclipse.hawkbit.amqp.annotation.EnableAmqp; +import org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.util.ErrorHandler; /** * The amqp autoconfiguration. @@ -24,4 +28,15 @@ import org.springframework.context.annotation.Configuration; @EnableAmqp public class AmqpAutoConfiguration { + /** + * Create default error handler bean. + * + * @return the default error handler bean + */ + @Bean + @ConditionalOnMissingBean + public ErrorHandler errorHandler() { + return new ConditionalRejectingErrorHandler(); + } + } diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index 9979e9a90..5e5530f9d 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -26,7 +26,6 @@ import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; 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.listener.ConditionalRejectingErrorHandler; import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; @@ -285,15 +284,4 @@ public class AmqpConfiguration { return args; } - /** - * Create default error handler bean. - * - * @return the default error handler bean - */ - @Bean - @ConditionalOnMissingBean - public ErrorHandler errorHandler() { - return new ConditionalRejectingErrorHandler(); - } - } From de375fe1835c0e38fca03fd2440a2a25e733c8a7 Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Mon, 1 Aug 2016 10:51:36 +0200 Subject: [PATCH 049/118] Updated javadoc Signed-off-by: Jonathan Philip Knoblauch --- .../main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java | 4 +++- .../amqp/ConfigurableRabbitListenerContainerFactory.java | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index 5e5530f9d..d15336eb6 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -267,7 +267,9 @@ public class AmqpConfiguration { /** * Returns the Listener factory. - * + * + * @param errorHandler + * the error hander * @return the {@link SimpleMessageListenerContainer} that gets used receive * AMQP messages */ diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java index e792db696..b213e744b 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/ConfigurableRabbitListenerContainerFactory.java @@ -29,6 +29,8 @@ public class ConfigurableRabbitListenerContainerFactory extends SimpleRabbitList * for the container factory * @param amqpProperties * to configure the container factory + * @param errorHandler + * the error handler which should be use */ public ConfigurableRabbitListenerContainerFactory(final AmqpProperties amqpProperties, final ConnectionFactory rabbitConnectionFactory, final ErrorHandler errorHandler) { From 4462d0aad96465e92842cb1f28d91bd7e6c17343 Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Mon, 1 Aug 2016 11:15:52 +0200 Subject: [PATCH 050/118] Refactoring for configuration Signed-off-by: Jonathan Philip Knoblauch --- .../java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index d15336eb6..bcac6a6e5 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -38,7 +38,7 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.retry.backoff.ExponentialBackOffPolicy; import org.springframework.retry.support.RetryTemplate; -import org.springframework.util.ErrorHandler;; +import org.springframework.util.ErrorHandler; /** * The spring AMQP configuration which is enabled by using the profile @@ -59,9 +59,6 @@ public class AmqpConfiguration { @Autowired private ConnectionFactory rabbitConnectionFactory; - // @Autowired - // private ErrorHandler errorHandler; - @Configuration @ConditionalOnMissingBean(ConnectionFactory.class) protected static class RabbitConnectionFactoryCreator { From 4e237f748bad38dec815360226abf5cc012172e6 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 1 Aug 2016 13:01:25 +0200 Subject: [PATCH 051/118] refactor the EventAwareEntity interface Signed-off-by: Michael Hirsch --- .../model/EntityPropertyChangeListener.java | 26 +++++++++--- .../jpa/model/EventAwareEntity.java | 40 +++++++++---------- .../repository/jpa/model/JpaAction.java | 21 ++++------ .../jpa/model/JpaDistributionSet.java | 39 +++++++++--------- .../repository/jpa/model/JpaRollout.java | 24 +++++------ .../repository/jpa/model/JpaRolloutGroup.java | 20 ++++------ .../repository/jpa/model/JpaTarget.java | 21 ++++------ .../repository/jpa/model/JpaTargetInfo.java | 13 +++--- 8 files changed, 101 insertions(+), 103 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java index df36309df..13b1507db 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java @@ -8,6 +8,7 @@ */ package org.eclipse.hawkbit.repository.jpa.model; +import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.descriptors.DescriptorEventAdapter; @@ -19,21 +20,34 @@ public class EntityPropertyChangeListener extends DescriptorEventAdapter { @Override public void postInsert(final DescriptorEvent event) { - final Object object = event.getObject(); - if (object instanceof EventAwareEntity) { - ((EventAwareEntity) object).fireCreateEvent(object,event); + if (isEventAwareEntity(object)) { + doNotifiy(() -> ((EventAwareEntity) object).fireCreateEvent(event)); } } @Override public void postUpdate(final DescriptorEvent event) { - final Object object = event.getObject(); - if (object instanceof EventAwareEntity) { - ((EventAwareEntity) object).fireUpdateEvent(object,event); + if (isEventAwareEntity(object)) { + doNotifiy(() -> ((EventAwareEntity) object).fireUpdateEvent(event)); } } + @Override + public void postDelete(final DescriptorEvent event) { + final Object object = event.getObject(); + if (isEventAwareEntity(object)) { + doNotifiy(() -> ((EventAwareEntity) object).fireDeleteEvent(event)); + } + } + + private boolean isEventAwareEntity(final Object object) { + return object instanceof EventAwareEntity; + } + + private void doNotifiy(final Runnable runnable) { + AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(runnable); + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java index 2c1fe51d2..1c6f217c9 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java @@ -1,20 +1,20 @@ -/** - * 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.jpa.model; - -import org.eclipse.persistence.descriptors.DescriptorEvent; - -public interface EventAwareEntity { - - public void fireCreateEvent(T t,DescriptorEvent descriptorEvent); - - public void fireUpdateEvent(T t,DescriptorEvent descriptorEvent); - - public void fireDeleteEvent(T t,DescriptorEvent descriptorEvent); -} +/** + * 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.jpa.model; + +import org.eclipse.persistence.descriptors.DescriptorEvent; + +public interface EventAwareEntity { + + void fireCreateEvent(DescriptorEvent descriptorEvent); + + void fireUpdateEvent(DescriptorEvent descriptorEvent); + + void fireDeleteEvent(DescriptorEvent descriptorEvent); +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java index e7bb04c04..72ef46ba3 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaAction.java @@ -30,7 +30,6 @@ import javax.persistence.Table; import org.eclipse.hawkbit.repository.eventbus.event.ActionCreatedEvent; import org.eclipse.hawkbit.repository.eventbus.event.ActionPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.model.Action; @@ -55,7 +54,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action, EventAwareEntity { +public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Action, EventAwareEntity { private static final long serialVersionUID = 1L; @ManyToOne(fetch = FetchType.LAZY) @@ -178,23 +177,19 @@ public class JpaAction extends AbstractJpaTenantAwareBaseEntity implements Actio } @Override - public void fireCreateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() - .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(jpaAction))); - + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new ActionCreatedEvent(this)); } @Override - public void fireUpdateEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post(new ActionPropertyChangeEvent(jpaAction, - EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent)))); - + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new ActionPropertyChangeEvent(this, + EntityPropertyChangeHelper.getChangeSet(Action.class, descriptorEvent))); } @Override - public void fireDeleteEvent(final JpaAction jpaAction, final DescriptorEvent descriptorEvent) { - + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + // there is no action deletion } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index afbddbade..cbaed2dbf 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -36,10 +36,10 @@ import javax.persistence.UniqueConstraint; import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.model.Action; @@ -69,11 +69,12 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity - implements DistributionSet, EventAwareEntity { +public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity implements DistributionSet, EventAwareEntity { private static final long serialVersionUID = 1L; - private static final String COMPLETE = "complete"; + private static final String COMPLETE_PROPERTY = "complete"; + + private static final String DELETED_PROPERTY = "deleted"; @Column(name = "required_migration_step") private boolean requiredMigrationStep; @@ -291,30 +292,30 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity } @Override - public void fireCreateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder - .getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); - + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(this)); } @Override - public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { final Map.Values> changeSet = EntityPropertyChangeHelper .getChangeSet(JpaDistributionSet.class, descriptorEvent); - if (changeSet.containsKey(COMPLETE) && changeSet.get(COMPLETE).getOldValue().equals(false) - && changeSet.get(COMPLETE).getNewValue().equals(true)) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder - .getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); + if (changeSet.containsKey(COMPLETE_PROPERTY) && changeSet.get(COMPLETE_PROPERTY).getOldValue().equals(false) + && changeSet.get(COMPLETE_PROPERTY).getNewValue().equals(true)) { + EventBusHolder.getInstance().getEventBus().post(new DistributionCreatedEvent(this)); } + EventBusHolder.getInstance().getEventBus().post(new DistributionSetUpdateEvent(this)); - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder - .getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); - + if (changeSet.containsKey(DELETED_PROPERTY)) { + final Boolean newDeleted = (Boolean) changeSet.get(DELETED_PROPERTY).getNewValue(); + if (newDeleted) { + EventBusHolder.getInstance().getEventBus().post(new DistributionDeletedEvent(getTenant(), getId())); + } + } } @Override - public void fireDeleteEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new DistributionDeletedEvent(getTenant(), getId())); } - } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java index 57c4d8a69..85395e27b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRollout.java @@ -28,7 +28,6 @@ import javax.persistence.UniqueConstraint; import org.eclipse.hawkbit.repository.eventbus.event.RolloutPropertyChangeEvent; import org.eclipse.hawkbit.repository.jpa.cache.CacheField; import org.eclipse.hawkbit.repository.jpa.cache.CacheKeys; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.model.Action.ActionType; @@ -49,7 +48,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, EventAwareEntity { +public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, EventAwareEntity { private static final long serialVersionUID = 1L; @@ -203,21 +202,20 @@ public class JpaRollout extends AbstractJpaNamedEntity implements Rollout, Event } @Override - public void fireCreateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { + // there is no rollout creation event + } + + @Override + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new RolloutPropertyChangeEvent(this, + EntityPropertyChangeHelper.getChangeSet(Rollout.class, descriptorEvent))); } @Override - public void fireUpdateEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post(new RolloutPropertyChangeEvent(jpaRollout, - EntityPropertyChangeHelper.getChangeSet(Rollout.class, descriptorEvent)))); - - } - - @Override - public void fireDeleteEvent(final JpaRollout jpaRollout, final DescriptorEvent descriptorEvent) { - + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + // there is no rollout deletion event } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java index 0b7a23985..9bb8644f4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaRolloutGroup.java @@ -26,7 +26,6 @@ import javax.persistence.Transient; import javax.persistence.UniqueConstraint; import org.eclipse.hawkbit.repository.eventbus.event.RolloutGroupPropertyChangeEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.model.Rollout; @@ -45,7 +44,7 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup, EventAwareEntity { +public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGroup, EventAwareEntity { private static final long serialVersionUID = 1L; @@ -242,21 +241,18 @@ public class JpaRolloutGroup extends AbstractJpaNamedEntity implements RolloutGr } @Override - public void fireCreateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { + // there is no RolloutGroup created event } @Override - public void fireUpdateEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() - .afterCommit(() -> EventBusHolder.getInstance().getEventBus() - .post(new RolloutGroupPropertyChangeEvent(jpaRolloutGroup, - EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent)))); + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new RolloutGroupPropertyChangeEvent(this, + EntityPropertyChangeHelper.getChangeSet(RolloutGroup.class, descriptorEvent))); } @Override - public void fireDeleteEvent(final JpaRolloutGroup jpaRolloutGroup, final DescriptorEvent descriptorEvent) { - + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + // there is no RolloutGroup deleted event } - } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java index d67d8e9d1..c91247321 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTarget.java @@ -37,8 +37,8 @@ import javax.validation.constraints.Size; import org.eclipse.hawkbit.im.authentication.SpPermission; import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityChecker; import org.eclipse.hawkbit.repository.jpa.model.helper.SecurityTokenGeneratorHolder; @@ -69,8 +69,7 @@ import org.springframework.data.domain.Persistable; // exception squid:S2160 - BaseEntity equals/hashcode is handling correctly for // sub entities @SuppressWarnings("squid:S2160") -public class JpaTarget extends AbstractJpaNamedEntity - implements Persistable, Target, EventAwareEntity { +public class JpaTarget extends AbstractJpaNamedEntity implements Persistable, Target, EventAwareEntity { private static final long serialVersionUID = 1L; @Column(name = "controller_id", length = 64) @@ -239,21 +238,17 @@ public class JpaTarget extends AbstractJpaNamedEntity } @Override - public void fireCreateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() - .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(jpaTarget))); + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new TargetCreatedEvent(this)); } @Override - public void fireUpdateEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit() - .afterCommit(() -> EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(jpaTarget))); - + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new TargetUpdatedEvent(this)); } @Override - public void fireDeleteEvent(final JpaTarget jpaTarget, final DescriptorEvent descriptorEvent) { - + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new TargetDeletedEvent(getTenant(), getId())); } - } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java index 59cff35c8..3923275df 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaTargetInfo.java @@ -40,7 +40,6 @@ import javax.persistence.Transient; import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; import org.eclipse.hawkbit.repository.exception.InvalidTargetAddressException; -import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.SystemSecurityContextHolder; import org.eclipse.hawkbit.repository.jpa.model.helper.TenantConfigurationManagementHolder; @@ -70,7 +69,7 @@ import org.springframework.data.domain.Persistable; @Index(name = "sp_idx_target_info_02", columnList = "target_id,update_status") }) @Entity @EntityListeners(EntityPropertyChangeListener.class) -public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareEntity { +public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareEntity { private static final long serialVersionUID = 1L; private static final Logger LOG = LoggerFactory.getLogger(TargetInfo.class); @@ -329,17 +328,17 @@ public class JpaTargetInfo implements Persistable, TargetInfo, EventAwareE } @Override - public void fireCreateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + public void fireCreateEvent(final DescriptorEvent descriptorEvent) { // there is no target info created event } @Override - public void fireUpdateEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit( - () -> EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(jpaTargetInfo))); + public void fireUpdateEvent(final DescriptorEvent descriptorEvent) { + EventBusHolder.getInstance().getEventBus().post(new TargetInfoUpdateEvent(this)); } @Override - public void fireDeleteEvent(final JpaTargetInfo jpaTargetInfo, final DescriptorEvent descriptorEvent) { + public void fireDeleteEvent(final DescriptorEvent descriptorEvent) { + // there is no target info deleted event } } From c0a3a44277bb3ecb06fb4e98d374a3d51a757d01 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Mon, 1 Aug 2016 13:40:40 +0200 Subject: [PATCH 052/118] Delete displayError in UiNotification Signed-off-by: Melanie Retter --- .../ui/components/HawkbitUIErrorHandler.java | 6 +++--- .../targettable/BulkUploadHandler.java | 7 ++++++- .../hawkbit/ui/utils/UINotification.java | 18 ------------------ 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index aa7e979f9..56bcba421 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -46,12 +46,12 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { } } - private Throwable getRootExceptionFrom(final ErrorEvent event) { + private static Throwable getRootExceptionFrom(final ErrorEvent event) { return getRootCauseOf(event.getThrowable()); } - private Throwable getRootCauseOf(final Throwable exception) { + private static Throwable getRootCauseOf(final Throwable exception) { if (exception.getCause() != null) { return getRootCauseOf(exception.getCause()); @@ -60,7 +60,7 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { return exception; } - private Optional getPageOriginError(final ErrorEvent event) { + private static Optional getPageOriginError(final ErrorEvent event) { final Component errorOrigin = findAbstractComponent(event); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index 982e9d75b..ee062493e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -33,6 +33,7 @@ import org.eclipse.hawkbit.repository.model.Action.ActionType; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.ui.common.DistributionSetIdName; import org.eclipse.hawkbit.ui.common.tagdetails.AbstractTagToken.TagData; +import org.eclipse.hawkbit.ui.components.HawkbitErrorNotificationMessage; import org.eclipse.hawkbit.ui.management.event.BulkUploadValidationMessageEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent.TargetComponentEvent; @@ -40,12 +41,14 @@ import org.eclipse.hawkbit.ui.management.state.ManagementUIState; import org.eclipse.hawkbit.ui.management.state.TargetBulkUpload; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; +import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SpringContextHelper; import org.eclipse.hawkbit.ui.utils.UINotification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vaadin.spring.events.EventBus; +import com.vaadin.server.Page; import com.vaadin.ui.Alignment; import com.vaadin.ui.ComboBox; import com.vaadin.ui.CustomComponent; @@ -445,7 +448,9 @@ public class BulkUploadHandler extends CustomComponent @Override public void uploadStarted(final StartedEvent event) { if (!event.getFilename().endsWith(".csv")) { - uINotification.displayError(i18n.get("bulk.targets.upload"), null, true); + + new HawkbitErrorNotificationMessage(SPUILabelDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE, null, + i18n.get("bulk.targets.upload"), true).show(Page.getCurrent()); LOG.error("Wrong file format for file {}", event.getFilename()); upload.interruptUpload(); } else { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java index 4822af570..8e7c52bc6 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/utils/UINotification.java @@ -53,22 +53,4 @@ public class UINotification implements Serializable { updatedMsg.toString(), true); } - /** - * Display error type of notification message. - * - * @param message - * errorMessage - * @param caption - * caption of the errorMessage - * @param autoClose - * boolean, if errorMessage should be closed by clicking on the - * error (false) or by clicking anywhere (true) - */ - public void displayError(final String message, final String caption, final Boolean autoClose) { - final StringBuilder updatedMsg = new StringBuilder(FontAwesome.EXCLAMATION_TRIANGLE.getHtml()); - updatedMsg.append(' '); - updatedMsg.append(message); - notificationMessage.showNotification(SPUILabelDefinitions.SP_NOTIFICATION_ERROR_MESSAGE_STYLE, caption, - updatedMsg.toString(), autoClose); - } } From 60cc2c333c60ac5f6dfd44f67e4702dfc345ab95 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 1 Aug 2016 15:12:03 +0200 Subject: [PATCH 053/118] Refactored the code for displaying distributions in the deployment view. --- .../jpa/model/JpaDistributionSet.java | 11 ----- .../management/dstable/DistributionTable.java | 44 +++++++++++-------- 2 files changed, 25 insertions(+), 30 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java index afbddbade..1fddb8837 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/JpaDistributionSet.java @@ -13,7 +13,6 @@ import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; @@ -34,13 +33,11 @@ import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.UniqueConstraint; -import org.eclipse.hawkbit.repository.eventbus.event.AbstractPropertyChangeEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.exception.DistributionSetTypeUndefinedException; import org.eclipse.hawkbit.repository.exception.UnsupportedSoftwareModuleForThisDistributionSetException; import org.eclipse.hawkbit.repository.jpa.model.helper.AfterTransactionCommitExecutorHolder; -import org.eclipse.hawkbit.repository.jpa.model.helper.EntityPropertyChangeHelper; import org.eclipse.hawkbit.repository.jpa.model.helper.EventBusHolder; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -299,14 +296,6 @@ public class JpaDistributionSet extends AbstractJpaNamedVersionedEntity @Override public void fireUpdateEvent(final JpaDistributionSet jpaDistributionSet, final DescriptorEvent descriptorEvent) { - final Map.Values> changeSet = EntityPropertyChangeHelper - .getChangeSet(JpaDistributionSet.class, descriptorEvent); - if (changeSet.containsKey(COMPLETE) && changeSet.get(COMPLETE).getOldValue().equals(false) - && changeSet.get(COMPLETE).getNewValue().equals(true)) { - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder - .getInstance().getEventBus().post(new DistributionCreatedEvent(jpaDistributionSet))); - } - AfterTransactionCommitExecutorHolder.getInstance().getAfterCommit().afterCommit(() -> EventBusHolder .getInstance().getEventBus().post(new DistributionSetUpdateEvent(jpaDistributionSet))); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index ff1edafc8..633a5834b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -21,7 +21,6 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; -import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -123,9 +122,6 @@ public class DistributionTable extends AbstractNamedVersionTable) events); - } else if (DistributionCreatedEvent.class.isInstance(firstEvent) - && ((DistributionCreatedEvent) firstEvent).getEntity().isComplete()) { - refreshDistributions(); } } @@ -133,18 +129,28 @@ public class DistributionTable extends AbstractNamedVersionTable visibleItemIds = (List) getVisibleItemIds(); - - // refresh the details tabs only if selected ds is updated - // refresh the details tabs only if selected ds is updated + + + final Boolean dsVisible = visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent(); + + if((ds.isComplete() && !dsVisible) ){ + refreshDistributions(); + } + else if( (!ds.isComplete() && dsVisible)){ + refreshDistributions(); + managementUIState.setLastSelectedDistribution(null); + } + else if(dsVisible){ + UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); + } + final DistributionSetIdName lastSelectedDsIdName = managementUIState.getLastSelectedDsIdName(); + // refresh the details tabs only if selected ds is updated if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) { // update table row+details layout eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, ds)); - } else if (visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent()) { - //update the name/version details visible in table - UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); - } + } } /** @@ -261,7 +267,7 @@ public class DistributionTable extends AbstractNamedVersionTable showMetadataDetails(itemId)); @@ -281,7 +287,7 @@ public class DistributionTable extends AbstractNamedVersionTable events) { + private void onDistributionDeleteEvent(final List events) { final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); final List visibleItemIds = (List) getVisibleItemIds(); boolean shouldRefreshDs = false; for (final DistributionDeletedEvent deletedEvent : events) { - Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); - for (Long dsId : distributionSetIDs) { + final Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); + for (final Long dsId : distributionSetIDs) { final DistributionSetIdName targetIdName = new DistributionSetIdName(dsId, null, null); if (visibleItemIds.contains(targetIdName)) { dsContainer.removeItem(targetIdName); From 9c442967f8a66c31ed0d8f6ac1d35a77793a558f Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 1 Aug 2016 15:14:40 +0200 Subject: [PATCH 054/118] add tests for repository entity events Signed-off-by: Michael Hirsch --- .../event/DistributionDeletedEvent.java | 25 ++- .../jpa/JpaDistributionSetManagement.java | 8 + .../repository/jpa/JpaTargetManagement.java | 7 + .../eventbus/RepositoryEntityEventTest.java | 161 ++++++++++++++++++ .../dstable/DistributionSetTable.java | 48 +++--- .../management/dstable/DistributionTable.java | 55 +++--- 6 files changed, 237 insertions(+), 67 deletions(-) create mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/eventbus/RepositoryEntityEventTest.java diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java index 1edfb47ac..7d04ba9c6 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/DistributionDeletedEvent.java @@ -11,27 +11,26 @@ package org.eclipse.hawkbit.repository.eventbus.event; import org.eclipse.hawkbit.eventbus.event.AbstractDistributedEvent; import org.eclipse.hawkbit.repository.model.DistributionSet; - /** - * * Defines the {@link AbstractDistributedEvent} for deletion of {@link DistributionSet}. - - * + * Defines the {@link AbstractDistributedEvent} for deletion of + * {@link DistributionSet}. */ -public class DistributionDeletedEvent extends AbstractDistributedEvent{ - private static final long serialVersionUID = -3308850381757843098L; - final Long[] distributionSetIDs; +public class DistributionDeletedEvent extends AbstractDistributedEvent { + private static final long serialVersionUID = -3308850381757843098L; + private final Long distributionId; + /** * @param tenant * the tenant for this event * @param distributionSetId - * the ID of the target which has been deleted + * the ID of the distribution set which has been deleted */ - public DistributionDeletedEvent(final String tenant, final Long...distributionIds) { + public DistributionDeletedEvent(final String tenant, final Long distributionId) { super(-1, tenant); - this.distributionSetIDs = distributionIds; + this.distributionId = distributionId; } - public Long[] getDistributionSetIDs() { - return distributionSetIDs; - } + public Long getDistributionSetId() { + return distributionId; + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index 84c81966f..8842a3507 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -28,6 +28,7 @@ import org.eclipse.hawkbit.repository.DistributionSetMetadataFields; import org.eclipse.hawkbit.repository.DistributionSetTypeFields; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TagManagement; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.exception.EntityLockedException; @@ -54,6 +55,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; +import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -102,6 +104,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Autowired private AfterTransactionCommitExecutor afterCommit; + @Autowired + private TenantAware tenantAware; + @Override public DistributionSet findDistributionSetByIdWithDetails(final Long distid) { return distributionSetRepository.findOne(DistributionSetSpecification.byId(distid)); @@ -193,6 +198,9 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { // handle the empty list distributionSetRepository.deleteByIdIn(toHardDelete); } + + Arrays.stream(distributionSetIDs) + .forEach(dsId -> eventBus.post(new DistributionDeletedEvent(tenantAware.getCurrentTenant(), dsId))); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java index 1cd2ffc3c..225c0b4b2 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaTargetManagement.java @@ -29,6 +29,7 @@ import javax.persistence.criteria.Root; import org.eclipse.hawkbit.repository.TargetFields; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.TargetTagAssigmentResultEvent; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; import org.eclipse.hawkbit.repository.jpa.configuration.Constants; @@ -48,6 +49,7 @@ import org.eclipse.hawkbit.repository.model.TargetIdName; import org.eclipse.hawkbit.repository.model.TargetTag; import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.eclipse.hawkbit.tenancy.TenantAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.data.domain.Page; @@ -94,6 +96,9 @@ public class JpaTargetManagement implements TargetManagement { @Autowired private EventBus eventBus; + @Autowired + private TenantAware tenantAware; + @Autowired private AfterTransactionCommitExecutor afterCommit; @@ -206,6 +211,8 @@ public class JpaTargetManagement implements TargetManagement { targetInfoRepository.deleteByTargetIdIn(targetsForCurrentTenant); targetRepository.deleteByIdIn(targetsForCurrentTenant); } + targetsForCurrentTenant + .forEach(targetId -> eventBus.post(new TargetDeletedEvent(tenantAware.getCurrentTenant(), targetId))); } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/eventbus/RepositoryEntityEventTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/eventbus/RepositoryEntityEventTest.java new file mode 100644 index 000000000..0aa305d52 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/eventbus/RepositoryEntityEventTest.java @@ -0,0 +1,161 @@ +/** + * 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.jpa.eventbus; + +import static org.fest.assertions.Assertions.assertThat; + +import java.net.URI; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import org.eclipse.hawkbit.eventbus.event.Event; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetCreatedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetDeletedEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetInfoUpdateEvent; +import org.eclipse.hawkbit.repository.eventbus.event.TargetUpdatedEvent; +import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; +import org.fest.assertions.api.Assertions; +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import com.google.common.eventbus.EventBus; +import com.google.common.eventbus.Subscribe; + +import ru.yandex.qatools.allure.annotations.Description; +import ru.yandex.qatools.allure.annotations.Features; +import ru.yandex.qatools.allure.annotations.Stories; + +@Features("Component Tests - Repository") +@Stories("Entity Events") +public class RepositoryEntityEventTest extends AbstractJpaIntegrationTest { + + @Autowired + private EventBus eventBus; + + private final MyEventListener eventListener = new MyEventListener(); + + @Before + public void beforeTest() { + eventListener.queue.clear(); + eventBus.register(eventListener); + } + + @Test + @Description("Verifies that the target created event is published when a target has been created") + public void targetCreatedEventIsPublished() throws InterruptedException { + final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345")); + + final TargetCreatedEvent targetCreatedEvent = eventListener.waitForEvent(TargetCreatedEvent.class, 1, + TimeUnit.SECONDS); + assertThat(targetCreatedEvent).isNotNull(); + assertThat(targetCreatedEvent.getEntity().getId()).isEqualTo(createdTarget.getId()); + } + + @Test + @Description("Verifies that the target update event is published when a target has been updated") + public void targetUpdateEventIsPublished() throws InterruptedException { + final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345")); + createdTarget.setName("updateName"); + targetManagement.updateTarget(createdTarget); + + final TargetUpdatedEvent targetUpdatedEvent = eventListener.waitForEvent(TargetUpdatedEvent.class, 1, + TimeUnit.SECONDS); + assertThat(targetUpdatedEvent).isNotNull(); + assertThat(targetUpdatedEvent.getEntity().getId()).isEqualTo(createdTarget.getId()); + } + + @Test + @Description("Verifies that the target info update event is published when a target info has been updated") + public void targetInfoUpdateEventIsPublished() throws InterruptedException { + final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345")); + controllerManagament.updateTargetStatus(createdTarget.getTargetInfo(), TargetUpdateStatus.PENDING, + System.currentTimeMillis(), URI.create("http://127.0.0.1")); + + final TargetInfoUpdateEvent targetInfoUpdatedEvent = eventListener.waitForEvent(TargetInfoUpdateEvent.class, 1, + TimeUnit.SECONDS); + assertThat(targetInfoUpdatedEvent).isNotNull(); + assertThat(targetInfoUpdatedEvent.getEntity().getTarget().getId()).isEqualTo(createdTarget.getId()); + } + + @Test + @Description("Verifies that the target deleted event is published when a target has been deleted") + public void targetDeletedEventIsPublished() throws InterruptedException { + final Target createdTarget = targetManagement.createTarget(entityFactory.generateTarget("12345")); + + targetManagement.deleteTargets(createdTarget.getId()); + + final TargetDeletedEvent targetDeletedEvent = eventListener.waitForEvent(TargetDeletedEvent.class, 1, + TimeUnit.SECONDS); + assertThat(targetDeletedEvent).isNotNull(); + assertThat(targetDeletedEvent.getTargetId()).isEqualTo(createdTarget.getId()); + } + + @Test + @Description("Verifies that the distribution set created event is published when a distribution set has been created") + public void distributionSetCreatedEventIsPublished() throws InterruptedException { + final DistributionSet generateDistributionSet = entityFactory.generateDistributionSet(); + generateDistributionSet.setName("dsEventTest"); + generateDistributionSet.setVersion("1"); + final DistributionSet createDistributionSet = distributionSetManagement + .createDistributionSet(generateDistributionSet); + + final DistributionCreatedEvent dsCreatedEvent = eventListener.waitForEvent(DistributionCreatedEvent.class, 1, + TimeUnit.SECONDS); + assertThat(dsCreatedEvent).isNotNull(); + assertThat(dsCreatedEvent.getEntity().getId()).isEqualTo(createDistributionSet.getId()); + } + + @Test + @Description("Verifies that the distribution set deleted event is published when a distribution set has been deleted") + public void distributionSetDeletedEventIsPublished() throws InterruptedException { + + final DistributionSet generateDistributionSet = entityFactory.generateDistributionSet(); + generateDistributionSet.setName("dsEventTest"); + generateDistributionSet.setVersion("1"); + final DistributionSet createDistributionSet = distributionSetManagement + .createDistributionSet(generateDistributionSet); + + distributionSetManagement.deleteDistributionSet(createDistributionSet); + + final DistributionDeletedEvent dsDeletedEvent = eventListener.waitForEvent(DistributionDeletedEvent.class, 1, + TimeUnit.SECONDS); + assertThat(dsDeletedEvent).isNotNull(); + assertThat(dsDeletedEvent.getDistributionSetId()).isEqualTo(createDistributionSet.getId()); + } + + private class MyEventListener { + + private final BlockingQueue queue = new LinkedBlockingQueue<>(); + + @Subscribe + public void onEvent(final Event event) { + queue.offer(event); + } + + public T waitForEvent(final Class eventType, final long timeout, final TimeUnit timeUnit) + throws InterruptedException { + Event event = null; + while ((event = queue.poll(timeout, timeUnit)) != null) { + if (event.getClass().isAssignableFrom(eventType)) { + return (T) event; + } + } + Assertions.fail("Missing event " + eventType + " within timeout " + timeout + " " + timeUnit); + return null; + } + } + +} diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index 7946532a3..6bef7a794 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -108,7 +108,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable visibleItemIds = (List) getVisibleItemIds(); // refresh the details tabs only if selected ds is updated @@ -219,10 +219,10 @@ public class DistributionSetTable extends AbstractNamedVersionTable showMetadataDetails(((DistributionSetIdName) itemId).getId())); + manageMetaDataBtn + .addClickListener(event -> showMetadataDetails(((DistributionSetIdName) itemId).getId())); return manageMetaDataBtn; } }); } - @Override protected List getTableVisibleColumns() { @@ -541,7 +541,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable events) { + private void onDistributionDeleteEvent(final List events) { final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); final List visibleItemIds = (List) getVisibleItemIds(); boolean shouldRefreshDs = false; for (final DistributionDeletedEvent deletedEvent : events) { - Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); - for (Long dsId : distributionSetIDs) { - final DistributionSetIdName targetIdName = new DistributionSetIdName(dsId, null, null); - if (visibleItemIds.contains(targetIdName)) { - dsContainer.removeItem(targetIdName); - } else { - shouldRefreshDs = true; - } + final Long distributionSetId = deletedEvent.getDistributionSetId(); + final DistributionSetIdName targetIdName = new DistributionSetIdName(distributionSetId, null, null); + if (visibleItemIds.contains(targetIdName)) { + dsContainer.removeItem(targetIdName); + } else { + shouldRefreshDs = true; } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index ff1edafc8..7609f71ef 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -93,16 +93,16 @@ public class DistributionTable extends AbstractNamedVersionTable) events); } else if (DistributionCreatedEvent.class.isInstance(firstEvent) && ((DistributionCreatedEvent) firstEvent).getEntity().isComplete()) { - refreshDistributions(); - } + refreshDistributions(); + } } @@ -137,12 +137,12 @@ public class DistributionTable extends AbstractNamedVersionTable visibleItemIds = (List) getVisibleItemIds(); // refresh the details tabs only if selected ds is updated - // refresh the details tabs only if selected ds is updated + // refresh the details tabs only if selected ds is updated if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) { // update table row+details layout eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, ds)); } else if (visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent()) { - //update the name/version details visible in table + // update the name/version details visible in table UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); } } @@ -261,27 +261,26 @@ public class DistributionTable extends AbstractNamedVersionTable showMetadataDetails(itemId)); - iconLayout.addComponent((Button)getPinButton(itemId)); + iconLayout.addComponent((Button) getPinButton(itemId)); iconLayout.addComponent(manageMetaDataBtn); return iconLayout; } - + }); } - - + private String getNameAndVerion(final Object itemId) { final Item item = getItem(itemId); final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue(); return name + "." + version; } - - private Button createManageMetadataButton(String nameVersionStr) { + + private Button createManageMetadataButton(final String nameVersionStr) { final Button manageMetadataBtn = SPUIComponentProvider.getButton( SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false, FontAwesome.LIST_ALT, SPUIButtonStyleSmallNoBorder.class); @@ -313,9 +312,9 @@ public class DistributionTable extends AbstractNamedVersionTable events) { + private void onDistributionDeleteEvent(final List events) { final LazyQueryContainer dsContainer = (LazyQueryContainer) getContainerDataSource(); final List visibleItemIds = (List) getVisibleItemIds(); boolean shouldRefreshDs = false; for (final DistributionDeletedEvent deletedEvent : events) { - Long[] distributionSetIDs = deletedEvent.getDistributionSetIDs(); - for (Long dsId : distributionSetIDs) { - final DistributionSetIdName targetIdName = new DistributionSetIdName(dsId, null, null); - if (visibleItemIds.contains(targetIdName)) { - dsContainer.removeItem(targetIdName); - } else { - shouldRefreshDs = true; - } + final Long distributionSetId = deletedEvent.getDistributionSetId(); + final DistributionSetIdName targetIdName = new DistributionSetIdName(distributionSetId, null, null); + if (visibleItemIds.contains(targetIdName)) { + dsContainer.removeItem(targetIdName); + } else { + shouldRefreshDs = true; } } From b8bc46d2994f9477ac6f7963811ed7fae0b9af84 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Mon, 1 Aug 2016 15:34:00 +0200 Subject: [PATCH 055/118] Add JavaDoc Signed-off-by: Melanie Retter --- .../HawkbitErrorNotificationMessage.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitErrorNotificationMessage.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitErrorNotificationMessage.java index e7199c04f..29bf822a8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitErrorNotificationMessage.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitErrorNotificationMessage.java @@ -14,17 +14,24 @@ import com.vaadin.shared.Position; import com.vaadin.ui.Notification; /** - * Notification message component. + * Notification message component for displaying errors in the UI. */ public class HawkbitErrorNotificationMessage extends Notification { - /** - * ID. - */ private static final long serialVersionUID = -6512576924243195753L; /** - * Constructor. + * Constructor of HawkbitErrorNotificationMessage + * + * @param style + * style of the notification message + * @param caption + * caption of the notification message + * @param description + * text which is displayed in the notification + * @param autoClose + * boolean if notification is closed after random click (true) or + * closed by clicking on the notification (false) */ public HawkbitErrorNotificationMessage(final String style, final String caption, final String description, final boolean autoClose) { From 046ec2b2ec0f0348487e9a5f9b492e84d4f61e51 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 1 Aug 2016 17:22:21 +0200 Subject: [PATCH 056/118] add preauthorize to system management Signed-off-by: Michael Hirsch --- .../hawkbit/repository/SystemManagement.java | 5 +++++ .../test/util/WithSpringAuthorityRule.java | 21 +++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index a44b13d92..e30009258 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -61,6 +61,9 @@ public interface SystemManagement { /** * @return {@link TenantMetaData} of {@link TenantAware#getCurrentTenant()} */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.HAS_AUTH_READ_TARGET + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantMetaData getTenantMetadata(); /** @@ -77,6 +80,7 @@ public interface SystemManagement { * to retrieve data for * @return {@link TenantMetaData} of given tenant */ + @PreAuthorize(SpringEvalExpressions.IS_SYSTEM_CODE) TenantMetaData getTenantMetadata(@NotNull String tenant); /** @@ -86,6 +90,7 @@ public interface SystemManagement { * to update * @return updated {@link TenantMetaData} entity */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantMetaData updateTenantMetadata(@NotNull TenantMetaData metaData); } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithSpringAuthorityRule.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithSpringAuthorityRule.java index a2bc90555..357ec5f69 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithSpringAuthorityRule.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithSpringAuthorityRule.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.concurrent.Callable; import org.eclipse.hawkbit.im.authentication.SpPermission; +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.repository.jpa.model.helper.SystemManagementHolder; import org.junit.rules.TestRule; @@ -56,10 +57,10 @@ public class WithSpringAuthorityRule implements TestRule { annotation = description.getTestClass().getAnnotation(WithUser.class); } if (annotation != null) { - setSecurityContext(annotation); if (annotation.autoCreateTenant()) { - SystemManagementHolder.getInstance().getSystemManagement().getTenantMetadata(annotation.tenantId()); + createTenant(annotation.tenantId()); } + setSecurityContext(annotation); } return oldContext; } @@ -158,7 +159,7 @@ public class WithSpringAuthorityRule implements TestRule { final SecurityContext oldContext = SecurityContextHolder.getContext(); setSecurityContext(withUser); if (withUser.autoCreateTenant()) { - SystemManagementHolder.getInstance().getSystemManagement().getTenantMetadata(withUser.tenantId()); + createTenant(withUser.tenantId()); } try { return callable.call(); @@ -166,6 +167,18 @@ public class WithSpringAuthorityRule implements TestRule { after(oldContext); } } + + private void createTenant(final String tenantId) throws Exception { + final SecurityContext oldContext = SecurityContextHolder.getContext(); + setSecurityContext(privilegedUser()); + try + { + SystemManagementHolder.getInstance().getSystemManagement().getTenantMetadata(tenantId); + }finally + { + after(oldContext); + } + } public static WithUser withUser(final String principal, final String... authorities) { return withUserAndTenant(principal, "default", true, true, authorities); @@ -254,7 +267,7 @@ public class WithSpringAuthorityRule implements TestRule { @Override public String[] authorities() { - return new String[] { "ROLE_CONTROLLER" }; + return new String[] { "ROLE_CONTROLLER", "ROLE_SYSTEM_CODE" }; } @Override From 1bf91372ae63d98a5d5f176ad31c449a2bff1bba Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 1 Aug 2016 17:51:34 +0200 Subject: [PATCH 057/118] Added the javadoc. --- .../repository/jpa/model/EventAwareEntity.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java index 1c6f217c9..95a14a979 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java @@ -12,9 +12,21 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; public interface EventAwareEntity { + /** + * Fired for the Entity creation. + * @param descriptorEvent + */ void fireCreateEvent(DescriptorEvent descriptorEvent); + /** + * Fired for the Entity updation. + * @param descriptorEvent + */ void fireUpdateEvent(DescriptorEvent descriptorEvent); + /** + * Fired for the Entity deletion. + * @param descriptorEvent + */ void fireDeleteEvent(DescriptorEvent descriptorEvent); } From fc4747083ca32a40746f5dd689c3fea194588221 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 2 Aug 2016 12:51:08 +0200 Subject: [PATCH 058/118] Use system role where necessary to invoke the getTenantMetadata method Signed-off-by: Michael Hirsch --- .../SecurityManagedConfiguration.java | 22 ++++++--- .../rest/resource/DdiRootControllerTest.java | 47 +++++++++--------- .../resource/MgmtDistributionSetResource.java | 9 +++- .../repository/jpa/SystemManagementTest.java | 48 ++++++++----------- 4 files changed, 66 insertions(+), 60 deletions(-) diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java index 1e4dbfb27..91d707c67 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java @@ -290,6 +290,9 @@ public class SecurityManagedConfiguration { @Autowired private SecurityProperties springSecurityProperties; + @Autowired + private SystemSecurityContext systemSecurityContext; + @Override protected void configure(final HttpSecurity http) throws Exception { @@ -318,9 +321,8 @@ public class SecurityManagedConfiguration { userAuthenticationFilter.destroy(); } }, RequestHeaderAuthenticationFilter.class) - .addFilterAfter( - new AuthenticationSuccessTenantMetadataCreationFilter(tenantAware, systemManagement), - SessionManagementFilter.class) + .addFilterAfter(new AuthenticationSuccessTenantMetadataCreationFilter(tenantAware, systemManagement, + systemSecurityContext), SessionManagementFilter.class) .authorizeRequests().anyRequest().authenticated() .antMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/**") .hasAnyAuthority(SpPermission.SYSTEM_ADMIN); @@ -522,6 +524,9 @@ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends @Autowired private SystemManagement systemManagement; + @Autowired + private SystemSecurityContext systemSecurityContext; + @Override public void onAuthenticationSuccess(final Authentication authentication) throws Exception { @@ -536,7 +541,9 @@ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends // LoginView. This needs to be changed with the update of // vaadin4spring 0.0.7 because it // has been fixed. - systemManagement.getTenantMetadata("DEFAULT"); + final String defaultTenant = "DEFAULT"; + systemSecurityContext.runAsSystemAsTenant(() -> systemManagement.getTenantMetadata(defaultTenant), + defaultTenant); } super.onAuthenticationSuccess(authentication); @@ -550,11 +557,13 @@ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter { private final TenantAware tenantAware; private final SystemManagement systemManagement; + private final SystemSecurityContext systemSecurityContext; AuthenticationSuccessTenantMetadataCreationFilter(final TenantAware tenantAware, - final SystemManagement systemManagement) { + final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext) { this.tenantAware = tenantAware; this.systemManagement = systemManagement; + this.systemSecurityContext = systemSecurityContext; } @Override @@ -569,7 +578,8 @@ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter { final String currentTenant = tenantAware.getCurrentTenant(); if (currentTenant != null) { // lazy initialize tenant meta data after successful authentication - systemManagement.getTenantMetadata(currentTenant); + systemSecurityContext.runAsSystemAsTenant(() -> systemManagement.getTenantMetadata(currentTenant), + currentTenant); } chain.doFilter(request, response); diff --git a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java index 31ec37c58..ba5e3d2f6 100644 --- a/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java +++ b/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java @@ -8,6 +8,10 @@ */ package org.eclipse.hawkbit.ddi.rest.resource; +import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.CONTROLLER_ROLE; +import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS; +import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION; +import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.SYSTEM_ROLE; import static org.fest.assertions.api.Assertions.assertThat; import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.Matchers.startsWith; @@ -23,7 +27,6 @@ import java.util.ArrayList; import java.util.List; import org.eclipse.hawkbit.im.authentication.SpPermission; -import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; @@ -57,7 +60,8 @@ public class DdiRootControllerTest extends AbstractRestIntegrationTestWithMongoD @Test @Description("Ensures that targets cannot be created e.g. in plug'n play scenarios when tenant does not exists but can be created if the tenant exists.") - @WithUser(tenantId = "tenantDoesNotExists", allSpPermissions = true, authorities = "ROLE_CONTROLLER", autoCreateTenant = false) + @WithUser(tenantId = "tenantDoesNotExists", allSpPermissions = true, authorities = { CONTROLLER_ROLE, + SYSTEM_ROLE }, autoCreateTenant = false) public void targetCannotBeRegisteredIfTenantDoesNotExistsButWhenExists() throws Exception { mvc.perform(get("/default-tenant/", tenantAware.getCurrentTenant())).andDo(MockMvcResultPrinter.print()) @@ -91,13 +95,11 @@ public class DdiRootControllerTest extends AbstractRestIntegrationTestWithMongoD // make a poll, audit information should not be changed, run as // controller principal! - securityRule.runAs( - WithSpringAuthorityRule.withUser("controller", SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS), () -> { - mvc.perform( - get("/{tenant}/controller/v1/" + knownTargetControllerId, tenantAware.getCurrentTenant())) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); - return null; - }); + securityRule.runAs(WithSpringAuthorityRule.withUser("controller", CONTROLLER_ROLE_ANONYMOUS), () -> { + mvc.perform(get("/{tenant}/controller/v1/" + knownTargetControllerId, tenantAware.getCurrentTenant())) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()); + return null; + }); // verify that audit information has not changed final Target targetVerify = targetManagement.findTargetByControllerID(knownTargetControllerId); @@ -143,22 +145,19 @@ public class DdiRootControllerTest extends AbstractRestIntegrationTestWithMongoD @Description("Ensures that tenant specific polling time, which is saved in the db, is delivered to the controller.") @WithUser(principal = "knownpricipal", allSpPermissions = false) public void pollWithModifiedGloablPollingTime() throws Exception { - securityRule.runAs( - WithSpringAuthorityRule.withUser("tenantadmin", SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION), - () -> { - tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL, - "00:02:00"); - return null; - }); + securityRule.runAs(WithSpringAuthorityRule.withUser("tenantadmin", HAS_AUTH_TENANT_CONFIGURATION), () -> { + tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.POLLING_TIME_INTERVAL, + "00:02:00"); + return null; + }); - securityRule.runAs( - WithSpringAuthorityRule.withUser("controller", SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS), () -> { - mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())) - .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) - .andExpect(content().contentType(MediaTypes.HAL_JSON)) - .andExpect(jsonPath("$config.polling.sleep", equalTo("00:02:00"))); - return null; - }); + securityRule.runAs(WithSpringAuthorityRule.withUser("controller", CONTROLLER_ROLE_ANONYMOUS), () -> { + mvc.perform(get("/{tenant}/controller/v1/4711", tenantAware.getCurrentTenant())) + .andDo(MockMvcResultPrinter.print()).andExpect(status().isOk()) + .andExpect(content().contentType(MediaTypes.HAL_JSON)) + .andExpect(jsonPath("$config.polling.sleep", equalTo("00:02:00"))); + return null; + }); } @Test diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java index e99a33c5f..e872e0221 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java @@ -39,6 +39,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetWithActionType; +import org.eclipse.hawkbit.security.SystemSecurityContext; import org.eclipse.hawkbit.tenancy.TenantAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -81,6 +82,9 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi { @Autowired private DistributionSetManagement distributionSetManagement; + @Autowired + private SystemSecurityContext systemSecurityContext; + @Override public ResponseEntity> getDistributionSets( @RequestParam(value = MgmtRestConstants.REQUEST_PARAMETER_PAGING_OFFSET, defaultValue = MgmtRestConstants.REQUEST_PARAMETER_PAGING_DEFAULT_OFFSET) final int pagingOffsetParam, @@ -119,8 +123,9 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi { LOG.debug("creating {} distribution sets", sets.size()); // set default Ds type if ds type is null - sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(this.systemManagement - .getTenantMetadata(this.currentTenant.getCurrentTenant()).getDefaultDsType().getKey())); + final String defaultDsKey = systemSecurityContext.runAsSystem(() -> this.systemManagement + .getTenantMetadata(this.currentTenant.getCurrentTenant()).getDefaultDsType().getKey()); + sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(defaultDsKey)); final Iterable createdDSets = this.distributionSetManagement .createDistributionSets(MgmtDistributionSetMapper.dsFromRequest(sets, this.softwareManagement, diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SystemManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SystemManagementTest.java index a9f004a73..ac2b30d23 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SystemManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/SystemManagementTest.java @@ -14,10 +14,10 @@ import java.io.ByteArrayInputStream; import java.util.List; import java.util.Random; +import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.repository.jpa.model.JpaSoftwareModule; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.repository.report.model.TenantUsage; import org.eclipse.hawkbit.repository.test.util.WithSpringAuthorityRule; import org.junit.Test; @@ -30,15 +30,6 @@ import ru.yandex.qatools.allure.annotations.Stories; @Stories("System Management") public class SystemManagementTest extends AbstractJpaIntegrationTestWithMongoDB { - @Test - @Description("Ensures that you can create a tenant without setting the necessary security context which holds a current tenant") - public void createInitialTenantWithoutSecurityContext() { - securityRule.clear(); - final String tenantToBeCreated = "newTenantToCreate"; - final TenantMetaData tenantMetadata = systemManagement.getTenantMetadata(tenantToBeCreated); - assertThat(tenantMetadata).isNotNull(); - } - @Test @Description("Ensures that findTenants returns all tenants and not only restricted to the tenant which currently is logged in") public void findTenantsReturnsAllTenantsNotOnlyWhichLoggedIn() throws Exception { @@ -109,26 +100,27 @@ public class SystemManagementTest extends AbstractJpaIntegrationTestWithMongoDB for (int i = 0; i < tenants; i++) { final String tenantname = "tenant" + i; - securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("bumlux", tenantname), () -> { - systemManagement.getTenantMetadata(tenantname); - if (artifactSize > 0) { - createTestArtifact(random); - createDeletedTestArtifact(random); - } - if (targets > 0) { - final List createdTargets = createTestTargets(targets); - if (updates > 0) { - for (int x = 0; x < updates; x++) { - final DistributionSet ds = testdataFactory.createDistributionSet("to be deployed" + x, - true); - - deploymentManagement.assignDistributionSet(ds, createdTargets); + securityRule.runAs(WithSpringAuthorityRule.withUserAndTenant("bumlux", tenantname, true, true, + SpringEvalExpressions.SYSTEM_ROLE), () -> { + systemManagement.getTenantMetadata(tenantname); + if (artifactSize > 0) { + createTestArtifact(random); + createDeletedTestArtifact(random); } - } - } + if (targets > 0) { + final List createdTargets = createTestTargets(targets); + if (updates > 0) { + for (int x = 0; x < updates; x++) { + final DistributionSet ds = testdataFactory + .createDistributionSet("to be deployed" + x, true); - return null; - }); + deploymentManagement.assignDistributionSet(ds, createdTargets); + } + } + } + + return null; + }); } return random; From 9c75ae308d4d96f6ed0842d4e6ae3a64376f6b28 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 2 Aug 2016 13:01:31 +0200 Subject: [PATCH 059/118] reduce usage of getTenantMetadata(String) Signed-off-by: Michael Hirsch --- .../SecurityManagedConfiguration.java | 25 +++++++------------ .../resource/MgmtDistributionSetResource.java | 8 ++---- .../test/util/AbstractIntegrationTest.java | 5 +++- 3 files changed, 15 insertions(+), 23 deletions(-) diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java index 91d707c67..e05bdb7f1 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java @@ -321,7 +321,7 @@ public class SecurityManagedConfiguration { userAuthenticationFilter.destroy(); } }, RequestHeaderAuthenticationFilter.class) - .addFilterAfter(new AuthenticationSuccessTenantMetadataCreationFilter(tenantAware, systemManagement, + .addFilterAfter(new AuthenticationSuccessTenantMetadataCreationFilter(systemManagement, systemSecurityContext), SessionManagementFilter.class) .authorizeRequests().anyRequest().authenticated() .antMatchers(MgmtRestConstants.BASE_SYSTEM_MAPPING + "/admin/**") @@ -531,8 +531,8 @@ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends public void onAuthenticationSuccess(final Authentication authentication) throws Exception { if (authentication.getClass().equals(TenantUserPasswordAuthenticationToken.class)) { - systemManagement - .getTenantMetadata(((TenantUserPasswordAuthenticationToken) authentication).getTenant().toString()); + systemSecurityContext.runAsSystemAsTenant(() -> systemManagement.getTenantMetadata(), + ((TenantUserPasswordAuthenticationToken) authentication).getTenant().toString()); } else if (authentication.getClass().equals(UsernamePasswordAuthenticationToken.class)) { // TODO: vaadin4spring-ext-security does not give us the // fullyAuthenticatedToken @@ -542,8 +542,7 @@ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends // vaadin4spring 0.0.7 because it // has been fixed. final String defaultTenant = "DEFAULT"; - systemSecurityContext.runAsSystemAsTenant(() -> systemManagement.getTenantMetadata(defaultTenant), - defaultTenant); + systemSecurityContext.runAsSystemAsTenant(() -> systemManagement.getTenantMetadata(), defaultTenant); } super.onAuthenticationSuccess(authentication); @@ -555,13 +554,11 @@ class TenantMetadataSavedRequestAwareVaadinAuthenticationSuccessHandler extends */ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter { - private final TenantAware tenantAware; private final SystemManagement systemManagement; private final SystemSecurityContext systemSecurityContext; - AuthenticationSuccessTenantMetadataCreationFilter(final TenantAware tenantAware, - final SystemManagement systemManagement, final SystemSecurityContext systemSecurityContext) { - this.tenantAware = tenantAware; + AuthenticationSuccessTenantMetadataCreationFilter(final SystemManagement systemManagement, + final SystemSecurityContext systemSecurityContext) { this.systemManagement = systemManagement; this.systemSecurityContext = systemSecurityContext; } @@ -575,14 +572,10 @@ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter { public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { - final String currentTenant = tenantAware.getCurrentTenant(); - if (currentTenant != null) { - // lazy initialize tenant meta data after successful authentication - systemSecurityContext.runAsSystemAsTenant(() -> systemManagement.getTenantMetadata(currentTenant), - currentTenant); - } - + // lazy initialize tenant meta data after successful authentication + systemSecurityContext.runAsSystem(() -> systemManagement.getTenantMetadata()); chain.doFilter(request, response); + } @Override diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java index e872e0221..721995d88 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResource.java @@ -40,7 +40,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetWithActionType; 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; @@ -73,9 +72,6 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi { @Autowired private SystemManagement systemManagement; - @Autowired - private TenantAware currentTenant; - @Autowired private EntityFactory entityFactory; @@ -123,8 +119,8 @@ public class MgmtDistributionSetResource implements MgmtDistributionSetRestApi { LOG.debug("creating {} distribution sets", sets.size()); // set default Ds type if ds type is null - final String defaultDsKey = systemSecurityContext.runAsSystem(() -> this.systemManagement - .getTenantMetadata(this.currentTenant.getCurrentTenant()).getDefaultDsType().getKey()); + final String defaultDsKey = systemSecurityContext + .runAsSystem(() -> this.systemManagement.getTenantMetadata().getDefaultDsType().getKey()); sets.stream().filter(ds -> ds.getType() == null).forEach(ds -> ds.setType(defaultDsKey)); final Iterable createdDSets = this.distributionSetManagement diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index 3d09fabc3..c12a3b0b3 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -8,6 +8,9 @@ */ package org.eclipse.hawkbit.repository.test.util; +import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.CONTROLLER_ROLE; +import static org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions.SYSTEM_ROLE; + import org.eclipse.hawkbit.ExcludePathAwareShallowETagFilter; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ControllerManagement; @@ -58,7 +61,7 @@ import org.springframework.web.context.WebApplicationContext; @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration @ActiveProfiles({ "test" }) -@WithUser(principal = "bumlux", allSpPermissions = true, authorities = "ROLE_CONTROLLER") +@WithUser(principal = "bumlux", allSpPermissions = true, authorities = { CONTROLLER_ROLE, SYSTEM_ROLE }) @SpringApplicationConfiguration(classes = { TestConfiguration.class }) // destroy the context after each test class because otherwise we get problem // when context is From 041dd3bb7af7b6485c0602f61f3ad1bc23176465 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 2 Aug 2016 14:05:24 +0200 Subject: [PATCH 060/118] don't allow anonymous login on rest-api Signed-off-by: Michael Hirsch --- .../security/SecurityManagedConfiguration.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java index e05bdb7f1..e6eb1d159 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java @@ -73,6 +73,7 @@ import org.springframework.security.config.annotation.web.servlet.configuration. import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.access.intercept.FilterSecurityInterceptor; import org.springframework.security.web.authentication.AnonymousAuthenticationFilter; import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint; @@ -328,6 +329,7 @@ public class SecurityManagedConfiguration { .hasAnyAuthority(SpPermission.SYSTEM_ADMIN); httpSec.httpBasic().and().exceptionHandling().authenticationEntryPoint(basicAuthEntryPoint); + httpSec.anonymous().disable(); } } @@ -573,7 +575,10 @@ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter { throws IOException, ServletException { // lazy initialize tenant meta data after successful authentication - systemSecurityContext.runAsSystem(() -> systemManagement.getTenantMetadata()); + final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + if (authentication != null && authentication.isAuthenticated()) { + systemSecurityContext.runAsSystem(() -> systemManagement.getTenantMetadata()); + } chain.doFilter(request, response); } From 0854d023fb1654f41146c555bcc9c8fb553fd529 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Tue, 2 Aug 2016 18:32:44 +0200 Subject: [PATCH 061/118] Fixed the code for the create ds for deployment view and fixed the issue for delete metadata(getting optimistic lock exception) --- .../jpa/JpaDistributionSetManagement.java | 11 +++- .../management/dstable/DistributionTable.java | 57 ++++++++++--------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java index 8842a3507..e8e05a9e1 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDistributionSetManagement.java @@ -483,11 +483,13 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { if (distributionSetMetadataRepository.exists(metadata.getId())) { throwMetadataKeyAlreadyExists(metadata.getId().getKey()); } + + final DistributionSet latestDistributionSet = findDistributionSetById(metadata.getDistributionSet().getId()); // merge base distribution set so optLockRevision gets updated and audit // log written because // modifying metadata is modifying the base distribution set itself for // auditing purposes. - entityManager.merge((JpaDistributionSet) metadata.getDistributionSet()).setLastModifiedAt(0L); + entityManager.merge((JpaDistributionSet) latestDistributionSet).setLastModifiedAt(0L); return distributionSetMetadataRepository.save(metadata); } @@ -502,7 +504,7 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { for (final JpaDistributionSetMetadata distributionSetMetadata : metadata) { checkAndThrowAlreadyIfDistributionSetMetadataExists(distributionSetMetadata.getId()); } - metadata.forEach(m -> entityManager.merge((JpaDistributionSet) m.getDistributionSet()).setLastModifiedAt(0L)); + metadata.forEach(m -> entityManager.merge((JpaDistributionSet) findDistributionSetById(m.getDistributionSet().getId())).setLastModifiedAt(0L)); return new ArrayList<>( (Collection) distributionSetMetadataRepository.save(metadata)); @@ -518,7 +520,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { findOne(metadata.getDistributionSet(), metadata.getKey()); // touch it to update the lock revision because we are modifying the // DS indirectly - entityManager.merge((JpaDistributionSet) metadata.getDistributionSet()).setLastModifiedAt(0L); + final DistributionSet latestDistributionSet = findDistributionSetById(metadata.getDistributionSet().getId()); + entityManager.merge((JpaDistributionSet) latestDistributionSet).setLastModifiedAt(0L); return distributionSetMetadataRepository.save(metadata); } @@ -526,6 +529,8 @@ public class JpaDistributionSetManagement implements DistributionSetManagement { @Transactional(isolation = Isolation.READ_UNCOMMITTED) @Modifying public void deleteDistributionSetMetadata(final DistributionSet distributionSet, final String key) { + final DistributionSet latestDistributionSet = findDistributionSetById(distributionSet.getId()); + entityManager.merge((JpaDistributionSet) latestDistributionSet).setLastModifiedAt(0L); distributionSetMetadataRepository.delete(new DsMetadataCompositeKey(distributionSet, key)); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index 3ded0ed07..56fdd9114 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -21,6 +21,7 @@ import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SpPermissionChecker; import org.eclipse.hawkbit.repository.TargetManagement; +import org.eclipse.hawkbit.repository.eventbus.event.DistributionCreatedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionDeletedEvent; import org.eclipse.hawkbit.repository.eventbus.event.DistributionSetUpdateEvent; import org.eclipse.hawkbit.repository.model.DistributionSet; @@ -92,16 +93,16 @@ public class DistributionTable extends AbstractNamedVersionTable) events); - } + } else if (DistributionCreatedEvent.class.isInstance(firstEvent) + && ((DistributionCreatedEvent) firstEvent).getEntity().isComplete()) { + refreshDistributions(); + } } @EventBusListenerMethod(scope = EventScope.SESSION) void onEvents(final DistributionSetUpdateEvent event) { final DistributionSet ds = event.getEntity(); - + final List visibleItemIds = (List) getVisibleItemIds(); - - - final Boolean dsVisible = visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst().isPresent(); - - if((ds.isComplete() && !dsVisible) ){ + + final Boolean dsVisible = visibleItemIds.stream().filter(e -> e.getId().equals(ds.getId())).findFirst() + .isPresent(); + + if ((ds.isComplete() && !dsVisible)) { refreshDistributions(); - } - else if( (!ds.isComplete() && dsVisible)){ + } else if ((!ds.isComplete() && dsVisible)) { refreshDistributions(); - managementUIState.setLastSelectedDistribution(null); - } - else if(dsVisible){ + if (ds.getId().equals(managementUIState.getLastSelectedDsIdName().getId())) { + managementUIState.setLastSelectedDistribution(null); + managementUIState.setLastSelectedEntity(null); + } + + } else if (dsVisible) { UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); } final DistributionSetIdName lastSelectedDsIdName = managementUIState.getLastSelectedDsIdName(); - // refresh the details tabs only if selected ds is updated + // refresh the details tabs only if selected ds is updated if (lastSelectedDsIdName != null && lastSelectedDsIdName.getId().equals(ds.getId())) { // update table row+details layout eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.UPDATED_ENTITY, ds)); - } + } } /** @@ -271,22 +277,21 @@ public class DistributionTable extends AbstractNamedVersionTable showMetadataDetails(itemId)); - iconLayout.addComponent((Button)getPinButton(itemId)); + iconLayout.addComponent((Button) getPinButton(itemId)); iconLayout.addComponent(manageMetaDataBtn); return iconLayout; } - + }); } - - + private String getNameAndVerion(final Object itemId) { final Item item = getItem(itemId); final String name = (String) item.getItemProperty(SPUILabelDefinitions.VAR_NAME).getValue(); final String version = (String) item.getItemProperty(SPUILabelDefinitions.VAR_VERSION).getValue(); return name + "." + version; } - + private Button createManageMetadataButton(final String nameVersionStr) { final Button manageMetadataBtn = SPUIComponentProvider.getButton( SPUIComponentIdProvider.DS_TABLE_MANAGE_METADATA_ID + "." + nameVersionStr, "", "", null, false, @@ -319,9 +324,9 @@ public class DistributionTable extends AbstractNamedVersionTable Date: Wed, 3 Aug 2016 09:08:03 +0200 Subject: [PATCH 062/118] Add missing PreAuthorize annotation to secure methods and write unit test Signed-off-by: Michael Hirsch --- .../hawkbit-repository-api/pom.xml | 65 ++++++---- .../repository/ControllerManagement.java | 2 + .../repository/SoftwareManagement.java | 1 + ...gementMethodPreAuthorizeAnnotatedTest.java | 121 ++++++++++++++++++ .../repository/jpa/MethodSecurityUtil.java | 63 --------- .../im/authentication/SpPermission.java | 8 ++ 6 files changed, 170 insertions(+), 90 deletions(-) create mode 100644 hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java delete mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/MethodSecurityUtil.java diff --git a/hawkbit-repository/hawkbit-repository-api/pom.xml b/hawkbit-repository/hawkbit-repository-api/pom.xml index 050a9a070..cfd45998c 100644 --- a/hawkbit-repository/hawkbit-repository-api/pom.xml +++ b/hawkbit-repository/hawkbit-repository-api/pom.xml @@ -1,24 +1,16 @@ - + - 4.0.0 - - org.eclipse.hawkbit - hawkbit-repository - 0.2.0-SNAPSHOT - - hawkbit-repository-api - hawkBit :: Repository API - - + 4.0.0 + + org.eclipse.hawkbit + hawkbit-repository + 0.2.0-SNAPSHOT + + hawkbit-repository-api + hawkBit :: Repository API + + org.eclipse.hawkbit hawkbit-security-core @@ -36,14 +28,33 @@ cz.jirutka.rsql rsql-parser - + org.springframework.hateoas spring-hateoas - - org.springframework.boot - spring-boot-configuration-processor - true - - + + + + org.springframework.boot + spring-boot-configuration-processor + true + + + + + ru.yandex.qatools.allure + allure-junit-adaptor + test + + + org.easytesting + fest-assert-core + test + + + org.easytesting + fest-assert + test + + \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java index e5dcb8f74..f06621fd4 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/ControllerManagement.java @@ -183,6 +183,8 @@ public interface ControllerManagement { * @return the security context of the target, in case no target exists for * the given controllerId {@code null} is returned */ + @PreAuthorize(SpringEvalExpressions.IS_CONTROLLER + SpringEvalExpressions.HAS_AUTH_OR + + SpringEvalExpressions.HAS_AUTH_READ_TARGET_SEC_TOKEN) String getSecurityTokenByControllerId(@NotEmpty String controllerId); /** diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java index 0934e871e..bc3c50004 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SoftwareManagement.java @@ -340,6 +340,7 @@ public interface SoftwareManagement { * to search for * @return {@link List} of found {@link SoftwareModule}s */ + @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) List findSoftwareModulesById(@NotEmpty Collection ids); /** diff --git a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java new file mode 100644 index 000000000..1ccbb8bc5 --- /dev/null +++ b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java @@ -0,0 +1,121 @@ +/** + * 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; + +import static org.fest.assertions.Assertions.assertThat; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.regex.Pattern; + +import org.junit.Test; +import org.springframework.security.access.prepost.PreAuthorize; + +import ru.yandex.qatools.allure.annotations.Description; +import ru.yandex.qatools.allure.annotations.Features; +import ru.yandex.qatools.allure.annotations.Stories; + +@Features("Unit Tests - Repository") +@Stories("Security Test") +public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { + + private static final Set METHOD_SECURITY_EXCLUSION = new HashSet<>(); + + static { + METHOD_SECURITY_EXCLUSION.add(getMethod(SystemManagement.class, "currentTenant")); + } + + @Test + @Description("Verfies that repository methods are @PreAuthorize annotated") + public void repositoryManagementMethodsArePreAuthorizedAnnotated() + throws ClassNotFoundException, URISyntaxException, IOException { + final List> findInterfacesInPackage = findInterfacesInPackage(getClass().getPackage(), + Pattern.compile(".*Management")); + for (final Class interfaceToCheck : findInterfacesInPackage) { + assertDeclaredMethodsContainsPreAuthorizeAnnotaions(interfaceToCheck); + } + } + + /** + * asserts that the given methods are annotated with the + * {@link PreAuthorize} annotation for security. Inherited methods are not + * checked. The following methods are excluded due inherited from + * {@link Object}, like equals() or toString(). + * + * @param clazz + * the class to retrieve the public declared methods + */ + private static void assertDeclaredMethodsContainsPreAuthorizeAnnotaions(final Class clazz) { + final Method[] declaredMethods = clazz.getDeclaredMethods(); + for (final Method method : declaredMethods) { + if (!METHOD_SECURITY_EXCLUSION.contains(method) && !method.isSynthetic() + && Modifier.isPublic(method.getModifiers())) { + final PreAuthorize annotation = method.getAnnotation(PreAuthorize.class); + assertThat(annotation).as("The public method " + method.getName() + " in class " + clazz.getName() + + " is not annoated with @PreAuthorize, security leak?").isNotNull(); + } + } + } + + /** + * Finds all interfaces in a given packages which matches the given filter. + * + * @param p + * the package to search for interfaces in + * @param includeFilter + * the pattern which interfaces class names should be included + * @return a list of loaded interfaces in a specific package and matches the + * given filter + * @throws URISyntaxException + * @throws IOException + * @throws ClassNotFoundException + */ + private List> findInterfacesInPackage(final Package p, final Pattern includeFilter) + throws URISyntaxException, IOException, ClassNotFoundException { + final List> interfacesToReturn = new ArrayList<>(); + final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + final Enumeration resources = classLoader.getResources(p.getName().replace(".", "/")); + while (resources.hasMoreElements()) { + final File packageDirectory = new File(new URI(resources.nextElement().toString()).getPath()); + final File[] filesInPackage = packageDirectory.listFiles(); + for (final File classFile : filesInPackage) { + final String classNameWithExtension = classFile.getName(); + final int indexOfExtension = classNameWithExtension.indexOf(".class"); + if (indexOfExtension > 0) { + final String classNameWithoutExtension = classNameWithExtension.substring(0, indexOfExtension); + if (includeFilter.matcher(classNameWithoutExtension).matches()) { + final Class classInPackage = Class.forName(p.getName() + "." + classNameWithoutExtension); + if (classInPackage.isInterface()) { + interfacesToReturn.add(classInPackage); + } + } + } + } + } + return interfacesToReturn; + } + + private static Method getMethod(final Class clazz, final String methodName, final Class... parameterTypes) { + try { + return clazz.getMethod(methodName, parameterTypes); + } catch (NoSuchMethodException | SecurityException e) { + throw new RuntimeException(e.getMessage(), e); + } + } +} diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/MethodSecurityUtil.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/MethodSecurityUtil.java deleted file mode 100644 index 032289e87..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/MethodSecurityUtil.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * 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.jpa; - -import static org.fest.assertions.Assertions.assertThat; - -import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import java.util.HashSet; -import java.util.Set; - -import org.springframework.security.access.prepost.PreAuthorize; - -public class MethodSecurityUtil { - - private static final Set METHOD_SECURITY_EXCLUSION = new HashSet<>(); - - static { - METHOD_SECURITY_EXCLUSION.add("equals"); - METHOD_SECURITY_EXCLUSION.add("toString"); - METHOD_SECURITY_EXCLUSION.add("hashCode"); - METHOD_SECURITY_EXCLUSION.add("clone"); - METHOD_SECURITY_EXCLUSION.add("setEnvironment"); - // this method shouldn't be public on the DeploymentManagemeht but it is - METHOD_SECURITY_EXCLUSION.add("setOverrideObsoleteUpdateActions"); - METHOD_SECURITY_EXCLUSION.add("isOverrideObsoleteUpdateActions"); - // this method must be public accessible without security because it's - // necessary to acccess - // the security-token of a target without being authenticated because - // the security-token is - // the authentication process - // ControllerManagement#getSecurityTokenByControllerId() - METHOD_SECURITY_EXCLUSION.add("getSecurityTokenByControllerId"); - } - - /** - * asserts that the given methods are annotated with the - * {@link PreAuthorize} annotation for security. Inherited methods are not - * checked. The following methods are excluded due inherited from - * {@link Object}, like equals() or toString(). - * - * @param clazz - * the class to retrieve the public declared methods - */ - public static void assertDeclaredMethodsContainsPreAuthorizeAnnotaions(final Class clazz) { - final Method[] declaredMethods = clazz.getDeclaredMethods(); - for (final Method method : declaredMethods) { - if (!METHOD_SECURITY_EXCLUSION.contains(method.getName()) && !method.isSynthetic() - && Modifier.isPublic(method.getModifiers())) { - final PreAuthorize annotation = method.getAnnotation(PreAuthorize.class); - assertThat(annotation).as( - "The public method " + method.getName() + " is not annoated with @PreAuthorize, security leak?") - .isNotNull(); - } - } - } -} diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java index daf5f0dd9..783f27b7e 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/im/authentication/SpPermission.java @@ -290,6 +290,14 @@ public final class SpPermission { public static final String HAS_AUTH_READ_TARGET = HAS_AUTH_PREFIX + READ_TARGET + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + /** + * Spring security eval hasAuthority expression to check if spring + * context contains {@link SpPermission#READ_TARGET_SEC_TOKEN} or + * {@link #IS_SYSTEM_CODE}. + */ + public static final String HAS_AUTH_READ_TARGET_SEC_TOKEN = HAS_AUTH_PREFIX + READ_TARGET_SEC_TOKEN + + HAS_AUTH_SUFFIX + HAS_AUTH_OR + IS_SYSTEM_CODE; + /** * Spring security eval hasAuthority expression to check if spring * context contains {@link SpPermission#CREATE_TARGET} or From 2965c93083f315ee2e35c81b479173cd0c9e9542 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 3 Aug 2016 09:24:28 +0200 Subject: [PATCH 063/118] fix unit test Signed-off-by: Michael Hirsch --- ...gementMethodPreAuthorizeAnnotatedTest.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java index 1ccbb8bc5..8de225dcd 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java +++ b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java @@ -47,6 +47,8 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { throws ClassNotFoundException, URISyntaxException, IOException { final List> findInterfacesInPackage = findInterfacesInPackage(getClass().getPackage(), Pattern.compile(".*Management")); + + assertThat(findInterfacesInPackage).isNotEmpty(); for (final Class interfaceToCheck : findInterfacesInPackage) { assertDeclaredMethodsContainsPreAuthorizeAnnotaions(interfaceToCheck); } @@ -92,17 +94,21 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); final Enumeration resources = classLoader.getResources(p.getName().replace(".", "/")); while (resources.hasMoreElements()) { - final File packageDirectory = new File(new URI(resources.nextElement().toString()).getPath()); - final File[] filesInPackage = packageDirectory.listFiles(); - for (final File classFile : filesInPackage) { - final String classNameWithExtension = classFile.getName(); - final int indexOfExtension = classNameWithExtension.indexOf(".class"); - if (indexOfExtension > 0) { - final String classNameWithoutExtension = classNameWithExtension.substring(0, indexOfExtension); - if (includeFilter.matcher(classNameWithoutExtension).matches()) { - final Class classInPackage = Class.forName(p.getName() + "." + classNameWithoutExtension); - if (classInPackage.isInterface()) { - interfacesToReturn.add(classInPackage); + final String uriPath = new URI(resources.nextElement().toString()).getPath(); + if (uriPath != null) { + final File packageDirectory = new File(uriPath); + final File[] filesInPackage = packageDirectory.listFiles(); + for (final File classFile : filesInPackage) { + final String classNameWithExtension = classFile.getName(); + final int indexOfExtension = classNameWithExtension.indexOf(".class"); + if (indexOfExtension > 0) { + final String classNameWithoutExtension = classNameWithExtension.substring(0, indexOfExtension); + if (includeFilter.matcher(classNameWithoutExtension).matches()) { + final Class classInPackage = Class + .forName(p.getName() + "." + classNameWithoutExtension); + if (classInPackage.isInterface()) { + interfacesToReturn.add(classInPackage); + } } } } From fca7ecbce4fe2bb0eb831e1eb7ce1974fe1be29a Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 3 Aug 2016 09:32:10 +0200 Subject: [PATCH 064/118] fix unit test Signed-off-by: Michael Hirsch --- ...gementMethodPreAuthorizeAnnotatedTest.java | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java index 8de225dcd..53b691c09 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java +++ b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java @@ -14,7 +14,6 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; @@ -94,21 +93,17 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); final Enumeration resources = classLoader.getResources(p.getName().replace(".", "/")); while (resources.hasMoreElements()) { - final String uriPath = new URI(resources.nextElement().toString()).getPath(); - if (uriPath != null) { - final File packageDirectory = new File(uriPath); - final File[] filesInPackage = packageDirectory.listFiles(); - for (final File classFile : filesInPackage) { - final String classNameWithExtension = classFile.getName(); - final int indexOfExtension = classNameWithExtension.indexOf(".class"); - if (indexOfExtension > 0) { - final String classNameWithoutExtension = classNameWithExtension.substring(0, indexOfExtension); - if (includeFilter.matcher(classNameWithoutExtension).matches()) { - final Class classInPackage = Class - .forName(p.getName() + "." + classNameWithoutExtension); - if (classInPackage.isInterface()) { - interfacesToReturn.add(classInPackage); - } + final File packageDirectory = new File(resources.nextElement().getFile()); + final File[] filesInPackage = packageDirectory.listFiles(); + for (final File classFile : filesInPackage) { + final String classNameWithExtension = classFile.getName(); + final int indexOfExtension = classNameWithExtension.indexOf(".class"); + if (indexOfExtension > 0) { + final String classNameWithoutExtension = classNameWithExtension.substring(0, indexOfExtension); + if (includeFilter.matcher(classNameWithoutExtension).matches()) { + final Class classInPackage = Class.forName(p.getName() + "." + classNameWithoutExtension); + if (classInPackage.isInterface()) { + interfacesToReturn.add(classInPackage); } } } From cd39f32c215fa93c0884f29d020dea1b4815872b Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 3 Aug 2016 09:49:57 +0200 Subject: [PATCH 065/118] fix unit test Signed-off-by: Michael Hirsch --- ...gementMethodPreAuthorizeAnnotatedTest.java | 44 ++++++++++++------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java index 53b691c09..3f77a2f38 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java +++ b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java @@ -14,6 +14,7 @@ import java.io.File; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.util.ArrayList; @@ -51,6 +52,10 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { for (final Class interfaceToCheck : findInterfacesInPackage) { assertDeclaredMethodsContainsPreAuthorizeAnnotaions(interfaceToCheck); } + + // all exclusion should be used, otherwise the method exlusion should be + // cleaned up again + assertThat(METHOD_SECURITY_EXCLUSION).isEmpty(); } /** @@ -65,12 +70,15 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { private static void assertDeclaredMethodsContainsPreAuthorizeAnnotaions(final Class clazz) { final Method[] declaredMethods = clazz.getDeclaredMethods(); for (final Method method : declaredMethods) { - if (!METHOD_SECURITY_EXCLUSION.contains(method) && !method.isSynthetic() - && Modifier.isPublic(method.getModifiers())) { - final PreAuthorize annotation = method.getAnnotation(PreAuthorize.class); - assertThat(annotation).as("The public method " + method.getName() + " in class " + clazz.getName() - + " is not annoated with @PreAuthorize, security leak?").isNotNull(); + final boolean methodExcluded = METHOD_SECURITY_EXCLUSION.contains(method); + if (methodExcluded || method.isSynthetic() || Modifier.isPublic(method.getModifiers())) { + // skip method because it should be excluded + METHOD_SECURITY_EXCLUSION.remove(method); + continue; } + final PreAuthorize annotation = method.getAnnotation(PreAuthorize.class); + assertThat(annotation).as("The public method " + method.getName() + " in class " + clazz.getName() + + " is not annoated with @PreAuthorize, security leak?").isNotNull(); } } @@ -93,17 +101,21 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); final Enumeration resources = classLoader.getResources(p.getName().replace(".", "/")); while (resources.hasMoreElements()) { - final File packageDirectory = new File(resources.nextElement().getFile()); - final File[] filesInPackage = packageDirectory.listFiles(); - for (final File classFile : filesInPackage) { - final String classNameWithExtension = classFile.getName(); - final int indexOfExtension = classNameWithExtension.indexOf(".class"); - if (indexOfExtension > 0) { - final String classNameWithoutExtension = classNameWithExtension.substring(0, indexOfExtension); - if (includeFilter.matcher(classNameWithoutExtension).matches()) { - final Class classInPackage = Class.forName(p.getName() + "." + classNameWithoutExtension); - if (classInPackage.isInterface()) { - interfacesToReturn.add(classInPackage); + final String uriPath = new URI(resources.nextElement().toString()).getPath(); + if (uriPath != null) { + final File packageDirectory = new File(uriPath); + final File[] filesInPackage = packageDirectory.listFiles(); + for (final File classFile : filesInPackage) { + final String classNameWithExtension = classFile.getName(); + final int indexOfExtension = classNameWithExtension.indexOf(".class"); + if (indexOfExtension > 0) { + final String classNameWithoutExtension = classNameWithExtension.substring(0, indexOfExtension); + if (includeFilter.matcher(classNameWithoutExtension).matches()) { + final Class classInPackage = Class + .forName(p.getName() + "." + classNameWithoutExtension); + if (classInPackage.isInterface()) { + interfacesToReturn.add(classInPackage); + } } } } From 43f71cc976e47127765a0d35e9bcf47961f56a1c Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Wed, 3 Aug 2016 17:31:46 +0200 Subject: [PATCH 066/118] Catch RuntimeException and handle with Vaadin error handler Signed-off-by: Jonathan Philip Knoblauch --- .../management/targettable/BulkUploadHandler.java | 15 ++++++++++----- .../targettable/TargetBulkUpdateWindowLayout.java | 9 +++++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index ee062493e..0dcaedc99 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -22,6 +22,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.concurrent.Executor; import org.eclipse.hawkbit.repository.DeploymentManagement; @@ -56,6 +57,7 @@ import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.ProgressBar; import com.vaadin.ui.TextArea; +import com.vaadin.ui.UI; import com.vaadin.ui.Upload; import com.vaadin.ui.Upload.FailedEvent; import com.vaadin.ui.Upload.FailedListener; @@ -99,7 +101,7 @@ public class BulkUploadHandler extends CustomComponent private final transient Executor executor; private transient EventBus.SessionEventBus eventBus; - final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout; + TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout; private transient EntityFactory entityFactory; @@ -139,7 +141,7 @@ public class BulkUploadHandler extends CustomComponent public void buildLayout() { final HorizontalLayout horizontalLayout = new HorizontalLayout(); upload = new Upload(); - upload.setEnabled(false); + upload.setEnabled(true); upload.setButtonCaption("Bulk Upload"); upload.setReceiver(this); upload.setImmediate(true); @@ -178,6 +180,7 @@ public class BulkUploadHandler extends CustomComponent } class UploadAsync implements Runnable { + final SucceededEvent event; /** @@ -193,7 +196,6 @@ public class BulkUploadHandler extends CustomComponent if (tempFile == null) { return; } - try (InputStream tempStream = new FileInputStream(tempFile)) { readFileStream(tempStream); } catch (final FileNotFoundException e) { @@ -201,12 +203,11 @@ public class BulkUploadHandler extends CustomComponent } catch (final IOException e) { LOG.error("Error while opening temorary file ", e); } - } private void readFileStream(final InputStream tempStream) { String line; - try (BufferedReader reader = new BufferedReader( + try (final BufferedReader reader = new BufferedReader( new InputStreamReader(tempStream, Charset.defaultCharset()))) { LOG.info("Bulk file upload started"); long innerCounter = 0; @@ -229,6 +230,10 @@ public class BulkUploadHandler extends CustomComponent managementUIState.getTargetTableFilters().getBulkUpload().getTargetsCreated().clear(); } catch (final IOException e) { LOG.error("Error reading file {}", tempFile.getName(), e); + } catch (final RuntimeException e) { + Optional.ofNullable(UI.getCurrent()).ifPresent( + error -> UI.getCurrent().getErrorHandler().error(new ConnectorErrorEvent(upload, e))); + targetBulkUpdateWindowLayout.closePopupAfterFailureAndRefresh(); } finally { resetCounts(); deleteFile(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java index e806e4f30..5cd053ee8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java @@ -239,6 +239,15 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { eventBus.publish(this, BulkUploadPopupEvent.CLOSED); } + /** + * Close and refresh this component. + */ + public void closePopupAfterFailureAndRefresh() { + closePopup(); + destroy(); + init(); + } + /** * @return */ From 5beb10b8db7f40db20f5761b64f296478fb3ea71 Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Wed, 3 Aug 2016 17:51:52 +0200 Subject: [PATCH 067/118] Removed uiNotification Signed-off-by: Jonathan Philip Knoblauch --- .../ui/management/targettable/BulkUploadHandler.java | 9 ++------- .../targettable/TargetBulkUpdateWindowLayout.java | 2 +- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index 0dcaedc99..fb8a27a7a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -44,7 +44,6 @@ import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SpringContextHelper; -import org.eclipse.hawkbit.ui.utils.UINotification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vaadin.spring.events.EventBus; @@ -85,8 +84,6 @@ public class BulkUploadHandler extends CustomComponent private final transient DeploymentManagement deploymentManagement; private final transient DistributionSetManagement distributionSetManagement; - private final UINotification uINotification; - protected File tempFile = null; private Upload upload; @@ -101,7 +98,7 @@ public class BulkUploadHandler extends CustomComponent private final transient Executor executor; private transient EventBus.SessionEventBus eventBus; - TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout; + private final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout; private transient EntityFactory entityFactory; @@ -111,12 +108,11 @@ public class BulkUploadHandler extends CustomComponent * @param targetManagement * @param managementUIState * @param deploymentManagement - * @param uINotification * @param i18n */ public BulkUploadHandler(final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout, final TargetManagement targetManagement, final ManagementUIState managementUIState, - final DeploymentManagement deploymentManagement, final UINotification uINotification, final I18N i18n) { + final DeploymentManagement deploymentManagement, final I18N i18n) { this.targetBulkUpdateWindowLayout = targetBulkUpdateWindowLayout; this.comboBox = targetBulkUpdateWindowLayout.getDsNamecomboBox(); this.descTextArea = targetBulkUpdateWindowLayout.getDescTextArea(); @@ -124,7 +120,6 @@ public class BulkUploadHandler extends CustomComponent this.progressBar = targetBulkUpdateWindowLayout.getProgressBar(); this.managementUIState = managementUIState; this.deploymentManagement = deploymentManagement; - this.uINotification = uINotification; this.targetsCountLabel = targetBulkUpdateWindowLayout.getTargetsCountLabel(); this.targetBulkTokenTags = targetBulkUpdateWindowLayout.getTargetBulkTokenTags(); this.i18n = i18n; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java index 5cd053ee8..0dbdb1642 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java @@ -178,7 +178,7 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { private BulkUploadHandler getBulkUploadHandler() { final BulkUploadHandler bulkUploadHandler = new BulkUploadHandler(this, targetManagement, managementUIState, - deploymentManagement, uINotification, i18n); + deploymentManagement, i18n); bulkUploadHandler.buildLayout(); bulkUploadHandler.addStyleName(SPUIStyleDefinitions.BULK_UPLOAD_BUTTON); return bulkUploadHandler; From a12b10cd14bd028b8bede36063d57934f0493205 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 4 Aug 2016 08:51:30 +0200 Subject: [PATCH 068/118] fix license header Signed-off-by: Michael Hirsch --- hawkbit-repository/hawkbit-repository-api/pom.xml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/pom.xml b/hawkbit-repository/hawkbit-repository-api/pom.xml index cfd45998c..0a3f541d9 100644 --- a/hawkbit-repository/hawkbit-repository-api/pom.xml +++ b/hawkbit-repository/hawkbit-repository-api/pom.xml @@ -1,5 +1,13 @@ - + 4.0.0 From cad916c1d746ec58bdc93cecdae0038583ecb01d Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Thu, 4 Aug 2016 10:04:08 +0200 Subject: [PATCH 069/118] Refactoring of bulk upload Signed-off-by: Jonathan Philip Knoblauch --- .../ui/management/targettable/BulkUploadHandler.java | 10 +++++----- .../targettable/TargetBulkUpdateWindowLayout.java | 9 --------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index fb8a27a7a..11bbec918 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -214,22 +214,22 @@ public class BulkUploadHandler extends CustomComponent * below event. */ eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_UPLOAD_PROCESS_STARTED)); + while ((line = reader.readLine()) != null) { innerCounter++; readEachLine(line, innerCounter, totalFileSize); } - doAssignments(); - eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_UPLOAD_COMPLETED)); - // Clearing after assignments are done - managementUIState.getTargetTableFilters().getBulkUpload().getTargetsCreated().clear(); } catch (final IOException e) { LOG.error("Error reading file {}", tempFile.getName(), e); } catch (final RuntimeException e) { Optional.ofNullable(UI.getCurrent()).ifPresent( error -> UI.getCurrent().getErrorHandler().error(new ConnectorErrorEvent(upload, e))); - targetBulkUpdateWindowLayout.closePopupAfterFailureAndRefresh(); } finally { + doAssignments(); + eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_UPLOAD_COMPLETED)); + // Clearing after assignments are done + managementUIState.getTargetTableFilters().getBulkUpload().getTargetsCreated().clear(); resetCounts(); deleteFile(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java index 0dbdb1642..f8e273232 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java @@ -239,15 +239,6 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { eventBus.publish(this, BulkUploadPopupEvent.CLOSED); } - /** - * Close and refresh this component. - */ - public void closePopupAfterFailureAndRefresh() { - closePopup(); - destroy(); - init(); - } - /** * @return */ From 038538f89a2d4ed9a80e3dbbae6df58631cad2df Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 4 Aug 2016 12:26:28 +0200 Subject: [PATCH 070/118] extract to meanful method Signed-off-by: Michael Hirsch --- .../security/SecurityManagedConfiguration.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java index e6eb1d159..30ce9d808 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java @@ -573,14 +573,16 @@ class AuthenticationSuccessTenantMetadataCreationFilter implements Filter { @Override public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException { + lazyCreateTenantMetadata(); + chain.doFilter(request, response); - // lazy initialize tenant meta data after successful authentication + } + + private void lazyCreateTenantMetadata() { final Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); if (authentication != null && authentication.isAuthenticated()) { systemSecurityContext.runAsSystem(() -> systemManagement.getTenantMetadata()); } - chain.doFilter(request, response); - } @Override From b1b9716cc561bae9b8792e9a00bf60c3c1162082 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 4 Aug 2016 12:41:13 +0200 Subject: [PATCH 071/118] refactor test code Signed-off-by: Michael Hirsch --- ...gementMethodPreAuthorizeAnnotatedTest.java | 76 ++++++++++++++----- 1 file changed, 55 insertions(+), 21 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java index 3f77a2f38..4971ed1c1 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java +++ b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java @@ -11,6 +11,7 @@ package org.eclipse.hawkbit.repository; import static org.fest.assertions.Assertions.assertThat; import java.io.File; +import java.io.FileFilter; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -97,31 +98,25 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { */ private List> findInterfacesInPackage(final Package p, final Pattern includeFilter) throws URISyntaxException, IOException, ClassNotFoundException { - final List> interfacesToReturn = new ArrayList<>(); final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); final Enumeration resources = classLoader.getResources(p.getName().replace(".", "/")); + final RegexIncludeInterfaceFileCollector regexIncludeInterfaceFileCollector = new RegexIncludeInterfaceFileCollector( + p, includeFilter); while (resources.hasMoreElements()) { - final String uriPath = new URI(resources.nextElement().toString()).getPath(); - if (uriPath != null) { - final File packageDirectory = new File(uriPath); - final File[] filesInPackage = packageDirectory.listFiles(); - for (final File classFile : filesInPackage) { - final String classNameWithExtension = classFile.getName(); - final int indexOfExtension = classNameWithExtension.indexOf(".class"); - if (indexOfExtension > 0) { - final String classNameWithoutExtension = classNameWithExtension.substring(0, indexOfExtension); - if (includeFilter.matcher(classNameWithoutExtension).matches()) { - final Class classInPackage = Class - .forName(p.getName() + "." + classNameWithoutExtension); - if (classInPackage.isInterface()) { - interfacesToReturn.add(classInPackage); - } - } - } - } - } + listFilesInPackage(resources.nextElement(), regexIncludeInterfaceFileCollector); } - return interfacesToReturn; + return regexIncludeInterfaceFileCollector.getInterfaceClasses(); + } + + private File[] listFilesInPackage(final URL resource, final RegexIncludeInterfaceFileCollector clazzCollector) + throws URISyntaxException { + final String packagePath = new URI(resource.toString()).getPath(); + if (packagePath != null) { + final File packageDirectory = new File(packagePath); + final File[] filesInPackage = packageDirectory.listFiles(clazzCollector); + return filesInPackage; + } + return new File[0]; } private static Method getMethod(final Class clazz, final String methodName, final Class... parameterTypes) { @@ -131,4 +126,43 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { throw new RuntimeException(e.getMessage(), e); } } + + private static final class RegexIncludeInterfaceFileCollector implements FileFilter { + + private final List> interfaceClasses = new ArrayList<>(); + private final Pattern includeFilter; + private final Package basePackage; + + public RegexIncludeInterfaceFileCollector(final Package basePackage, final Pattern pattern) { + this.basePackage = basePackage; + this.includeFilter = pattern; + } + + @Override + public boolean accept(final File pathname) { + final String classNameWithExtension = pathname.getName(); + final int indexOfExtension = classNameWithExtension.indexOf(".class"); + if (indexOfExtension == -1) { + return false; + } + final String classNameWithoutExtension = classNameWithExtension.substring(0, indexOfExtension); + if (!includeFilter.matcher(classNameWithoutExtension).matches()) { + return false; + } + + try { + final Class classInPackage = Class.forName(basePackage.getName() + "." + classNameWithoutExtension); + if (classInPackage.isInterface()) { + interfaceClasses.add(classInPackage); + } + } catch (final ClassNotFoundException e) { + // don't need to handle here + } + return false; + } + + public List> getInterfaceClasses() { + return interfaceClasses; + } + } } From f5d9cf19bb5f9adbb5d4c536314380d2ee49acbb Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 4 Aug 2016 13:30:53 +0200 Subject: [PATCH 072/118] return type is not used, method can be void Signed-off-by: Michael Hirsch --- ...RepositoryManagementMethodPreAuthorizeAnnotatedTest.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java index 4971ed1c1..a827b36e7 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java +++ b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java @@ -108,15 +108,13 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { return regexIncludeInterfaceFileCollector.getInterfaceClasses(); } - private File[] listFilesInPackage(final URL resource, final RegexIncludeInterfaceFileCollector clazzCollector) + private void listFilesInPackage(final URL resource, final RegexIncludeInterfaceFileCollector clazzCollector) throws URISyntaxException { final String packagePath = new URI(resource.toString()).getPath(); if (packagePath != null) { final File packageDirectory = new File(packagePath); - final File[] filesInPackage = packageDirectory.listFiles(clazzCollector); - return filesInPackage; + packageDirectory.listFiles(clazzCollector); } - return new File[0]; } private static Method getMethod(final Class clazz, final String methodName, final Class... parameterTypes) { From 6be3d72a5a85ce625720e3b2b33ad91ac0b9f2bf Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Thu, 4 Aug 2016 13:57:06 +0200 Subject: [PATCH 073/118] changed connector for error Signed-off-by: Jonathan Philip Knoblauch --- .../targettable/BulkUploadHandler.java | 24 +++++++++++++------ .../targettable/TargetTableHeader.java | 1 + 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index 11bbec918..5fcebbead 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -98,7 +98,9 @@ public class BulkUploadHandler extends CustomComponent private final transient Executor executor; private transient EventBus.SessionEventBus eventBus; - private final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout; + final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout; + + TargetTableHeader targetTableHeader; private transient EntityFactory entityFactory; @@ -223,9 +225,10 @@ public class BulkUploadHandler extends CustomComponent } catch (final IOException e) { LOG.error("Error reading file {}", tempFile.getName(), e); } catch (final RuntimeException e) { - Optional.ofNullable(UI.getCurrent()).ifPresent( - error -> UI.getCurrent().getErrorHandler().error(new ConnectorErrorEvent(upload, e))); + Optional.ofNullable(UI.getCurrent()).ifPresent(error -> UI.getCurrent().getErrorHandler() + .error(new ConnectorErrorEvent(targetTableHeader, e))); } finally { + updateBulkUpload(); doAssignments(); eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_UPLOAD_COMPLETED)); // Clearing after assignments are done @@ -283,13 +286,16 @@ public class BulkUploadHandler extends CustomComponent if (Math.abs(next - 0.1) < 0.00001 || current - next >= 0 || next - current >= 0.05 || Math.abs(next - 1) < 0.00001) { managementUIState.getTargetTableFilters().getBulkUpload().setProgressBarCurrentValue(next); - managementUIState.getTargetTableFilters().getBulkUpload() - .setSucessfulUploadCount(successfullTargetCount); - managementUIState.getTargetTableFilters().getBulkUpload().setFailedUploadCount(failedTargetCount); - eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_TARGET_CREATED)); + updateBulkUpload(); } } + private void updateBulkUpload() { + managementUIState.getTargetTableFilters().getBulkUpload().setSucessfulUploadCount(successfullTargetCount); + managementUIState.getTargetTableFilters().getBulkUpload().setFailedUploadCount(failedTargetCount); + eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_TARGET_CREATED)); + } + private void doAssignments() { final StringBuilder errorMessage = new StringBuilder(); String dsAssignmentFailedMsg = null; @@ -457,4 +463,8 @@ public class BulkUploadHandler extends CustomComponent eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_TARGET_UPLOAD_STARTED)); } } + + public void setTargetBulkUpdateWindowLayout(final TargetTableHeader targetTableHeader) { + this.targetTableHeader = targetTableHeader; + } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java index 16dc584ed..760332e09 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java @@ -82,6 +82,7 @@ public class TargetTableHeader extends AbstractTableHeader { // creating add window for adding new target targetAddUpdateWindow.init(); targetBulkUpdateWindow.init(); + targetBulkUpdateWindow.getBulkUploader().setTargetBulkUpdateWindowLayout(this); onLoadRestoreState(); } From 11bb28269958d1217e144c89dcbeebbe694ad43a Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Thu, 4 Aug 2016 15:57:20 +0200 Subject: [PATCH 074/118] Refactoring for button enable Signed-off-by: Jonathan Philip Knoblauch --- .../hawkbit/ui/management/targettable/BulkUploadHandler.java | 3 ++- .../management/targettable/TargetBulkUpdateWindowLayout.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index 5fcebbead..fd7f5fa3d 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -138,7 +138,7 @@ public class BulkUploadHandler extends CustomComponent public void buildLayout() { final HorizontalLayout horizontalLayout = new HorizontalLayout(); upload = new Upload(); - upload.setEnabled(true); + upload.setEnabled(false); upload.setButtonCaption("Bulk Upload"); upload.setReceiver(this); upload.setImmediate(true); @@ -227,6 +227,7 @@ public class BulkUploadHandler extends CustomComponent } catch (final RuntimeException e) { Optional.ofNullable(UI.getCurrent()).ifPresent(error -> UI.getCurrent().getErrorHandler() .error(new ConnectorErrorEvent(targetTableHeader, e))); + } finally { updateBulkUpload(); doAssignments(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java index f8e273232..77eaaddea 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java @@ -296,8 +296,9 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { descTextArea.clear(); targetBulkTokenTags.getTokenField().clear(); targetBulkTokenTags.populateContainer(); - progressBar.setValue(0f); + progressBar.setValue(0F); progressBar.setVisible(false); + managementUIState.getTargetTableFilters().getBulkUpload().setProgressBarCurrentValue(0F); targetsCountLabel.setVisible(false); } From 709ea990dff1544f7beab941e069aab7101e2e1b Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Thu, 4 Aug 2016 16:19:35 +0200 Subject: [PATCH 075/118] Removed component that was not needed Signed-off-by: Jonathan Philip Knoblauch --- .../hawkbit/ui/management/targettable/BulkUploadHandler.java | 2 +- .../management/targettable/TargetBulkUpdateWindowLayout.java | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index fd7f5fa3d..44b3d2e50 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -100,7 +100,7 @@ public class BulkUploadHandler extends CustomComponent final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout; - TargetTableHeader targetTableHeader; + private TargetTableHeader targetTableHeader; private transient EntityFactory entityFactory; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java index 77eaaddea..b77576411 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java @@ -31,7 +31,6 @@ import org.eclipse.hawkbit.ui.utils.SPUIComponentIdProvider; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; -import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; @@ -73,9 +72,6 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { @Autowired private transient TargetManagement targetManagement; - @Autowired - private transient UINotification uINotification; - @Autowired private transient EventBus.SessionEventBus eventBus; From 303a668f1632cb6ea15f19422cfb24efe5a34733 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 4 Aug 2016 17:36:28 +0200 Subject: [PATCH 076/118] Fix for the entity lock exception for unassign soft module from DS Signed-off-by: Gaurav --- .../SoftwareModuleDetailsTable.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java index 1af6aabe1..713beced1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java @@ -186,12 +186,19 @@ public class SoftwareModuleDetailsTable extends Table { private void unassignSW(final ClickEvent event, final DistributionSet distributionSet, final Set alreadyAssignedSwModules) { final SoftwareModule unAssignedSw = getSoftwareModule(event.getButton().getId(), alreadyAssignedSwModules); - final DistributionSet newDistributionSet = distributionSetManagement.unassignSoftwareModule(distributionSet, - unAssignedSw); - manageDistUIState.setLastSelectedEntity(DistributionSetIdName.generate(newDistributionSet)); - eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, newDistributionSet)); - eventBus.publish(this, DistributionsUIEvent.ORDER_BY_DISTRIBUTION); - uiNotification.displaySuccess(i18n.get("message.sw.unassigned", unAssignedSw.getName())); + if (distributionSetManagement.isDistributionSetInUse(distributionSet)) { + uiNotification.displayValidationError( + String.format("Distribution set %s:%s is already assigned to targets and cannot be changed", + distributionSet.getName(), distributionSet.getVersion())); + } else { + final DistributionSet newDistributionSet = distributionSetManagement.unassignSoftwareModule(distributionSet, + unAssignedSw); + manageDistUIState.setLastSelectedEntity(DistributionSetIdName.generate(newDistributionSet)); + eventBus.publish(this, new DistributionTableEvent(BaseEntityEventType.SELECTED_ENTITY, newDistributionSet)); + eventBus.publish(this, DistributionsUIEvent.ORDER_BY_DISTRIBUTION); + uiNotification.displaySuccess(i18n.get("message.sw.unassigned", unAssignedSw.getName())); + } + } private static boolean isSoftModAvaiableForSoftType(final Set swModulesSet, From 582ac22678fd2749461fcd9e6110840abec0a48c Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 4 Aug 2016 17:44:13 +0200 Subject: [PATCH 077/118] Formatted the code --- .../ui/common/detailslayout/SoftwareModuleDetailsTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java index 713beced1..036b229df 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java @@ -198,7 +198,7 @@ public class SoftwareModuleDetailsTable extends Table { eventBus.publish(this, DistributionsUIEvent.ORDER_BY_DISTRIBUTION); uiNotification.displaySuccess(i18n.get("message.sw.unassigned", unAssignedSw.getName())); } - + } private static boolean isSoftModAvaiableForSoftType(final Set swModulesSet, From f964f7c0c6e2b87b80bd49446e6ee51c7d07a687 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 4 Aug 2016 17:44:13 +0200 Subject: [PATCH 078/118] Formatted the code Signed-off-by: Gaurav --- .../ui/common/detailslayout/SoftwareModuleDetailsTable.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java index 713beced1..036b229df 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java @@ -198,7 +198,7 @@ public class SoftwareModuleDetailsTable extends Table { eventBus.publish(this, DistributionsUIEvent.ORDER_BY_DISTRIBUTION); uiNotification.displaySuccess(i18n.get("message.sw.unassigned", unAssignedSw.getName())); } - + } private static boolean isSoftModAvaiableForSoftType(final Set swModulesSet, From 54ce3ad8e06596c8ed7f2808a7e370b742f62521 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Fri, 5 Aug 2016 08:56:38 +0200 Subject: [PATCH 079/118] Fix sonar issues Signed-off-by: SirWayne --- .../simulator/DeviceSimulatorUpdater.java | 125 ++++++++------ .../simulator/amqp/SpReceiverService.java | 11 +- .../hawkbit/simulator/ui/GenerateDialog.java | 27 ++- .../hawkbit/simulator/ui/SimulatorView.java | 156 +++++++++--------- .../eventbus/EventBusAutoConfiguration.java | 2 +- .../AsyncConfigurerAutoConfiguration.java | 2 +- .../SecurityManagedConfiguration.java | 2 + .../hawkbit/cache/RedisConfiguration.java | 4 + .../cache/eventbus/EventDistributor.java | 6 +- .../hawkbit/api/ProtocolProperties.java | 2 +- .../event/CancelTargetAssignmentEvent.java | 2 +- .../{AbstractEvent.java => DefaultEvent.java} | 5 +- .../eventbus/event/TargetDeletedEvent.java | 4 +- ...on.java => AbstractServerRtException.java} | 11 +- .../exception/GenericSpServerException.java | 2 +- .../hawkbit/repository/ActionFields.java | 18 +- .../hawkbit/repository/FieldNameProvider.java | 21 ++- ...nvalidTenantConfigurationKeyException.java | 4 +- .../TenantConfigurationValidator.java | 2 +- ...TenantConfigurationValidatorException.java | 4 +- .../ddi/json/model/DdiArtifactHash.java | 1 + .../hawkbit/ddi/json/model/DdiChunk.java | 2 +- .../hawkbit/ddi/json/model/DdiConfig.java | 5 +- .../ddi/json/model/DdiControllerBase.java | 2 +- .../hawkbit/ddi/json/model/DdiDeployment.java | 5 +- .../ddi/json/model/DdiDeploymentBase.java | 10 +- .../hawkbit/ddi/json/model/DdiPolling.java | 6 +- .../amqp/AmqpControllerAuthentfication.java | 2 +- .../amqp/AmqpMessageHandlerService.java | 20 +++ .../eclipse/hawkbit/amqp/BaseAmqpService.java | 4 +- .../rest/api/MgmtDownloadArtifactRestApi.java | 1 + .../mgmt/rest/api/MgmtDownloadRestApi.java | 1 + .../rest/resource/MgmtDownloadResource.java | 10 +- .../repository/DistributionSetManagement.java | 6 +- .../eventbus/event/RolloutChangeEvent.java | 4 +- .../event/RolloutGroupChangeEvent.java | 4 +- .../TargetAssignDistributionSetEvent.java | 4 +- .../ArtifactDeleteFailedException.java | 4 +- .../ArtifactUploadFailedException.java | 4 +- .../CancelActionNotAllowedException.java | 4 +- .../ConcurrentModificationException.java | 4 +- ...FailedMissingMandatoryModuleException.java | 4 +- ...DistributionSetTypeUndefinedException.java | 4 +- .../EntityAlreadyExistsException.java | 4 +- .../exception/EntityLockedException.java | 4 +- .../exception/EntityNotFoundException.java | 4 +- .../exception/EntityReadOnlyException.java | 4 +- .../ForceQuitActionNotAllowedException.java | 4 +- .../GridFSDBFileNotFoundException.java | 4 +- .../IncompleteDistributionSetException.java | 4 +- .../InsufficientPermissionException.java | 4 +- .../exception/InvalidMD5HashException.java | 4 +- .../exception/InvalidSHA1HashException.java | 4 +- .../InvalidTargetAddressException.java | 4 +- .../MultiPartFileUploadException.java | 4 +- .../RSQLParameterSyntaxException.java | 4 +- ...SQLParameterUnsupportedFieldException.java | 4 +- .../RolloutIllegalStateException.java | 4 +- .../exception/TenantNotExistException.java | 4 +- .../ToManyAttributeEntriesException.java | 4 +- .../ToManyStatusEntriesException.java | 4 +- ...ModuleForThisDistributionSetException.java | 4 +- .../MessageNotReadableException.java | 4 +- .../exception/ResponseExceptionHandler.java | 14 +- .../SortParameterSyntaxErrorException.java | 4 +- ...arameterUnsupportedDirectionException.java | 4 +- ...ortParameterUnsupportedFieldException.java | 4 +- .../util/FileSteamingFailedException.java | 4 +- 68 files changed, 341 insertions(+), 290 deletions(-) rename hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/{AbstractEvent.java => DefaultEvent.java} (87%) rename hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/{SpServerRtException.java => AbstractServerRtException.java} (79%) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java index 69ed4fd4a..b7423e899 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java @@ -118,6 +118,16 @@ public class DeviceSimulatorUpdater { } private static final class DeviceSimulatorUpdateThread implements Runnable { + /** + * + */ + private static final String BUT_GOT_LOG_MESSAGE = " but got: "; + + /** + * + */ + private static final String DOWNLOAD_LOG_MESSAGE = "Download "; + private static final int MINIMUM_TOKENLENGTH_FOR_HINT = 6; private static final Random rndSleep = new SecureRandom(); @@ -212,60 +222,73 @@ public class DeviceSimulatorUpdater { LOGGER.debug("Downloading {} with token {}, expected sha1 hash {} and size {}", url, hideTokenDetails(targetToken), sha1Hash, size); - long overallread = 0; try { - final CloseableHttpClient httpclient = createHttpClientThatAcceptsAllServerCerts(); - final HttpGet request = new HttpGet(url); - request.addHeader(HttpHeaders.AUTHORIZATION, "TargetToken " + targetToken); - - final String sha1HashResult; - try (final CloseableHttpResponse response = httpclient.execute(request)) { - - if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) { - final String message = wrongStatusCode(url, response); - return new UpdateStatus(ResponseStatus.ERROR, message); - } - - if (response.getEntity().getContentLength() != size) { - final String message = wrongContentLength(url, size, response); - return new UpdateStatus(ResponseStatus.ERROR, message); - } - - // Exception squid:S2070 - not used for hashing sensitive - // data - @SuppressWarnings("squid:S2070") - final MessageDigest md = MessageDigest.getInstance("SHA-1"); - - try (final BufferedOutputStream bdos = new BufferedOutputStream( - new DigestOutputStream(ByteStreams.nullOutputStream(), md))) { - try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) { - overallread = ByteStreams.copy(bis, bdos); - } - } - - if (overallread != size) { - final String message = incompleteRead(url, size, overallread); - return new UpdateStatus(ResponseStatus.ERROR, message); - } - - sha1HashResult = BaseEncoding.base16().lowerCase().encode(md.digest()); - } - - if (!sha1Hash.equalsIgnoreCase(sha1HashResult)) { - final String message = wrongHash(url, sha1Hash, overallread, sha1HashResult); - return new UpdateStatus(ResponseStatus.ERROR, message); - } - + return readAndCheckDownloadUrl(url, targetToken, sha1Hash, size); } catch (IOException | KeyManagementException | NoSuchAlgorithmException | KeyStoreException e) { LOGGER.error("Failed to download" + url, e); return new UpdateStatus(ResponseStatus.ERROR, "Failed to download " + url + ": " + e.getMessage()); } + } + + private static UpdateStatus readAndCheckDownloadUrl(final String url, final String targetToken, + final String sha1Hash, final long size) + throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, IOException { + long overallread; + final CloseableHttpClient httpclient = createHttpClientThatAcceptsAllServerCerts(); + final HttpGet request = new HttpGet(url); + request.addHeader(HttpHeaders.AUTHORIZATION, "TargetToken " + targetToken); + + final String sha1HashResult; + try (final CloseableHttpResponse response = httpclient.execute(request)) { + + if (response.getStatusLine().getStatusCode() != HttpStatus.OK.value()) { + final String message = wrongStatusCode(url, response); + return new UpdateStatus(ResponseStatus.ERROR, message); + } + + if (response.getEntity().getContentLength() != size) { + final String message = wrongContentLength(url, size, response); + return new UpdateStatus(ResponseStatus.ERROR, message); + } + + // Exception squid:S2070 - not used for hashing sensitive + // data + @SuppressWarnings("squid:S2070") + final MessageDigest md = MessageDigest.getInstance("SHA-1"); + + overallread = getOverallRead(response, md); + + if (overallread != size) { + final String message = incompleteRead(url, size, overallread); + return new UpdateStatus(ResponseStatus.ERROR, message); + } + + sha1HashResult = BaseEncoding.base16().lowerCase().encode(md.digest()); + } + + if (!sha1Hash.equalsIgnoreCase(sha1HashResult)) { + final String message = wrongHash(url, sha1Hash, overallread, sha1HashResult); + return new UpdateStatus(ResponseStatus.ERROR, message); + } + final String message = "Downloaded " + url + " (" + overallread + " bytes)"; LOGGER.debug(message); return new UpdateStatus(ResponseStatus.SUCCESSFUL, message); } + private static long getOverallRead(final CloseableHttpResponse response, final MessageDigest md) + throws IOException { + long overallread; + try (final BufferedOutputStream bdos = new BufferedOutputStream( + new DigestOutputStream(ByteStreams.nullOutputStream(), md))) { + try (BufferedInputStream bis = new BufferedInputStream(response.getEntity().getContent())) { + overallread = ByteStreams.copy(bis, bdos); + } + } + return overallread; + } + private static String hideTokenDetails(final String targetToken) { if (targetToken == null) { return ""; @@ -285,29 +308,30 @@ public class DeviceSimulatorUpdater { private static String wrongHash(final String url, final String sha1Hash, final long overallread, final String sha1HashResult) { - final String message = "Download " + url + " failed with SHA1 hash missmatch (Expected: " + sha1Hash - + " but got: " + sha1HashResult + ") (" + overallread + " bytes)"; + final String message = DOWNLOAD_LOG_MESSAGE + url + " failed with SHA1 hash missmatch (Expected: " + + sha1Hash + BUT_GOT_LOG_MESSAGE + sha1HashResult + ") (" + overallread + " bytes)"; LOGGER.error(message); return message; } private static String incompleteRead(final String url, final long size, final long overallread) { - final String message = "Download " + url + " is incomplete (Expected: " + size + " but got: " + overallread - + ")"; + final String message = DOWNLOAD_LOG_MESSAGE + url + " is incomplete (Expected: " + size + + BUT_GOT_LOG_MESSAGE + overallread + ")"; LOGGER.error(message); return message; } private static String wrongContentLength(final String url, final long size, final CloseableHttpResponse response) { - final String message = "Download " + url + " has wrong content length (Expected: " + size + " but got: " - + response.getEntity().getContentLength() + ")"; + final String message = DOWNLOAD_LOG_MESSAGE + url + " has wrong content length (Expected: " + size + + BUT_GOT_LOG_MESSAGE + response.getEntity().getContentLength() + ")"; LOGGER.error(message); return message; } private static String wrongStatusCode(final String url, final CloseableHttpResponse response) { - final String message = "Download " + url + " failed (" + response.getStatusLine().getStatusCode() + ")"; + final String message = DOWNLOAD_LOG_MESSAGE + url + " failed (" + response.getStatusLine().getStatusCode() + + ")"; LOGGER.error(message); return message; } @@ -339,4 +363,5 @@ public class DeviceSimulatorUpdater { */ void updateFinished(AbstractSimulatedDevice device, final Long actionId); } + } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java index 4f2981be1..7d55fb375 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java @@ -67,8 +67,6 @@ public class SpReceiverService extends ReceiverService { * the incoming message * @param type * the action type - * @param contentType - * the content type in message header * @param thingId * the thing id in message header */ @@ -82,14 +80,11 @@ public class SpReceiverService extends ReceiverService { private void delegateMessage(final Message message, final String type, final String thingId) { final MessageType messageType = MessageType.valueOf(type); - switch (messageType) { - case EVENT: + if (MessageType.EVENT.equals(messageType)) { handleEventMessage(message, thingId); - break; - default: - LOGGER.info("No valid message type property."); - break; + return; } + LOGGER.info("No valid message type property."); } private void handleEventMessage(final Message message, final String thingId) { diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java index 272531407..b50098829 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java @@ -33,9 +33,10 @@ import com.vaadin.ui.Window; * Popup dialog window for setting the values of generating the simulated * devices, e.g. the amount. * - * @author Michael Hirsch * */ +// Vaadin Inheritance +@SuppressWarnings("squid:MaximumInheritanceDepth") public class GenerateDialog extends Window { private static final long serialVersionUID = 1L; @@ -49,8 +50,8 @@ public class GenerateDialog extends Window { private final TextField pollDelayTextField; private final TextField pollUrlTextField; private final TextField gatewayTokenTextField; - private final OptionGroup protocolGroup; - private final Button buttonOk; + private OptionGroup protocolGroup; + private Button buttonOk; /** * Creates a new pop window for setting the configuration of simulating @@ -87,8 +88,8 @@ public class GenerateDialog extends Window { gatewayTokenTextField.setColumns(50); gatewayTokenTextField.setVisible(false); - protocolGroup = createProtocolGroup(); - buttonOk = createOkButton(callback); + createProtocolGroup(); + createOkButton(callback); namePrefixTextField.addValueChangeListener(event -> checkValid()); amountTextField.addValueChangeListener(event -> checkValid()); @@ -181,9 +182,9 @@ public class GenerateDialog extends Window { final URL basePollURL, final String gatewayToken, final Protocol protocol); } - private OptionGroup createProtocolGroup() { + private void createProtocolGroup() { - final OptionGroup protocolGroup = new OptionGroup("Simulated Device Protocol"); + this.protocolGroup = new OptionGroup("Simulated Device Protocol"); protocolGroup.addItem(Protocol.DMF_AMQP); protocolGroup.addItem(Protocol.DDI_HTTP); protocolGroup.setItemCaption(Protocol.DMF_AMQP, "Device Management Federation API (AMQP push)"); @@ -195,12 +196,11 @@ public class GenerateDialog extends Window { pollUrlTextField.setVisible(directDeviceOptionSelected); gatewayTokenTextField.setVisible(directDeviceOptionSelected); }); - return protocolGroup; } - private Button createOkButton(final GenerateDialogCallback callback) { + private void createOkButton(final GenerateDialogCallback callback) { - final Button buttonOk = new Button("generate"); + this.buttonOk = new Button("generate"); buttonOk.setImmediate(true); buttonOk.setIcon(FontAwesome.GEARS); buttonOk.addClickListener(event -> { @@ -210,14 +210,11 @@ public class GenerateDialog extends Window { Integer.valueOf(pollDelayTextField.getValue().replace(".", "")), new URL(pollUrlTextField.getValue()), gatewayTokenTextField.getValue(), (Protocol) protocolGroup.getValue()); - } catch (final NumberFormatException e) { - LOGGER.info(e.getMessage(), e); - } catch (final MalformedURLException e) { + } catch (final NumberFormatException | MalformedURLException e) { LOGGER.info(e.getMessage(), e); } GenerateDialog.this.close(); }); - return buttonOk; } private TextField createRequiredTextfield(final String caption, final String value, final Resource icon, @@ -226,7 +223,7 @@ public class GenerateDialog extends Window { return addTextFieldValues(textField, icon, validator); } - private TextField createRequiredTextfield(final String caption, final Property dataSource, final Resource icon, + private TextField createRequiredTextfield(final String caption, final Property dataSource, final Resource icon, final Validator validator) { final TextField textField = new TextField(caption, dataSource); return addTextFieldValues(textField, icon, validator); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java index 9405edd2b..686945407 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java @@ -57,6 +57,11 @@ import com.vaadin.ui.renderers.ProgressBarRenderer; @SuppressWarnings("squid:MaximumInheritanceDepth") public class SimulatorView extends VerticalLayout implements View { + /** + * + */ + private static final String HTML_SPAN = ";"; + private static final String NEXT_POLL_COUNTER_SEC_COL = "nextPollCounterSec"; private static final String RESPONSE_STATUS_COL = "updateStatus"; @@ -266,89 +271,90 @@ public class SimulatorView extends VerticalLayout implements View { })); } - private Converter createProtocolConverter() { - - return new Converter() { - - private static final long serialVersionUID = 1L; - - @Override - public Protocol convertToModel(final String value, final Class targetType, - final Locale locale) { - return null; - } - - @Override - public String convertToPresentation(final Protocol value, final Class targetType, - final Locale locale) { - switch (value) { - case DDI_HTTP: - return "DDI API (http)"; - case DMF_AMQP: - return "DMF API (amqp)"; - default: - return "unknown"; - } - } - - @Override - public Class getModelType() { - return Protocol.class; - } - - @Override - public Class getPresentationType() { - return String.class; - } - }; - + private ProtocolConverter createProtocolConverter() { + return new ProtocolConverter(); } - private Converter createStatusConverter() { - return new Converter() { - private static final long serialVersionUID = 1L; + private StatusConverter createStatusConverter() { + return new StatusConverter(); + } - @Override - public Status convertToModel(final String value, final Class targetType, - final Locale locale) { - return null; - } + public static final class ProtocolConverter implements Converter { + private static final long serialVersionUID = 1L; - @Override - public String convertToPresentation(final Status value, final Class targetType, - final Locale locale) { - switch (value) { - case UNKNWON: - return "&#x" - + Integer.toHexString(FontAwesome.QUESTION_CIRCLE.getCodepoint()) + ";"; - case PEDNING: - return "&#x" + Integer.toHexString(FontAwesome.REFRESH.getCodepoint()) - + ";"; - case FINISH: - return "&#x" - + Integer.toHexString(FontAwesome.CHECK_CIRCLE.getCodepoint()) + ";"; - case ERROR: - return "&#x" - + Integer.toHexString(FontAwesome.EXCLAMATION_CIRCLE.getCodepoint()) + ";"; - default: - throw new IllegalStateException("unknown value"); - } - } + @Override + public Protocol convertToModel(final String value, final Class targetType, + final Locale locale) { + return null; + } - @Override - public Class getModelType() { - return Status.class; + @Override + public String convertToPresentation(final Protocol value, final Class targetType, + final Locale locale) { + switch (value) { + case DDI_HTTP: + return "DDI API (http)"; + case DMF_AMQP: + return "DMF API (amqp)"; + default: + return "unknown"; } + } - @Override - public Class getPresentationType() { - return String.class; + @Override + public Class getModelType() { + return Protocol.class; + } + + @Override + public Class getPresentationType() { + return String.class; + } + } + + private static final class StatusConverter implements Converter { + private static final long serialVersionUID = 1L; + + @Override + public Status convertToModel(final String value, final Class targetType, + final Locale locale) { + return null; + } + + @Override + public String convertToPresentation(final Status value, final Class targetType, + final Locale locale) { + switch (value) { + case UNKNWON: + return "&#x" + Integer.toHexString(FontAwesome.QUESTION_CIRCLE.getCodepoint()) + + HTML_SPAN; + case PEDNING: + return "&#x" + Integer.toHexString(FontAwesome.REFRESH.getCodepoint()) + + HTML_SPAN; + case FINISH: + return "&#x" + Integer.toHexString(FontAwesome.CHECK_CIRCLE.getCodepoint()) + + HTML_SPAN; + case ERROR: + return "&#x" + + Integer.toHexString(FontAwesome.EXCLAMATION_CIRCLE.getCodepoint()) + HTML_SPAN; + default: + throw new IllegalStateException("unknown value"); } - }; + } + + @Override + public Class getModelType() { + return Status.class; + } + + @Override + public Class getPresentationType() { + return String.class; + } } } diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/eventbus/EventBusAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/eventbus/EventBusAutoConfiguration.java index d4cc32825..c0cbabb08 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/eventbus/EventBusAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/eventbus/EventBusAutoConfiguration.java @@ -23,7 +23,7 @@ import com.google.common.eventbus.AsyncEventBus; import com.google.common.eventbus.EventBus; /** - * + * Auto configuration for the event bus. * */ @Configuration diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/AsyncConfigurerAutoConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/AsyncConfigurerAutoConfiguration.java index 7e2b780b4..eebfac6b0 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/AsyncConfigurerAutoConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/scheduling/AsyncConfigurerAutoConfiguration.java @@ -21,7 +21,7 @@ import org.springframework.scheduling.annotation.EnableAsync; /** * - * + * Auto config fot the exception handler. */ @Configuration @EnableAsync diff --git a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java index 1e4dbfb27..07ea15a8a 100644 --- a/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java +++ b/hawkbit-autoconfigure/src/main/java/org/eclipse/hawkbit/autoconfigure/security/SecurityManagedConfiguration.java @@ -119,6 +119,8 @@ public class SecurityManagedConfiguration { */ @Bean @ConditionalOnMissingBean + // Exception squid:S00112 - Is aspectJ proxy + @SuppressWarnings({ "squid:S00112" }) public UserAuthenticationFilter userAuthenticationFilter() throws Exception { return new UserAuthenticationFilterBasicAuth(configuration.getAuthenticationManager()); } diff --git a/hawkbit-cache-redis/src/main/java/org/eclipse/hawkbit/cache/RedisConfiguration.java b/hawkbit-cache-redis/src/main/java/org/eclipse/hawkbit/cache/RedisConfiguration.java index fc3364d81..d9f759da3 100644 --- a/hawkbit-cache-redis/src/main/java/org/eclipse/hawkbit/cache/RedisConfiguration.java +++ b/hawkbit-cache-redis/src/main/java/org/eclipse/hawkbit/cache/RedisConfiguration.java @@ -56,6 +56,10 @@ public class RedisConfiguration { return new TenantAwareCacheManager(directCacheManager(), tenantAware); } + /** + * + * @return bean for the direct cache manager. + */ @Bean(name = "directCacheManager") public CacheManager directCacheManager() { return new RedisCacheManager(redisTemplate()); diff --git a/hawkbit-cache-redis/src/main/java/org/eclipse/hawkbit/cache/eventbus/EventDistributor.java b/hawkbit-cache-redis/src/main/java/org/eclipse/hawkbit/cache/eventbus/EventDistributor.java index 8749340f0..973dcb6d6 100644 --- a/hawkbit-cache-redis/src/main/java/org/eclipse/hawkbit/cache/eventbus/EventDistributor.java +++ b/hawkbit-cache-redis/src/main/java/org/eclipse/hawkbit/cache/eventbus/EventDistributor.java @@ -28,7 +28,7 @@ import com.google.common.eventbus.EventBus; import com.google.common.eventbus.Subscribe; /** - * + * The distributor for events. * */ @EventSubscriber @@ -100,11 +100,11 @@ public class EventDistributor { return topics; } - private void logDistributingEvent(final Event event, final String channel) { + private static void logDistributingEvent(final Event event, final String channel) { LOGGER.trace("distributing event {} from node {} to topic {}", event, NODE_ID, channel); } - private void logNotDistributingEvent(final Event event, final String channel) { + private static void logNotDistributingEvent(final Event event, final String channel) { LOGGER.debug("no redis template configured, event {} will not be distributed to channel {} from node {}", event, channel, NODE_ID); } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ProtocolProperties.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ProtocolProperties.java index c4a9556b7..57f376c4e 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ProtocolProperties.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/api/ProtocolProperties.java @@ -37,4 +37,4 @@ public interface ProtocolProperties { * @return true if the {@link ProtocolProperties} is enabled. */ boolean isEnabled(); -} \ No newline at end of file +} diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/CancelTargetAssignmentEvent.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/CancelTargetAssignmentEvent.java index da93cc1a3..78c718f36 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/CancelTargetAssignmentEvent.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/CancelTargetAssignmentEvent.java @@ -17,7 +17,7 @@ import java.net.URI; * * */ -public class CancelTargetAssignmentEvent extends AbstractEvent { +public class CancelTargetAssignmentEvent extends DefaultEvent { private final String controllerId; private final Long actionId; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractEvent.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DefaultEvent.java similarity index 87% rename from hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractEvent.java rename to hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DefaultEvent.java index 498418169..1874fc01f 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/AbstractEvent.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/DefaultEvent.java @@ -12,11 +12,10 @@ package org.eclipse.hawkbit.eventbus.event; * Abstract event definition class which holds the necessary revsion and tenant * information which every event needs. * - * @author Michael Hirsch * @see AbstractDistributedEvent for events which should be distributed to other * cluster nodes */ -public class AbstractEvent implements Event { +public class DefaultEvent implements Event { private final long revision; private final String tenant; @@ -27,7 +26,7 @@ public class AbstractEvent implements Event { * @param tenant * the tenant of the event */ - protected AbstractEvent(final long revision, final String tenant) { + protected DefaultEvent(final long revision, final String tenant) { this.revision = revision; this.tenant = tenant; } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java index e6fcac135..048274abc 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/eventbus/event/TargetDeletedEvent.java @@ -9,9 +9,7 @@ package org.eclipse.hawkbit.eventbus.event; /** - * - * - * + * The event when a target is deleted. */ public class TargetDeletedEvent extends AbstractDistributedEvent { diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerRtException.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/AbstractServerRtException.java similarity index 79% rename from hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerRtException.java rename to hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/AbstractServerRtException.java index ba691bb5f..cb695d2f7 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerRtException.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/AbstractServerRtException.java @@ -15,8 +15,7 @@ package org.eclipse.hawkbit.exception; * Generic Custom Exception to wrap the Runtime and checked exception * */ - -public abstract class SpServerRtException extends RuntimeException { +public abstract class AbstractServerRtException extends RuntimeException { private static final long serialVersionUID = 1L; @@ -28,7 +27,7 @@ public abstract class SpServerRtException extends RuntimeException { * @param error * detail */ - public SpServerRtException(final SpServerError error) { + public AbstractServerRtException(final SpServerError error) { super(error.getMessage()); this.error = error; } @@ -41,7 +40,7 @@ public abstract class SpServerRtException extends RuntimeException { * @param error * detail */ - public SpServerRtException(final String message, final SpServerError error) { + public AbstractServerRtException(final String message, final SpServerError error) { super(message); this.error = error; } @@ -56,7 +55,7 @@ public abstract class SpServerRtException extends RuntimeException { * @param cause * of the exception */ - public SpServerRtException(final String message, final SpServerError error, final Throwable cause) { + public AbstractServerRtException(final String message, final SpServerError error, final Throwable cause) { super(message, cause); this.error = error; } @@ -69,7 +68,7 @@ public abstract class SpServerRtException extends RuntimeException { * @param cause * of the exception */ - public SpServerRtException(final SpServerError error, final Throwable cause) { + public AbstractServerRtException(final SpServerError error, final Throwable cause) { super(error.getMessage(), cause); this.error = error; } diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/GenericSpServerException.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/GenericSpServerException.java index f0a3f4d1f..4ac02e081 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/GenericSpServerException.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/GenericSpServerException.java @@ -16,7 +16,7 @@ package org.eclipse.hawkbit.exception; * * */ -public class GenericSpServerException extends SpServerRtException { +public class GenericSpServerException extends AbstractServerRtException { private static final long serialVersionUID = 1L; private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_GENERIC_ERROR; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionFields.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionFields.java index c2d8ec49d..237fed978 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionFields.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/repository/ActionFields.java @@ -11,11 +11,8 @@ package org.eclipse.hawkbit.repository; /** * Sort fields for {@link ActionRest}. * - * - * - * */ -public enum ActionFields implements FieldNameProvider,FieldValueConverter { +public enum ActionFields implements FieldNameProvider, FieldValueConverter { /** * The status field. @@ -42,13 +39,10 @@ public enum ActionFields implements FieldNameProvider,FieldValueConverter contains contains not + */ default boolean containsSubEntityAttribute(final String propertyField) { return FieldNameProvider.containsSubEntityAttribute(propertyField, getSubEntityAttributes()); - }; + } + /** + * + * @return all sub entities attributes. + */ default List getSubEntityAttributes() { return Collections.emptyList(); - }; + } /** * the database column for the key @@ -59,11 +70,11 @@ public interface FieldNameProvider { /** * Is the entity field a {@link Map}. * - * @return + * @return is a map is not a map */ default boolean isMap() { return getKeyFieldName() != null; - }; + } /** * Check if a sub attribute exists. diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.java index dcc42065c..977b66a6a 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/InvalidTenantConfigurationKeyException.java @@ -9,14 +9,14 @@ package org.eclipse.hawkbit.tenancy.configuration; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * The {@link #InvalidTenantConfigurationKeyException} is thrown when an invalid * configuration key is used. * */ -public class InvalidTenantConfigurationKeyException extends SpServerRtException { +public class InvalidTenantConfigurationKeyException extends AbstractServerRtException { private static final long serialVersionUID = 1L; private static final SpServerError THIS_ERROR = SpServerError.SP_CONFIGURATION_KEY_INVALID; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java index dccf515e6..bb61f1ec5 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidator.java @@ -22,7 +22,7 @@ public interface TenantConfigurationValidator { * @throws TenantConfigurationValidatorException * is thrown, when parameter is invalid. */ - default void validate(final Object tenantConfigurationValue) throws TenantConfigurationValidatorException { + default void validate(final Object tenantConfigurationValue) { if (tenantConfigurationValue != null && validateToClass().isAssignableFrom(tenantConfigurationValue.getClass())) { return; diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidatorException.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidatorException.java index dffc13dcb..4cc545287 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidatorException.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/tenancy/configuration/validator/TenantConfigurationValidatorException.java @@ -9,14 +9,14 @@ package org.eclipse.hawkbit.tenancy.configuration.validator; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Exception which is thrown, when the validation of the configuration value has * not been successful. * */ -public class TenantConfigurationValidatorException extends SpServerRtException { +public class TenantConfigurationValidatorException extends AbstractServerRtException { private static final long serialVersionUID = 1L; private static final SpServerError THIS_ERROR = SpServerError.SP_CONFIGURATION_VALUE_INVALID; diff --git a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiArtifactHash.java b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiArtifactHash.java index 9541055f8..898ee244a 100644 --- a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiArtifactHash.java +++ b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiArtifactHash.java @@ -27,6 +27,7 @@ public class DdiArtifactHash { * Default constructor. */ public DdiArtifactHash() { + // needed for json create } /** diff --git a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiChunk.java b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiChunk.java index 78de8591d..cf146b597 100644 --- a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiChunk.java +++ b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiChunk.java @@ -29,7 +29,7 @@ public class DdiChunk { private List artifacts; public DdiChunk() { - + // needed for json create } /** diff --git a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiConfig.java b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiConfig.java index 5ec1b4dde..0dfed6e79 100644 --- a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiConfig.java +++ b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiConfig.java @@ -34,8 +34,11 @@ public class DdiConfig { this.polling = polling; } + /** + * Constructor. + */ public DdiConfig() { - + // needed for json create. } public DdiPolling getPolling() { diff --git a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiControllerBase.java b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiControllerBase.java index 3f160157c..526227601 100644 --- a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiControllerBase.java +++ b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiControllerBase.java @@ -37,7 +37,7 @@ public class DdiControllerBase extends ResourceSupport { } public DdiControllerBase() { - + // needed for json create } public DdiConfig getConfig() { diff --git a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeployment.java b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeployment.java index f72083d7a..c7e364b36 100644 --- a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeployment.java +++ b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeployment.java @@ -23,8 +23,11 @@ public class DdiDeployment { private List chunks; + /** + * Constructor. + */ public DdiDeployment() { - + // needed for json create. } /** diff --git a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeploymentBase.java b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeploymentBase.java index 8f1116b1b..a058fd24a 100644 --- a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeploymentBase.java +++ b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeploymentBase.java @@ -21,10 +21,10 @@ public class DdiDeploymentBase extends ResourceSupport { @JsonProperty("id") @NotNull - private String deplyomentId; + private final String deplyomentId; @NotNull - private DdiDeployment deployment; + private final DdiDeployment deployment; /** * Constructor. @@ -35,14 +35,10 @@ public class DdiDeploymentBase extends ResourceSupport { * details. */ public DdiDeploymentBase(final String id, final DdiDeployment deployment) { - deplyomentId = id; + this.deplyomentId = id; this.deployment = deployment; } - public DdiDeploymentBase() { - - } - public DdiDeployment getDeployment() { return deployment; } diff --git a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiPolling.java b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiPolling.java index 489178be8..81427510a 100644 --- a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiPolling.java +++ b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiPolling.java @@ -30,11 +30,15 @@ public class DdiPolling { * between polls */ public DdiPolling(final String sleep) { - super(); this.sleep = sleep; } + /** + * Constructor. + * + */ public DdiPolling() { + // needed for json create } public String getSleep() { diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java index 91d07de37..788d1d8d8 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentfication.java @@ -36,7 +36,7 @@ import org.springframework.stereotype.Component; /** * - * + * A controller which handles the amqp authentfication. */ @Component public class AmqpControllerAuthentfication { diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index 19ceb123f..8906bc96c 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -138,6 +138,13 @@ public class AmqpMessageHandlerService extends BaseAmqpService { return onMessage(message, type, tenant, getRabbitTemplate().getConnectionFactory().getVirtualHost()); } + /** + * Executed on a authentication request. + * + * @param message + * the amqp message + * @return the rpc message back to supplier. + */ @RabbitListener(queues = "${hawkbit.dmf.rabbitmq.authenticationReceiverQueue}", containerFactory = "listenerContainerFactory") public Message onAuthenticationRequest(final Message message) { checkContentTypeJson(message); @@ -153,6 +160,19 @@ public class AmqpMessageHandlerService extends BaseAmqpService { } } + /** + * * Executed if a amqp message arrives. + * + * @param message + * the message + * @param type + * the type + * @param tenant + * the tenant + * @param virtualHost + * the virtual host + * @return the rpc message back to supplier. + */ public Message onMessage(final Message message, final String type, final String tenant, final String virtualHost) { checkContentTypeJson(message); final SecurityContext oldContext = SecurityContextHolder.getContext(); diff --git a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java index b9314ac27..b11d5a437 100644 --- a/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java +++ b/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/BaseAmqpService.java @@ -88,8 +88,7 @@ public class BaseAmqpService { return rabbitTemplate.getMessageConverter(); } - protected final String getStringHeaderKey(final Message message, final String key, - final String errorMessageIfNull) { + protected String getStringHeaderKey(final Message message, final String key, final String errorMessageIfNull) { final Map header = message.getMessageProperties().getHeaders(); final Object value = header.get(key); if (value == null) { @@ -117,4 +116,5 @@ public class BaseAmqpService { protected void cleanMessageHeaderProperties(final Message message) { message.getMessageProperties().getHeaders().remove(AbstractJavaTypeMapper.DEFAULT_CLASSID_FIELD_NAME); } + } diff --git a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java index ea6dccc7e..9053af8c8 100644 --- a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java +++ b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadArtifactRestApi.java @@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.ResponseBody; * */ @RequestMapping(MgmtRestConstants.SOFTWAREMODULE_V1_REQUEST_MAPPING) +@FunctionalInterface public interface MgmtDownloadArtifactRestApi { /** diff --git a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadRestApi.java b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadRestApi.java index 52cd1c991..ea179b830 100644 --- a/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadRestApi.java +++ b/hawkbit-mgmt-api/src/main/java/org/eclipse/hawkbit/mgmt/rest/api/MgmtDownloadRestApi.java @@ -20,6 +20,7 @@ import org.springframework.web.bind.annotation.ResponseBody; * */ @RequestMapping(MgmtRestConstants.DOWNLOAD_ID_V1_REQUEST_MAPPING_BASE) +@FunctionalInterface public interface MgmtDownloadRestApi { /** diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResource.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResource.java index 87a215183..b6f9f27c8 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResource.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDownloadResource.java @@ -15,6 +15,7 @@ import org.eclipse.hawkbit.artifact.repository.ArtifactRepository; import org.eclipse.hawkbit.artifact.repository.model.DbArtifact; import org.eclipse.hawkbit.cache.CacheConstants; import org.eclipse.hawkbit.cache.DownloadArtifactCache; +import org.eclipse.hawkbit.cache.DownloadType; import org.eclipse.hawkbit.mgmt.rest.api.MgmtDownloadRestApi; import org.eclipse.hawkbit.rest.util.RequestResponseContextHolder; import org.slf4j.Logger; @@ -73,14 +74,11 @@ public class MgmtDownloadResource implements MgmtDownloadRestApi { final DownloadArtifactCache artifactCache = (DownloadArtifactCache) cacheWrapper.get(); DbArtifact artifact = null; - switch (artifactCache.getDownloadType()) { - case BY_SHA1: - artifact = artifactRepository.getArtifactBySha1(artifactCache.getId()); - break; - default: + if (DownloadType.BY_SHA1.equals(artifactCache.getDownloadType())) { + artifact = artifactRepository.getArtifactBySha1(artifactCache.getId()); + } else { LOGGER.warn("Download Type {} not supported", artifactCache.getDownloadType()); - break; } if (artifact == null) { diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java index a2e7e5213..1784606bd 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DistributionSetManagement.java @@ -24,6 +24,7 @@ import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldExc import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetFilter; +import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder; import org.eclipse.hawkbit.repository.model.DistributionSetMetadata; import org.eclipse.hawkbit.repository.model.DistributionSetTag; import org.eclipse.hawkbit.repository.model.DistributionSetTagAssignmentResult; @@ -32,7 +33,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.SoftwareModuleType; import org.eclipse.hawkbit.repository.model.Tag; import org.eclipse.hawkbit.repository.model.Target; -import org.eclipse.hawkbit.repository.model.DistributionSetFilter.DistributionSetFilterBuilder; import org.hibernate.validator.constraints.NotEmpty; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -44,9 +44,6 @@ import org.springframework.security.access.prepost.PreAuthorize; */ public interface DistributionSetManagement { - // TODO rename/document the whole with details thing (document what the - // details are and maybe find a better name, e.g. with dependencies?) - /** * Assigns {@link SoftwareModule} to existing {@link DistributionSet}. * @@ -320,7 +317,6 @@ public interface DistributionSetManagement { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_REPOSITORY) List findDistributionSetsAll(Collection dist); - // TODO discuss: use enum instead of the true,false,null switch ? /** * finds all {@link DistributionSet}s. * diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutChangeEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutChangeEvent.java index 2ff739726..05960938f 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutChangeEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutChangeEvent.java @@ -8,7 +8,7 @@ */ package org.eclipse.hawkbit.repository.eventbus.event; -import org.eclipse.hawkbit.eventbus.event.AbstractEvent; +import org.eclipse.hawkbit.eventbus.event.DefaultEvent; /** * Event declaration for the UI to notify the UI that a rollout has been @@ -17,7 +17,7 @@ import org.eclipse.hawkbit.eventbus.event.AbstractEvent; * @author Michael Hirsch * */ -public class RolloutChangeEvent extends AbstractEvent { +public class RolloutChangeEvent extends DefaultEvent { private final Long rolloutId; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutGroupChangeEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutGroupChangeEvent.java index 5c36ab61f..686625d03 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutGroupChangeEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/RolloutGroupChangeEvent.java @@ -8,7 +8,7 @@ */ package org.eclipse.hawkbit.repository.eventbus.event; -import org.eclipse.hawkbit.eventbus.event.AbstractEvent; +import org.eclipse.hawkbit.eventbus.event.DefaultEvent; /** * Event declaration for the UI to notify the UI that a rollout has been @@ -17,7 +17,7 @@ import org.eclipse.hawkbit.eventbus.event.AbstractEvent; * @author Michael Hirsch * */ -public class RolloutGroupChangeEvent extends AbstractEvent { +public class RolloutGroupChangeEvent extends DefaultEvent { private final Long rolloutId; private final Long rolloutGroupId; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetAssignDistributionSetEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetAssignDistributionSetEvent.java index 077e05462..586a4b9d2 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetAssignDistributionSetEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetAssignDistributionSetEvent.java @@ -11,14 +11,14 @@ package org.eclipse.hawkbit.repository.eventbus.event; import java.net.URI; import java.util.Collection; -import org.eclipse.hawkbit.eventbus.event.AbstractEvent; +import org.eclipse.hawkbit.eventbus.event.DefaultEvent; import org.eclipse.hawkbit.repository.model.SoftwareModule; /** * Event that gets sent when a distribution set gets assigned to a target. * */ -public class TargetAssignDistributionSetEvent extends AbstractEvent { +public class TargetAssignDistributionSetEvent extends DefaultEvent { private final Collection softwareModules; private final String controllerId; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactDeleteFailedException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactDeleteFailedException.java index 7b7975d78..c7ed8637e 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactDeleteFailedException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactDeleteFailedException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Thrown if artifact deletion failed. @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public final class ArtifactDeleteFailedException extends SpServerRtException { +public final class ArtifactDeleteFailedException extends AbstractServerRtException { /** * */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactUploadFailedException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactUploadFailedException.java index d83f80e64..6f762b56c 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactUploadFailedException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ArtifactUploadFailedException.java @@ -9,14 +9,14 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * * * */ -public final class ArtifactUploadFailedException extends SpServerRtException { +public final class ArtifactUploadFailedException extends AbstractServerRtException { /** * diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/CancelActionNotAllowedException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/CancelActionNotAllowedException.java index 0a787e5bb..1afd994cf 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/CancelActionNotAllowedException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/CancelActionNotAllowedException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Thrown if cancelation of actions is performened where the action is not @@ -19,7 +19,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public final class CancelActionNotAllowedException extends SpServerRtException { +public final class CancelActionNotAllowedException extends AbstractServerRtException { /** * */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ConcurrentModificationException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ConcurrentModificationException.java index c2a3b4456..ec2691e52 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ConcurrentModificationException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ConcurrentModificationException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * {@link ConcurrentModificationException} is thrown when a given entity in's @@ -19,7 +19,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class ConcurrentModificationException extends SpServerRtException { +public class ConcurrentModificationException extends AbstractServerRtException { private static final long serialVersionUID = 1L; private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_CONCURRENT_MODIFICATION; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/DistributionSetCreationFailedMissingMandatoryModuleException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/DistributionSetCreationFailedMissingMandatoryModuleException.java index 0dc2f9752..936d3e5d2 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/DistributionSetCreationFailedMissingMandatoryModuleException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/DistributionSetCreationFailedMissingMandatoryModuleException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Thrown if DS creation failed. @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public final class DistributionSetCreationFailedMissingMandatoryModuleException extends SpServerRtException { +public final class DistributionSetCreationFailedMissingMandatoryModuleException extends AbstractServerRtException { /** * */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/DistributionSetTypeUndefinedException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/DistributionSetTypeUndefinedException.java index d3e10b213..8cf3c6162 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/DistributionSetTypeUndefinedException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/DistributionSetTypeUndefinedException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetType; @@ -21,7 +21,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSetType; * * */ -public class DistributionSetTypeUndefinedException extends SpServerRtException { +public class DistributionSetTypeUndefinedException extends AbstractServerRtException { /** * */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityAlreadyExistsException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityAlreadyExistsException.java index a38ec5bb6..73b14c57a 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityAlreadyExistsException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityAlreadyExistsException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * the {@link EntityAlreadyExistsException} is thrown when a entity is tried to @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class EntityAlreadyExistsException extends SpServerRtException { +public class EntityAlreadyExistsException extends AbstractServerRtException { private static final long serialVersionUID = 1L; private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_ENTITY_ALRREADY_EXISTS; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityLockedException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityLockedException.java index 1d55bdc34..23c372410 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityLockedException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityLockedException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * The {@link EntityLockedException} is thrown when an entity has been locked by @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class EntityLockedException extends SpServerRtException { +public class EntityLockedException extends AbstractServerRtException { private static final long serialVersionUID = 1L; private static final SpServerError THIS_ERROR = SpServerError.SP_ENTITY_LOCKED; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityNotFoundException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityNotFoundException.java index 280436d3b..ce1446f67 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityNotFoundException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityNotFoundException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * the {@link EntityNotFoundException} is thrown when a entity is tried find but @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class EntityNotFoundException extends SpServerRtException { +public class EntityNotFoundException extends AbstractServerRtException { private static final long serialVersionUID = 1L; private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_ENTITY_NOT_EXISTS; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityReadOnlyException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityReadOnlyException.java index 7908c4db5..f2686abb1 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityReadOnlyException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/EntityReadOnlyException.java @@ -9,13 +9,13 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * the {@link EntityReadOnlyException} is thrown when a entity is in read only * mode and a user tries to change it. */ -public class EntityReadOnlyException extends SpServerRtException { +public class EntityReadOnlyException extends AbstractServerRtException { private static final long serialVersionUID = 1L; private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_ENTITY_READ_ONLY; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ForceQuitActionNotAllowedException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ForceQuitActionNotAllowedException.java index 23b5f7067..83957739a 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ForceQuitActionNotAllowedException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ForceQuitActionNotAllowedException.java @@ -9,14 +9,14 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Thrown when force quitting an actions is not allowed. e.g. the action is not * active or it is not canceled before. * */ -public final class ForceQuitActionNotAllowedException extends SpServerRtException { +public final class ForceQuitActionNotAllowedException extends AbstractServerRtException { /** * */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/GridFSDBFileNotFoundException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/GridFSDBFileNotFoundException.java index d22fe2b6e..3f3c49e03 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/GridFSDBFileNotFoundException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/GridFSDBFileNotFoundException.java @@ -9,14 +9,14 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * * * */ -public final class GridFSDBFileNotFoundException extends SpServerRtException { +public final class GridFSDBFileNotFoundException extends AbstractServerRtException { /** * diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/IncompleteDistributionSetException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/IncompleteDistributionSetException.java index 51b95afbd..10bc5bba4 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/IncompleteDistributionSetException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/IncompleteDistributionSetException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Thrown if a distribution set is assigned to a a target that is incomplete @@ -19,7 +19,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public final class IncompleteDistributionSetException extends SpServerRtException { +public final class IncompleteDistributionSetException extends AbstractServerRtException { /** * */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InsufficientPermissionException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InsufficientPermissionException.java index e15ba43ee..d3802300a 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InsufficientPermissionException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InsufficientPermissionException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Exception which is thrown in case the current security context object does @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class InsufficientPermissionException extends SpServerRtException { +public class InsufficientPermissionException extends AbstractServerRtException { private static final long serialVersionUID = 1L; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidMD5HashException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidMD5HashException.java index c08673164..f6083a612 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidMD5HashException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidMD5HashException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Thrown if MD5 checksum check fails. @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class InvalidMD5HashException extends SpServerRtException { +public class InvalidMD5HashException extends AbstractServerRtException { /** * */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidSHA1HashException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidSHA1HashException.java index e4136cd82..4cc26c571 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidSHA1HashException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidSHA1HashException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Thrown if SHA1 checksum check fails. @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class InvalidSHA1HashException extends SpServerRtException { +public class InvalidSHA1HashException extends AbstractServerRtException { /** * */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidTargetAddressException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidTargetAddressException.java index 70b890483..160d5c07b 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidTargetAddressException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/InvalidTargetAddressException.java @@ -9,12 +9,12 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Exception which is thrown when trying to set an invalid target address. */ -public class InvalidTargetAddressException extends SpServerRtException { +public class InvalidTargetAddressException extends AbstractServerRtException { /** * diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiPartFileUploadException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiPartFileUploadException.java index e37786e19..7b554982e 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiPartFileUploadException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiPartFileUploadException.java @@ -9,13 +9,13 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Thrown if a multi part exception occurred. * */ -public final class MultiPartFileUploadException extends SpServerRtException { +public final class MultiPartFileUploadException extends AbstractServerRtException { private static final long serialVersionUID = 1L; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterSyntaxException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterSyntaxException.java index 268ab02ba..d46f6d827 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterSyntaxException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterSyntaxException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Exception used by the REST API in case of RSQL search filter query. @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class RSQLParameterSyntaxException extends SpServerRtException { +public class RSQLParameterSyntaxException extends AbstractServerRtException { /** * diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterUnsupportedFieldException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterUnsupportedFieldException.java index df58ecc8b..402a3eee7 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterUnsupportedFieldException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RSQLParameterUnsupportedFieldException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Exception used by the REST API in case of invalid field name in the rsql @@ -19,7 +19,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class RSQLParameterUnsupportedFieldException extends SpServerRtException { +public class RSQLParameterUnsupportedFieldException extends AbstractServerRtException { /** * diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RolloutIllegalStateException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RolloutIllegalStateException.java index f2920c18d..2f1937008 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RolloutIllegalStateException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/RolloutIllegalStateException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * the {@link RolloutIllegalStateException} is thrown when a rollout is changing @@ -17,7 +17,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * rollout, or trying to resume a already finished rollout. * */ -public class RolloutIllegalStateException extends SpServerRtException { +public class RolloutIllegalStateException extends AbstractServerRtException { private static final long serialVersionUID = 1L; private static final SpServerError THIS_ERROR = SpServerError.SP_ROLLOUT_ILLEGAL_STATE; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/TenantNotExistException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/TenantNotExistException.java index 95aab39a8..810054e93 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/TenantNotExistException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/TenantNotExistException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * the {@link TenantNotExistException} is thrown when e.g. a controller tries to @@ -20,7 +20,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class TenantNotExistException extends SpServerRtException { +public class TenantNotExistException extends AbstractServerRtException { private static final long serialVersionUID = 1L; private static final SpServerError THIS_ERROR = SpServerError.SP_REPO_TENANT_NOT_EXISTS; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyAttributeEntriesException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyAttributeEntriesException.java index 78da0b9f3..6004bc2e7 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyAttributeEntriesException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyAttributeEntriesException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Thrown if too many status entries have been inserted. @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public final class ToManyAttributeEntriesException extends SpServerRtException { +public final class ToManyAttributeEntriesException extends AbstractServerRtException { /** * */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyStatusEntriesException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyStatusEntriesException.java index 5d4367924..7b8f4a1b0 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyStatusEntriesException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/ToManyStatusEntriesException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Thrown if too many status entries have been inserted. @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public final class ToManyStatusEntriesException extends SpServerRtException { +public final class ToManyStatusEntriesException extends AbstractServerRtException { /** * */ diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/UnsupportedSoftwareModuleForThisDistributionSetException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/UnsupportedSoftwareModuleForThisDistributionSetException.java index 3726e3188..2ed76dfbc 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/UnsupportedSoftwareModuleForThisDistributionSetException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/UnsupportedSoftwareModuleForThisDistributionSetException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.repository.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.DistributionSetType; import org.eclipse.hawkbit.repository.model.SoftwareModule; @@ -23,7 +23,7 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; * * */ -public class UnsupportedSoftwareModuleForThisDistributionSetException extends SpServerRtException { +public class UnsupportedSoftwareModuleForThisDistributionSetException extends AbstractServerRtException { /** * */ diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/MessageNotReadableException.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/MessageNotReadableException.java index 3c5e0aee3..319ac9a38 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/MessageNotReadableException.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/MessageNotReadableException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.rest.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Exception which is thrown in case an request body is not well formaned and @@ -19,7 +19,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class MessageNotReadableException extends SpServerRtException { +public class MessageNotReadableException extends AbstractServerRtException { /** * diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java index 02a48ef78..81d70103b 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/ResponseExceptionHandler.java @@ -16,7 +16,7 @@ import javax.servlet.http.HttpServletRequest; import org.apache.commons.lang3.exception.ExceptionUtils; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; import org.eclipse.hawkbit.repository.exception.MultiPartFileUploadException; import org.eclipse.hawkbit.rest.json.model.ExceptionInfo; import org.slf4j.Logger; @@ -75,7 +75,7 @@ public class ResponseExceptionHandler { } /** - * method for handling exception of type SpServerRtException. Called by the + * method for handling exception of type AbstractServerRtException. Called by the * Spring-Framework for exception handling. * * @param request @@ -86,14 +86,14 @@ public class ResponseExceptionHandler { * @return the entity to be responded containing the exception information * as entity. */ - @ExceptionHandler(SpServerRtException.class) + @ExceptionHandler(AbstractServerRtException.class) public ResponseEntity handleSpServerRtExceptions(final HttpServletRequest request, final Exception ex) { logRequest(request, ex); final ExceptionInfo response = createExceptionInfo(ex); final HttpStatus responseStatus; - if (ex instanceof SpServerRtException) { - responseStatus = getStatusOrDefault(((SpServerRtException) ex).getError()); + if (ex instanceof AbstractServerRtException) { + responseStatus = getStatusOrDefault(((AbstractServerRtException) ex).getError()); } else { responseStatus = DEFAULT_RESPONSE_STATUS; } @@ -152,8 +152,8 @@ public class ResponseExceptionHandler { final ExceptionInfo response = new ExceptionInfo(); response.setMessage(ex.getMessage()); response.setExceptionClass(ex.getClass().getName()); - if (ex instanceof SpServerRtException) { - response.setErrorCode(((SpServerRtException) ex).getError().getKey()); + if (ex instanceof AbstractServerRtException) { + response.setErrorCode(((AbstractServerRtException) ex).getError().getKey()); } return response; diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterSyntaxErrorException.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterSyntaxErrorException.java index a8d476ac1..d43cec066 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterSyntaxErrorException.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterSyntaxErrorException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.rest.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Exception used by the REST API in case of invalid sort parameter syntax. @@ -18,7 +18,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class SortParameterSyntaxErrorException extends SpServerRtException { +public class SortParameterSyntaxErrorException extends AbstractServerRtException { /** * diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterUnsupportedDirectionException.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterUnsupportedDirectionException.java index b44b94917..6a79e8abe 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterUnsupportedDirectionException.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterUnsupportedDirectionException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.rest.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Exception used by the REST API in case of invalid sort parameter direction @@ -19,7 +19,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class SortParameterUnsupportedDirectionException extends SpServerRtException { +public class SortParameterUnsupportedDirectionException extends AbstractServerRtException { /** * diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterUnsupportedFieldException.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterUnsupportedFieldException.java index c9ce0dcdd..a00d245ab 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterUnsupportedFieldException.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/exception/SortParameterUnsupportedFieldException.java @@ -9,7 +9,7 @@ package org.eclipse.hawkbit.rest.exception; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Exception used by the REST API in case of invalid field name in the sort @@ -19,7 +19,7 @@ import org.eclipse.hawkbit.exception.SpServerRtException; * * */ -public class SortParameterUnsupportedFieldException extends SpServerRtException { +public class SortParameterUnsupportedFieldException extends AbstractServerRtException { /** * diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/FileSteamingFailedException.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/FileSteamingFailedException.java index abf7c0245..472c78c2a 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/FileSteamingFailedException.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/FileSteamingFailedException.java @@ -9,12 +9,12 @@ package org.eclipse.hawkbit.rest.util; import org.eclipse.hawkbit.exception.SpServerError; -import org.eclipse.hawkbit.exception.SpServerRtException; +import org.eclipse.hawkbit.exception.AbstractServerRtException; /** * Thrown if artifact content streaming to client failed. */ -public final class FileSteamingFailedException extends SpServerRtException { +public final class FileSteamingFailedException extends AbstractServerRtException { private static final long serialVersionUID = 1L; From 9bd47a5c555956265f0a0ffa13ac2e8c3930759a Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 5 Aug 2016 10:49:24 +0200 Subject: [PATCH 080/118] Added the message in the message.properties. Signed-off-by: Gaurav --- .../detailslayout/SoftwareModuleDetailsTable.java | 4 +--- .../ui/distributions/dstable/DistributionSetTable.java | 10 ++++------ hawkbit-ui/src/main/resources/messages.properties | 1 + hawkbit-ui/src/main/resources/messages_de.properties | 1 + hawkbit-ui/src/main/resources/messages_en.properties | 1 + 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java index 036b229df..a7adb8711 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/detailslayout/SoftwareModuleDetailsTable.java @@ -187,9 +187,7 @@ public class SoftwareModuleDetailsTable extends Table { final Set alreadyAssignedSwModules) { final SoftwareModule unAssignedSw = getSoftwareModule(event.getButton().getId(), alreadyAssignedSwModules); if (distributionSetManagement.isDistributionSetInUse(distributionSet)) { - uiNotification.displayValidationError( - String.format("Distribution set %s:%s is already assigned to targets and cannot be changed", - distributionSet.getName(), distributionSet.getVersion())); + uiNotification.displayValidationError(i18n.get("message.error.notification.ds.target.assigned",distributionSet.getName(), distributionSet.getVersion())); } else { final DistributionSet newDistributionSet = distributionSetManagement.unassignSoftwareModule(distributionSet, unAssignedSw); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index 1547ef11b..fc415f4de 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -334,9 +334,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable Date: Fri, 5 Aug 2016 10:51:11 +0200 Subject: [PATCH 081/118] Fix criticals sonar issues Signed-off-by: SirWayne --- .../hawkbit/artifact/FreePortFileWriter.java | 33 +++---- .../test/util/AbstractIntegrationTest.java | 2 +- .../util/JpaTestRepositoryManagement.java | 6 +- .../repository/test/util/TestdataFactory.java | 13 +-- .../test/util/WithSpringAuthorityRule.java | 99 +++++-------------- .../common/tagdetails/AbstractTagToken.java | 6 ++ 6 files changed, 57 insertions(+), 102 deletions(-) diff --git a/hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/FreePortFileWriter.java b/hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/FreePortFileWriter.java index 257c85076..0e957d83a 100644 --- a/hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/FreePortFileWriter.java +++ b/hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/FreePortFileWriter.java @@ -14,7 +14,7 @@ import java.net.ServerSocket; /** * - * + * Look for a free port. */ public class FreePortFileWriter { @@ -24,7 +24,9 @@ public class FreePortFileWriter { /** * @param from + * port range from (start point) * @param to + * port range to (end point) */ public FreePortFileWriter(final int from, final int to, final String filePortPath) { this.from = from; @@ -51,23 +53,20 @@ public class FreePortFileWriter { portFile.getParentFile().mkdirs(); if (portFile.exists()) { return false; - } else { - boolean isFree = false; - final ServerSocket sock = new ServerSocket(); - sock.setReuseAddress(true); - sock.bind(new InetSocketAddress(port)); - if (portFile.createNewFile()) { - portFile.deleteOnExit(); - isFree = true; - } - sock.close(); - // is free: - return isFree; - // We rely on an exception thrown to determine availability or - // not availability. } - } catch (final Exception e) { - // not free. + boolean isFree = false; + final ServerSocket sock = new ServerSocket(); + sock.setReuseAddress(true); + sock.bind(new InetSocketAddress(port)); + if (portFile.createNewFile()) { + portFile.deleteOnExit(); + isFree = true; + } + sock.close(); + return isFree; + // We rely on an exception thrown to determine availability or + // not availability and don't want to log the exception. + } catch (@SuppressWarnings({ "squid:S2221", "squid:S1166" }) final Exception e) { return false; } } diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java index 3d09fabc3..650a16c96 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/AbstractIntegrationTest.java @@ -223,7 +223,7 @@ public abstract class AbstractIntegrationTest implements EnvironmentAware { createTestdatabaseAndStart(); } - private static void createTestdatabaseAndStart() { + private static synchronized void createTestdatabaseAndStart() { if ("MYSQL".equals(System.getProperty("spring.jpa.database"))) { tesdatabase = new CIMySqlTestDatabase(); tesdatabase.before(); diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/JpaTestRepositoryManagement.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/JpaTestRepositoryManagement.java index eae0b9a7d..7d7908d6e 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/JpaTestRepositoryManagement.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/JpaTestRepositoryManagement.java @@ -13,11 +13,14 @@ import java.util.List; import org.eclipse.hawkbit.cache.TenantAwareCacheManager; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.security.SystemSecurityContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; public class JpaTestRepositoryManagement implements TestRepositoryManagement { + private static final Logger LOGGER = LoggerFactory.getLogger(JpaTestRepositoryManagement.class); @Autowired private TenantAwareCacheManager cacheManager; @@ -28,6 +31,7 @@ public class JpaTestRepositoryManagement implements TestRepositoryManagement { private SystemManagement systemManagement; @Override + @Transactional public void clearTestRepository() { deleteAllRepos(); cacheManager.getDirectCacheNames().forEach(name -> cacheManager.getDirectCache(name).clear()); @@ -43,7 +47,7 @@ public class JpaTestRepositoryManagement implements TestRepositoryManagement { return null; }); } catch (final Exception e) { - e.printStackTrace(); + LOGGER.error("Error hile delete tenant", e); } }); } diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java index 81e2c1daf..34031639d 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/TestdataFactory.java @@ -10,10 +10,10 @@ package org.eclipse.hawkbit.repository.test.util; import java.io.InputStream; import java.nio.charset.Charset; +import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Random; import java.util.UUID; import org.apache.commons.io.IOUtils; @@ -191,16 +191,17 @@ public class TestdataFactory { public DistributionSet createDistributionSet(final String prefix, final String version, final boolean isRequiredMigrationStep) { - final SoftwareModule appMod = softwareManagement.createSoftwareModule(entityFactory.generateSoftwareModule( - findOrCreateSoftwareModuleType(SM_TYPE_APP, Integer.MAX_VALUE), prefix + SM_TYPE_APP, - version + "." + new Random().nextInt(100), LOREM.words(20), prefix + " vendor Limited, California")); + final SoftwareModule appMod = softwareManagement.createSoftwareModule( + entityFactory.generateSoftwareModule(findOrCreateSoftwareModuleType(SM_TYPE_APP, Integer.MAX_VALUE), + prefix + SM_TYPE_APP, version + "." + new SecureRandom().nextInt(100), LOREM.words(20), + prefix + " vendor Limited, California")); final SoftwareModule runtimeMod = softwareManagement .createSoftwareModule(entityFactory.generateSoftwareModule(findOrCreateSoftwareModuleType(SM_TYPE_RT), - prefix + "app runtime", version + "." + new Random().nextInt(100), LOREM.words(20), + prefix + "app runtime", version + "." + new SecureRandom().nextInt(100), LOREM.words(20), prefix + " vendor GmbH, Stuttgart, Germany")); final SoftwareModule osMod = softwareManagement .createSoftwareModule(entityFactory.generateSoftwareModule(findOrCreateSoftwareModuleType(SM_TYPE_OS), - prefix + " Firmware", version + "." + new Random().nextInt(100), LOREM.words(20), + prefix + " Firmware", version + "." + new SecureRandom().nextInt(100), LOREM.words(20), prefix + " vendor Limited Inc, California")); return distributionSetManagement diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithSpringAuthorityRule.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithSpringAuthorityRule.java index a2bc90555..7c588febe 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithSpringAuthorityRule.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/WithSpringAuthorityRule.java @@ -28,16 +28,12 @@ import org.springframework.security.core.context.SecurityContextHolder; public class WithSpringAuthorityRule implements TestRule { - /* - * (non-Javadoc) - * - * @see org.junit.rules.TestRule#apply(org.junit.runners.model.Statement, - * org.junit.runner.Description) - */ @Override public Statement apply(final Statement base, final Description description) { return new Statement() { @Override + // throwable comes from jnuit evaluate signature + @SuppressWarnings("squid:S00112") public void evaluate() throws Throwable { final SecurityContext oldContext = before(description); try { @@ -49,7 +45,7 @@ public class WithSpringAuthorityRule implements TestRule { }; } - private SecurityContext before(final Description description) throws Throwable { + private SecurityContext before(final Description description) { final SecurityContext oldContext = SecurityContextHolder.getContext(); WithUser annotation = description.getAnnotation(WithUser.class); if (annotation == null) { @@ -63,19 +59,14 @@ public class WithSpringAuthorityRule implements TestRule { } return oldContext; } - - /** - * @param annotation - */ + private void setSecurityContext(final WithUser annotation) { SecurityContextHolder.setContext(new SecurityContext() { - /** - * - */ private static final long serialVersionUID = 1L; @Override public void setAuthentication(final Authentication authentication) { + // nothing todo } @Override @@ -113,7 +104,8 @@ public class WithSpringAuthorityRule implements TestRule { if (addPermission) { allPermissions.add(permissionName); } - } catch (IllegalArgumentException | IllegalAccessException e) { + // don't want to log this exceptions. + } catch (@SuppressWarnings("squid:S1166") IllegalArgumentException | IllegalAccessException e) { // nope } } @@ -129,18 +121,17 @@ public class WithSpringAuthorityRule implements TestRule { private void after(final SecurityContext oldContext) { SecurityContextHolder.setContext(oldContext); } - + /** * Clears the current security context. */ - public void clear() - { + public void clear() { SecurityContextHolder.clearContext(); } /** * @param callable - * @return + * @return the callable result * @throws Exception */ public T runAsPrivileged(final Callable callable) throws Exception { @@ -151,7 +142,7 @@ public class WithSpringAuthorityRule implements TestRule { * * @param withUser * @param callable - * @return + * @return callable result * @throws Exception */ public T runAs(final WithUser withUser, final Callable callable) throws Exception { @@ -170,7 +161,7 @@ public class WithSpringAuthorityRule implements TestRule { public static WithUser withUser(final String principal, final String... authorities) { return withUserAndTenant(principal, "default", true, true, authorities); } - + public static WithUser withUser(final String principal, final boolean allSpPermision, final String... authorities) { return withUserAndTenant(principal, "default", true, allSpPermision, authorities); } @@ -185,6 +176,15 @@ public class WithSpringAuthorityRule implements TestRule { public static WithUser withUserAndTenant(final String principal, final String tenant, final boolean autoCreateTenant, final boolean allSpPermission, final String... authorities) { + return createWithUser(principal, tenant, autoCreateTenant, allSpPermission, authorities); + } + + private static WithUser privilegedUser() { + return createWithUser("bumlux", "default", true, true, new String[] { "ROLE_CONTROLLER" }); + } + + private static WithUser createWithUser(final String principal, final String tenant, final boolean autoCreateTenant, + final boolean allSpPermission, final String... authorities) { return new WithUser() { @Override @@ -214,7 +214,7 @@ public class WithSpringAuthorityRule implements TestRule { @Override public String[] removeFromAllPermission() { - return null; + return new String[0]; } @Override @@ -222,65 +222,10 @@ public class WithSpringAuthorityRule implements TestRule { return tenant; } - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.WithUser#autoCreateTenant() - */ @Override public boolean autoCreateTenant() { return autoCreateTenant; } }; } - - private static WithUser privilegedUser() { - return new WithUser() { - - @Override - public Class annotationType() { - return WithUser.class; - } - - @Override - public String principal() { - return "bumlux"; - } - - @Override - public String credentials() { - return null; - } - - @Override - public String[] authorities() { - return new String[] { "ROLE_CONTROLLER" }; - } - - @Override - public boolean allSpPermissions() { - return true; - } - - @Override - public String[] removeFromAllPermission() { - return null; - } - - @Override - public String tenantId() { - return "default"; - } - - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.WithUser#autoCreateTenant() - */ - @Override - public boolean autoCreateTenant() { - return true; - } - }; - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java index 042492613..2160bdac2 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java @@ -43,6 +43,9 @@ import com.vaadin.ui.themes.ValoTheme; /** * Abstract class for target/ds tag token layout. + * + * @param + * the special entity */ public abstract class AbstractTagToken implements Serializable { @@ -75,6 +78,9 @@ public abstract class AbstractTagToken implements Serializ @Autowired protected ManagementUIState managementUIState; + // BaseEntity implements Serializable so this entity is serializable. Maybe + // a sonar bug + @SuppressWarnings("squid:S1948") protected T selectedEntity; @PostConstruct From 41e7c16713f61faaec6e1fe647322827ba0b8b75 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Fri, 5 Aug 2016 11:29:14 +0200 Subject: [PATCH 082/118] Fix criticals sonar issues Signed-off-by: SirWayne --- .../test/util/FreePortFileWriter.java | 34 +++++++++---------- 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/FreePortFileWriter.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/FreePortFileWriter.java index 149cdf2b5..635cc9d6e 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/FreePortFileWriter.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/util/FreePortFileWriter.java @@ -14,7 +14,7 @@ import java.net.ServerSocket; /** * - * + * Look for a free port. */ public class FreePortFileWriter { @@ -24,7 +24,9 @@ public class FreePortFileWriter { /** * @param from + * port range from (start point) * @param to + * port range to (end point) */ public FreePortFileWriter(final int from, final int to, final String filePortPath) { this.from = from; @@ -51,25 +53,21 @@ public class FreePortFileWriter { portFile.getParentFile().mkdirs(); if (portFile.exists()) { return false; - } else { - boolean isFree = false; - final ServerSocket sock = new ServerSocket(); - sock.setReuseAddress(true); - sock.bind(new InetSocketAddress(port)); - if (portFile.createNewFile()) { - portFile.deleteOnExit(); - isFree = true; - } - sock.close(); - // is free: - return isFree; - // We rely on an exception thrown to determine availability or - // not availability. } - } catch (final Exception e) { - // not free. + boolean isFree = false; + final ServerSocket sock = new ServerSocket(); + sock.setReuseAddress(true); + sock.bind(new InetSocketAddress(port)); + if (portFile.createNewFile()) { + portFile.deleteOnExit(); + isFree = true; + } + sock.close(); + return isFree; + // We rely on an exception thrown to determine availability or + // not availability and don't want to log the exception. + } catch (@SuppressWarnings({ "squid:S2221", "squid:S1166" }) final Exception e) { return false; } } - } From 89605b0984beb72525476fa7eb88ddbff4ab0959 Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Fri, 5 Aug 2016 12:42:03 +0200 Subject: [PATCH 083/118] Changed error and how it is connected to current page Signed-off-by: Jonathan Philip Knoblauch --- .../hawkbit/ui/components/HawkbitUIErrorHandler.java | 2 +- .../ui/management/targettable/BulkUploadHandler.java | 12 +++--------- .../ui/management/targettable/TargetTableHeader.java | 1 - 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index 56bcba421..a860b7ff4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -68,7 +68,7 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { return Optional.fromNullable(errorOrigin.getUI().getPage()); } - return Optional.absent(); + return Optional.of(Page.getCurrent()); } protected HawkbitErrorNotificationMessage buildNotification(final Throwable exception) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index 44b3d2e50..0fe512334 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -22,7 +22,6 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.concurrent.Executor; import org.eclipse.hawkbit.repository.DeploymentManagement; @@ -100,8 +99,6 @@ public class BulkUploadHandler extends CustomComponent final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout; - private TargetTableHeader targetTableHeader; - private transient EntityFactory entityFactory; /** @@ -225,9 +222,9 @@ public class BulkUploadHandler extends CustomComponent } catch (final IOException e) { LOG.error("Error reading file {}", tempFile.getName(), e); } catch (final RuntimeException e) { - Optional.ofNullable(UI.getCurrent()).ifPresent(error -> UI.getCurrent().getErrorHandler() - .error(new ConnectorErrorEvent(targetTableHeader, e))); - + if (UI.getCurrent() != null) { + UI.getCurrent().getErrorHandler().error(new com.vaadin.server.ErrorEvent(e)); + } } finally { updateBulkUpload(); doAssignments(); @@ -465,7 +462,4 @@ public class BulkUploadHandler extends CustomComponent } } - public void setTargetBulkUpdateWindowLayout(final TargetTableHeader targetTableHeader) { - this.targetTableHeader = targetTableHeader; - } } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java index 760332e09..16dc584ed 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetTableHeader.java @@ -82,7 +82,6 @@ public class TargetTableHeader extends AbstractTableHeader { // creating add window for adding new target targetAddUpdateWindow.init(); targetBulkUpdateWindow.init(); - targetBulkUpdateWindow.getBulkUploader().setTargetBulkUpdateWindowLayout(this); onLoadRestoreState(); } From 06f64da6d5884beda70e0f2bdda87c976ac4a611 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 5 Aug 2016 13:04:56 +0200 Subject: [PATCH 084/118] refactor test using ClassPath from guava Signed-off-by: Michael Hirsch --- .../hawkbit-repository-api/pom.xml | 19 ++--- ...gementMethodPreAuthorizeAnnotatedTest.java | 81 ++----------------- 2 files changed, 14 insertions(+), 86 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/pom.xml b/hawkbit-repository/hawkbit-repository-api/pom.xml index 0a3f541d9..ce9b47a3d 100644 --- a/hawkbit-repository/hawkbit-repository-api/pom.xml +++ b/hawkbit-repository/hawkbit-repository-api/pom.xml @@ -1,13 +1,5 @@ - + 4.0.0 @@ -40,7 +32,7 @@ org.springframework.hateoas spring-hateoas - + org.springframework.boot @@ -64,5 +56,10 @@ fest-assert test + + com.google.guava + guava + test + \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java index a827b36e7..1a0d85d30 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java +++ b/hawkbit-repository/hawkbit-repository-api/src/test/java/org/eclipse/hawkbit/repository/RepositoryManagementMethodPreAuthorizeAnnotatedTest.java @@ -10,24 +10,21 @@ package org.eclipse.hawkbit.repository; import static org.fest.assertions.Assertions.assertThat; -import java.io.File; -import java.io.FileFilter; import java.io.IOException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.net.URI; import java.net.URISyntaxException; -import java.net.URL; -import java.util.ArrayList; -import java.util.Enumeration; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.regex.Pattern; +import java.util.stream.Collectors; import org.junit.Test; import org.springframework.security.access.prepost.PreAuthorize; +import com.google.common.reflect.ClassPath; + import ru.yandex.qatools.allure.annotations.Description; import ru.yandex.qatools.allure.annotations.Features; import ru.yandex.qatools.allure.annotations.Stories; @@ -83,38 +80,11 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { } } - /** - * Finds all interfaces in a given packages which matches the given filter. - * - * @param p - * the package to search for interfaces in - * @param includeFilter - * the pattern which interfaces class names should be included - * @return a list of loaded interfaces in a specific package and matches the - * given filter - * @throws URISyntaxException - * @throws IOException - * @throws ClassNotFoundException - */ private List> findInterfacesInPackage(final Package p, final Pattern includeFilter) throws URISyntaxException, IOException, ClassNotFoundException { - final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - final Enumeration resources = classLoader.getResources(p.getName().replace(".", "/")); - final RegexIncludeInterfaceFileCollector regexIncludeInterfaceFileCollector = new RegexIncludeInterfaceFileCollector( - p, includeFilter); - while (resources.hasMoreElements()) { - listFilesInPackage(resources.nextElement(), regexIncludeInterfaceFileCollector); - } - return regexIncludeInterfaceFileCollector.getInterfaceClasses(); - } - - private void listFilesInPackage(final URL resource, final RegexIncludeInterfaceFileCollector clazzCollector) - throws URISyntaxException { - final String packagePath = new URI(resource.toString()).getPath(); - if (packagePath != null) { - final File packageDirectory = new File(packagePath); - packageDirectory.listFiles(clazzCollector); - } + return ClassPath.from(Thread.currentThread().getContextClassLoader()).getTopLevelClasses(p.getName()).stream() + .filter(clazzInfo -> includeFilter.matcher(clazzInfo.getSimpleName()).matches()) + .map(clazzInfo -> clazzInfo.load()).filter(clazz -> clazz.isInterface()).collect(Collectors.toList()); } private static Method getMethod(final Class clazz, final String methodName, final Class... parameterTypes) { @@ -124,43 +94,4 @@ public class RepositoryManagementMethodPreAuthorizeAnnotatedTest { throw new RuntimeException(e.getMessage(), e); } } - - private static final class RegexIncludeInterfaceFileCollector implements FileFilter { - - private final List> interfaceClasses = new ArrayList<>(); - private final Pattern includeFilter; - private final Package basePackage; - - public RegexIncludeInterfaceFileCollector(final Package basePackage, final Pattern pattern) { - this.basePackage = basePackage; - this.includeFilter = pattern; - } - - @Override - public boolean accept(final File pathname) { - final String classNameWithExtension = pathname.getName(); - final int indexOfExtension = classNameWithExtension.indexOf(".class"); - if (indexOfExtension == -1) { - return false; - } - final String classNameWithoutExtension = classNameWithExtension.substring(0, indexOfExtension); - if (!includeFilter.matcher(classNameWithoutExtension).matches()) { - return false; - } - - try { - final Class classInPackage = Class.forName(basePackage.getName() + "." + classNameWithoutExtension); - if (classInPackage.isInterface()) { - interfaceClasses.add(classInPackage); - } - } catch (final ClassNotFoundException e) { - // don't need to handle here - } - return false; - } - - public List> getInterfaceClasses() { - return interfaceClasses; - } - } } From cf0ed6d82845715e36f3fc1147e7fdb25e621007 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 5 Aug 2016 13:09:24 +0200 Subject: [PATCH 085/118] remove guava from test dependencies Signed-off-by: Michael Hirsch --- hawkbit-repository/hawkbit-repository-api/pom.xml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/pom.xml b/hawkbit-repository/hawkbit-repository-api/pom.xml index ce9b47a3d..ccccaf038 100644 --- a/hawkbit-repository/hawkbit-repository-api/pom.xml +++ b/hawkbit-repository/hawkbit-repository-api/pom.xml @@ -56,10 +56,5 @@ fest-assert test - - com.google.guava - guava - test - \ No newline at end of file From 1e00439f3c29f1a48994f768f59399d33c4989d8 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 5 Aug 2016 13:13:46 +0200 Subject: [PATCH 086/118] add new line Signed-off-by: Michael Hirsch --- .../java/org/eclipse/hawkbit/repository/SystemManagement.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java index e30009258..cd414b09a 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/SystemManagement.java @@ -93,4 +93,4 @@ public interface SystemManagement { @PreAuthorize(SpringEvalExpressions.HAS_AUTH_TENANT_CONFIGURATION) TenantMetaData updateTenantMetadata(@NotNull TenantMetaData metaData); -} \ No newline at end of file +} From 431143133b833764b61dcc1dd79078dc9222e2ae Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 5 Aug 2016 13:19:29 +0200 Subject: [PATCH 087/118] fix license header Signed-off-by: Michael Hirsch --- hawkbit-repository/hawkbit-repository-api/pom.xml | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/pom.xml b/hawkbit-repository/hawkbit-repository-api/pom.xml index ccccaf038..e809ce29d 100644 --- a/hawkbit-repository/hawkbit-repository-api/pom.xml +++ b/hawkbit-repository/hawkbit-repository-api/pom.xml @@ -1,5 +1,13 @@ - + 4.0.0 From f3f9dbc665a19b0a23c81eed329c709984eb0362 Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Fri, 5 Aug 2016 13:50:46 +0200 Subject: [PATCH 088/118] Added method to sync after upload Signed-off-by: Jonathan Philip Knoblauch --- .../targettable/BulkUploadHandler.java | 35 ++++++++++++------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index 0fe512334..6ecaca255 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -226,14 +226,26 @@ public class BulkUploadHandler extends CustomComponent UI.getCurrent().getErrorHandler().error(new com.vaadin.server.ErrorEvent(e)); } } finally { - updateBulkUpload(); - doAssignments(); - eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_UPLOAD_COMPLETED)); - // Clearing after assignments are done - managementUIState.getTargetTableFilters().getBulkUpload().getTargetsCreated().clear(); - resetCounts(); deleteFile(); } + syncCountAfterUpload(); + doAssignments(); + eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_UPLOAD_COMPLETED)); + // Clearing after assignments are done + managementUIState.getTargetTableFilters().getBulkUpload().getTargetsCreated().clear(); + resetCounts(); + } + + private void syncCountAfterUpload() { + if (managementUIState.getTargetTableFilters().getBulkUpload() + .getSucessfulUploadCount() != successfullTargetCount) { + managementUIState.getTargetTableFilters().getBulkUpload() + .setSucessfulUploadCount(successfullTargetCount); + eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_TARGET_CREATED)); + } + if (managementUIState.getTargetTableFilters().getBulkUpload().getFailedUploadCount() != failedTargetCount) { + managementUIState.getTargetTableFilters().getBulkUpload().setSucessfulUploadCount(failedTargetCount); + } } private double getTotalNumberOfLines() { @@ -284,16 +296,13 @@ public class BulkUploadHandler extends CustomComponent if (Math.abs(next - 0.1) < 0.00001 || current - next >= 0 || next - current >= 0.05 || Math.abs(next - 1) < 0.00001) { managementUIState.getTargetTableFilters().getBulkUpload().setProgressBarCurrentValue(next); - updateBulkUpload(); + managementUIState.getTargetTableFilters().getBulkUpload() + .setSucessfulUploadCount(successfullTargetCount); + managementUIState.getTargetTableFilters().getBulkUpload().setFailedUploadCount(failedTargetCount); + eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_TARGET_CREATED)); } } - private void updateBulkUpload() { - managementUIState.getTargetTableFilters().getBulkUpload().setSucessfulUploadCount(successfullTargetCount); - managementUIState.getTargetTableFilters().getBulkUpload().setFailedUploadCount(failedTargetCount); - eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_TARGET_CREATED)); - } - private void doAssignments() { final StringBuilder errorMessage = new StringBuilder(); String dsAssignmentFailedMsg = null; From 222f06d9bb961208a35027887f5b2d6055c9d2d8 Mon Sep 17 00:00:00 2001 From: Dominic Schabel Date: Fri, 5 Aug 2016 14:12:27 +0200 Subject: [PATCH 089/118] JavaDoc comments added and method visibility raised to public Signed-off-by: Dominic Schabel --- .../jpa/model/EntityInterceptorListener.java | 57 ++++++++++++++++--- 1 file changed, 49 insertions(+), 8 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java index 1e9c39237..c3a4e6552 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java @@ -27,43 +27,84 @@ import org.eclipse.hawkbit.repository.model.EntityInterceptor; */ public class EntityInterceptorListener { + /** + * Callback for lifecyle event pre persist. + * + * @param entity + * the JPA entity which this listener is associated with + */ @PrePersist - protected void prePersist(final Object entity) { + public void prePersist(final Object entity) { notifyAll(interceptor -> interceptor.prePersist(entity)); } + /** + * Callback for lifecyle event post persist. + * + * @param entity + * the JPA entity which this listener is associated with + */ @PostPersist - protected void postPersist(final Object entity) { + public void postPersist(final Object entity) { notifyAll(interceptor -> interceptor.postPersist(entity)); } + /** + * Callback for lifecyle event post remove. + * + * @param entity + * the JPA entity which this listener is associated with + */ @PostRemove - protected void postRemove(final Object entity) { + public void postRemove(final Object entity) { notifyAll(interceptor -> interceptor.postRemove(entity)); } + /** + * Callback for lifecyle event pre remove. + * + * @param entity + * the JPA entity which this listener is associated with + */ @PreRemove - protected void preRemove(final Object entity) { + public void preRemove(final Object entity) { notifyAll(interceptor -> interceptor.preRemove(entity)); } + /** + * Callback for lifecyle event post load. + * + * @param entity + * the JPA entity which this listener is associated with + */ @PostLoad - protected void postLoad(final Object entity) { + public void postLoad(final Object entity) { notifyAll(interceptor -> interceptor.postLoad(entity)); } + /** + * Callback for lifecyle event pre update. + * + * @param entity + * the JPA entity which this listener is associated with + */ @PreUpdate - protected void preUpdate(final Object entity) { + public void preUpdate(final Object entity) { notifyAll(interceptor -> interceptor.preUpdate(entity)); } + /** + * Callback for lifecyle event post update. + * + * @param entity + * the JPA entity which this listener is associated with + */ @PostUpdate - protected void postUpdate(final Object entity) { + public void postUpdate(final Object entity) { notifyAll(interceptor -> interceptor.postUpdate(entity)); } private void notifyAll(final Consumer action) { EntityInterceptorHolder.getInstance().getEntityInterceptors().forEach(action); } - } From 59490d80cdc1db1713697ab632c08fa052098f31 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Fri, 5 Aug 2016 14:26:32 +0200 Subject: [PATCH 090/118] Fix sonar issues Signed-off-by: SirWayne --- .../org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java index b7423e899..9c4c43ad2 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/DeviceSimulatorUpdater.java @@ -197,7 +197,7 @@ public class DeviceSimulatorUpdater { return result; } - private boolean isErrorResponse(final UpdateStatus status) { + private static boolean isErrorResponse(final UpdateStatus status) { if (status == null) { return false; } From c71cf4852ab53de90ecd3d11fab820aca0ee7d5d Mon Sep 17 00:00:00 2001 From: SirWayne Date: Fri, 5 Aug 2016 14:58:17 +0200 Subject: [PATCH 091/118] fix sonar issues Signed-off-by: SirWayne --- .../jpa/model/EntityInterceptorListener.java | 2 +- .../eclipse/hawkbit/rest/util/ByteRange.java | 14 ++----- .../artifacts/smtype/SMTypeFilterButtons.java | 10 +++-- .../upload/UploadConfirmationwindow.java | 38 ++++++++----------- .../tagdetails/DistributionTagToken.java | 15 +------- 5 files changed, 26 insertions(+), 53 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java index c3a4e6552..75f1411ef 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityInterceptorListener.java @@ -104,7 +104,7 @@ public class EntityInterceptorListener { notifyAll(interceptor -> interceptor.postUpdate(entity)); } - private void notifyAll(final Consumer action) { + private static void notifyAll(final Consumer action) { EntityInterceptorHolder.getInstance().getEntityInterceptors().forEach(action); } } diff --git a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/ByteRange.java b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/ByteRange.java index 667fc197d..0811ac312 100644 --- a/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/ByteRange.java +++ b/hawkbit-rest-core/src/main/java/org/eclipse/hawkbit/rest/util/ByteRange.java @@ -69,13 +69,10 @@ public class ByteRange { return total; } - /* - * (non-Javadoc) - * - * @see java.lang.Object#hashCode() - */ @Override - public int hashCode() { // NOSONAR - as this is generated + // NOSONAR - as this is generated + @SuppressWarnings("squid:S864") + public int hashCode() { final int prime = 31; int result = 1; result = prime * result + (int) (end ^ end >>> 32); @@ -85,11 +82,6 @@ public class ByteRange { return result; } - /* - * (non-Javadoc) - * - * @see java.lang.Object#equals(java.lang.Object) - */ @Override public boolean equals(final Object obj) { // NOSONAR - as this is generated if (this == obj) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterButtons.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterButtons.java index d627a6dd0..88a9fa779 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterButtons.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/smtype/SMTypeFilterButtons.java @@ -8,7 +8,10 @@ */ package org.eclipse.hawkbit.ui.artifacts.smtype; +import java.util.EnumSet; + import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent; +import org.eclipse.hawkbit.ui.artifacts.event.SoftwareModuleTypeEvent.SoftwareModuleTypeEnum; import org.eclipse.hawkbit.ui.artifacts.event.UploadArtifactUIEvent; import org.eclipse.hawkbit.ui.artifacts.event.UploadViewAcceptCriteria; import org.eclipse.hawkbit.ui.artifacts.state.ArtifactUploadState; @@ -46,12 +49,11 @@ public class SMTypeFilterButtons extends AbstractFilterButtons { @EventBusListenerMethod(scope = EventScope.SESSION) void onEvent(final SoftwareModuleTypeEvent event) { - if (event.getSoftwareModuleTypeEnum() == SoftwareModuleTypeEvent.SoftwareModuleTypeEnum.ADD_SOFTWARE_MODULE_TYPE - || event.getSoftwareModuleTypeEnum() == SoftwareModuleTypeEvent.SoftwareModuleTypeEnum.UPDATE_SOFTWARE_MODULE_TYPE - || event.getSoftwareModuleTypeEnum() == SoftwareModuleTypeEvent.SoftwareModuleTypeEnum.DELETE_SOFTWARE_MODULE_TYPE - && event.getSoftwareModuleType() != null) { + if (event.getSoftwareModuleType() != null + && EnumSet.allOf(SoftwareModuleTypeEnum.class).contains(event.getSoftwareModuleTypeEnum())) { refreshTable(); } + } @EventBusListenerMethod(scope = EventScope.SESSION) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java index 8455dea69..915aee48a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadConfirmationwindow.java @@ -108,7 +108,7 @@ public class UploadConfirmationwindow implements Button.ClickListener { private UploadResultWindow currentUploadResultWindow; - private int redErrorLabelCount = 0; + private int redErrorLabelCount; private final ArtifactUploadState artifactUploadState; @@ -353,11 +353,8 @@ public class UploadConfirmationwindow implements Button.ClickListener { * label * @return Boolean */ - private Boolean isWarningIcon(final Label icon) { - if (icon.isVisible() && !icon.getStyleName().contains(SPUIStyleDefinitions.ERROR_LABEL)) { - return true; - } - return false; + private static Boolean isWarningIcon(final Label icon) { + return !isErrorIcon(icon); } /** @@ -367,14 +364,11 @@ public class UploadConfirmationwindow implements Button.ClickListener { * label * @return Boolean */ - private Boolean isErrorIcon(final Label icon) { - if (icon.isVisible() && icon.getStyleName().contains(SPUIStyleDefinitions.ERROR_LABEL)) { - return true; - } - return false; + private static Boolean isErrorIcon(final Label icon) { + return icon.isVisible() && icon.getStyleName().contains(SPUIStyleDefinitions.ERROR_LABEL); } - private Label getWarningLabel() { + private static Label getWarningLabel() { final Label warningIconLabel = new Label(); warningIconLabel.addStyleName(ValoTheme.LABEL_SMALL); warningIconLabel.setHeightUndefined(); @@ -436,7 +430,7 @@ public class UploadConfirmationwindow implements Button.ClickListener { private void hideErrorIcon(final Label warningLabel, final int errorLabelCount, final int duplicateCount, final Label errorLabel, final String oldFileName, final Long currentSwId) { - if (warningLabel == null && (errorLabelCount > 1 || duplicateCount == 1 && errorLabelCount == 1)) { + if (warningLabel == null && (errorLabelCount > 1 || (duplicateCount == 1 && errorLabelCount == 1))) { final ArtifactManagement artifactManagement = SpringContextHelper.getBean(ArtifactManagement.class); final List artifactList = artifactManagement.findByFilenameAndSoftwareModule(oldFileName, currentSwId); @@ -486,12 +480,12 @@ public class UploadConfirmationwindow implements Button.ClickListener { uploadDetailsTable.setColumnHeader(SIZE, i18n.get("upload.size")); uploadDetailsTable.setColumnHeader(ACTION, i18n.get("upload.action")); - uploadDetailsTable.setColumnExpandRatio(FILE_NAME_LAYOUT, 0.25f); - uploadDetailsTable.setColumnExpandRatio(SW_MODULE_NAME, 0.17f); - uploadDetailsTable.setColumnExpandRatio(SHA1_CHECKSUM, 0.2f); - uploadDetailsTable.setColumnExpandRatio(MD5_CHECKSUM, 0.2f); - uploadDetailsTable.setColumnExpandRatio(SIZE, 0.12f); - uploadDetailsTable.setColumnExpandRatio(ACTION, 0.06f); + uploadDetailsTable.setColumnExpandRatio(FILE_NAME_LAYOUT, 0.25F); + uploadDetailsTable.setColumnExpandRatio(SW_MODULE_NAME, 0.17F); + uploadDetailsTable.setColumnExpandRatio(SHA1_CHECKSUM, 0.2F); + uploadDetailsTable.setColumnExpandRatio(MD5_CHECKSUM, 0.2F); + uploadDetailsTable.setColumnExpandRatio(SIZE, 0.12F); + uploadDetailsTable.setColumnExpandRatio(ACTION, 0.06F); final Object[] visibileColumn = { FILE_NAME_LAYOUT, SW_MODULE_NAME, SHA1_CHECKSUM, MD5_CHECKSUM, SIZE, ACTION }; uploadDetailsTable.setVisibleColumns(visibileColumn); @@ -548,9 +542,7 @@ public class UploadConfirmationwindow implements Button.ClickListener { uploadConfrimationWindow.close(); } else if (event.getComponent().getId().equals(SPUIComponentIdProvider.UPLOAD_BUTTON)) { processArtifactUpload(); - } - - else if (event.getComponent().getId().startsWith(SPUIComponentIdProvider.UPLOAD_DELETE_ICON)) { + } else if (event.getComponent().getId().startsWith(SPUIComponentIdProvider.UPLOAD_DELETE_ICON)) { final String itemId = ((Button) event.getComponent()).getData().toString(); final Item item = uploadDetailsTable.getItem(((Button) event.getComponent()).getData()); final Long swId = (Long) item.getItemProperty(BASE_SOFTWARE_ID).getValue(); @@ -667,7 +659,7 @@ public class UploadConfirmationwindow implements Button.ClickListener { } - private void closeFileStream(final FileInputStream fis, final File newFile) { + private static void closeFileStream(final FileInputStream fis, final File newFile) { if (fis != null) { try { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java index 88467d838..3b044be2c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.ui.common.tagdetails; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -86,23 +85,11 @@ public class DistributionTagToken extends AbstractTagToken { @Override protected void unassignTag(final String tagName) { final DistributionSetTagAssignmentResult result = toggleAssignment(tagName); - if (result.getUnassigned() >= 1 && (isClickedTagListEmpty() || getClickedTagList().contains(tagName))) { + if (result.getUnassigned() >= 1) { eventBus.publish(this, ManagementUIEvent.UNASSIGN_DISTRIBUTION_TAG); } } - private Boolean isClickedTagListEmpty() { - if (getClickedTagList() == null || getClickedTagList() != null && !getClickedTagList().isEmpty()) { - return true; - } - return false; - } - - /* To Be Done : this implementation will vary in views */ - private List getClickedTagList() { - return new ArrayList<>(); - } - @Override protected Boolean isToggleTagAssignmentAllowed() { return checker.hasUpdateDistributionPermission(); From 5f20066cff4a7b1d1e8ffcfb42cc0da0ddc3f058 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Fri, 5 Aug 2016 15:55:49 +0200 Subject: [PATCH 092/118] Fix sonar issue Signed-off-by: SirWayne --- .../hawkbit/artifact/FreePortFileWriter.java | 8 +- .../mgmt/rest/resource/MgmtSystemMapper.java | 4 +- .../test/matcher/BaseEntityMatcher.java | 2 +- .../security/SecurityContextTenantAware.java | 9 +- .../security/SystemSecurityContext.java | 8 +- .../ui/artifacts/upload/UploadLayout.java | 84 +++++++++---------- .../ui/colorpicker/ColorPickerConstants.java | 2 +- .../ui/colorpicker/ColorPickerHelper.java | 8 +- .../polling/DurationConfigField.java | 63 ++++++++++++-- 9 files changed, 121 insertions(+), 67 deletions(-) diff --git a/hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/FreePortFileWriter.java b/hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/FreePortFileWriter.java index 0e957d83a..b0bcc5b6e 100644 --- a/hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/FreePortFileWriter.java +++ b/hawkbit-artifact-repository-mongo/src/test/java/org/eclipse/hawkbit/artifact/FreePortFileWriter.java @@ -12,6 +12,8 @@ import java.io.File; import java.net.InetSocketAddress; import java.net.ServerSocket; +import org.apache.commons.io.IOUtils; + /** * * Look for a free port. @@ -48,6 +50,7 @@ public class FreePortFileWriter { } boolean isFree(final int port) { + ServerSocket sock = null; try { final File portFile = new File(filePortPath + File.separator + port + ".port"); portFile.getParentFile().mkdirs(); @@ -55,19 +58,20 @@ public class FreePortFileWriter { return false; } boolean isFree = false; - final ServerSocket sock = new ServerSocket(); + sock = new ServerSocket(); sock.setReuseAddress(true); sock.bind(new InetSocketAddress(port)); if (portFile.createNewFile()) { portFile.deleteOnExit(); isFree = true; } - sock.close(); return isFree; // We rely on an exception thrown to determine availability or // not availability and don't want to log the exception. } catch (@SuppressWarnings({ "squid:S2221", "squid:S1166" }) final Exception e) { return false; + } finally { + IOUtils.closeQuietly(sock); } } diff --git a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemMapper.java b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemMapper.java index d3f78fad2..d0c8dfcc5 100644 --- a/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemMapper.java +++ b/hawkbit-mgmt-resource/src/main/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtSystemMapper.java @@ -23,7 +23,7 @@ import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey; * A mapper which maps repository model to RESTful model representation and * back. */ -public class MgmtSystemMapper { +public final class MgmtSystemMapper { private MgmtSystemMapper() { // Utility class @@ -51,6 +51,8 @@ public class MgmtSystemMapper { * maps a TenantConfigurationValue from the repository model to a * MgmtSystemTenantConfigurationValue, the RESTful model. * + * @param key + * the key * @param repoConfValue * configuration value as repository model * @return configuration value as RESTful model diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/BaseEntityMatcher.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/BaseEntityMatcher.java index cb3f5476f..c83ae8ad1 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/BaseEntityMatcher.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/BaseEntityMatcher.java @@ -17,7 +17,7 @@ import org.hamcrest.Matchers; /** * Matcher for {@link BaseEntity}. */ -public class BaseEntityMatcher { +public final class BaseEntityMatcher { private BaseEntityMatcher() { } diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java index f2cfbbdbf..6e4ac7f8f 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SecurityContextTenantAware.java @@ -28,11 +28,6 @@ import org.springframework.security.core.context.SecurityContextImpl; */ public class SecurityContextTenantAware implements TenantAware { - /* - * (non-Javadoc) - * - * @see org.eclipse.hawkbit.server.tenancy.TenantAware#getCurrentTenantId() - */ @Override public String getCurrentTenant() { final SecurityContext context = SecurityContextHolder.getContext(); @@ -56,7 +51,7 @@ public class SecurityContextTenantAware implements TenantAware { } } - private SecurityContext buildSecurityContext(final String tenant) { + private static SecurityContext buildSecurityContext(final String tenant) { final SecurityContextImpl securityContext = new SecurityContextImpl(); securityContext.setAuthentication( new AuthenticationDelegate(SecurityContextHolder.getContext().getAuthentication(), tenant)); @@ -68,7 +63,7 @@ public class SecurityContextTenantAware implements TenantAware { * {@link Authentication} object except setting the details specifically for * a specific tenant. */ - private class AuthenticationDelegate implements Authentication { + private static final class AuthenticationDelegate implements Authentication { private static final long serialVersionUID = 1L; private final Authentication delegate; diff --git a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java index 0e3863d97..4432fbb67 100644 --- a/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java +++ b/hawkbit-security-core/src/main/java/org/eclipse/hawkbit/security/SystemSecurityContext.java @@ -34,7 +34,7 @@ import com.google.common.base.Throwables; @Service public class SystemSecurityContext { - private static final Logger logger = LoggerFactory.getLogger(SystemSecurityContext.class); + private static final Logger LOG = LoggerFactory.getLogger(SystemSecurityContext.class); private final TenantAware tenantAware; @@ -96,7 +96,7 @@ public class SystemSecurityContext { public T runAsSystemAsTenant(final Callable callable, final String tenant) { final SecurityContext oldContext = SecurityContextHolder.getContext(); try { - logger.debug("entering system code execution"); + LOG.debug("entering system code execution"); return tenantAware.runAsTenant(tenant, () -> { try { setSystemContext(SecurityContextHolder.getContext()); @@ -110,7 +110,7 @@ public class SystemSecurityContext { } finally { SecurityContextHolder.setContext(oldContext); - logger.debug("leaving system code execution"); + LOG.debug("leaving system code execution"); } } @@ -136,7 +136,7 @@ public class SystemSecurityContext { * {@link SpringEvalExpressions#SYSTEM_ROLE} which is allowed to execute all * secured methods. */ - public static class SystemCodeAuthentication implements Authentication { + public static final class SystemCodeAuthentication implements Authentication { private static final long serialVersionUID = 1L; private static final List AUTHORITIES = Collections diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java index af02e917b..a7e5bd670 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java @@ -248,7 +248,7 @@ public class UploadLayout extends VerticalLayout { final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); // selected software module at the time of file drop is // considered for upload - SoftwareModule selectedSw = artifactUploadState.getSelectedBaseSoftwareModule().get(); + final SoftwareModule selectedSw = artifactUploadState.getSelectedBaseSoftwareModule().get(); // reset the flag hasDirectory = Boolean.FALSE; for (final Html5File file : files) { @@ -265,7 +265,7 @@ public class UploadLayout extends VerticalLayout { } } - private void processFile(final Html5File file, SoftwareModule selectedSw) { + private void processFile(final Html5File file, final SoftwareModule selectedSw) { if (!isDirectory(file)) { if (!checkForDuplicate(file.getFileName(), selectedSw)) { artifactUploadState.getNumberOfFileUploadsExpected().incrementAndGet(); @@ -276,7 +276,7 @@ public class UploadLayout extends VerticalLayout { } } - private StreamVariable createStreamVariable(final Html5File file, SoftwareModule selectedSw) { + private StreamVariable createStreamVariable(final Html5File file, final SoftwareModule selectedSw) { return new UploadHandler(file.getFileName(), file.getFileSize(), UploadLayout.this, spInfo.getMaxArtifactFileSize(), null, file.getType(), selectedSw); } @@ -366,11 +366,13 @@ public class UploadLayout extends VerticalLayout { * in case of upload errors */ OutputStream saveUploadedFileDetails(final String name, final long size, final String mimeType, - SoftwareModule selectedSw) { + final SoftwareModule selectedSw) { File tempFile = null; try { tempFile = File.createTempFile("spUiArtifactUpload", null); + // we return the outputstream so we cannot close it here + @SuppressWarnings("squid:S2095") final OutputStream out = new FileOutputStream(tempFile); final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion(selectedSw.getName(), @@ -445,8 +447,8 @@ public class UploadLayout extends VerticalLayout { */ public Boolean checkIfFileIsDuplicate(final String name, final SoftwareModule selectedSoftwareModule) { Boolean isDuplicate = false; - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( - selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil + .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); for (final CustomFile customFile : artifactUploadState.getFileSelected()) { final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( @@ -510,9 +512,9 @@ public class UploadLayout extends VerticalLayout { artifactUploadState.getNumberOfFileUploadsExpected().incrementAndGet(); } - void updateFileSize(final String name, final long size, SoftwareModule selectedSoftwareModule) { - final String currentBaseSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( - selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); + void updateFileSize(final String name, final long size, final SoftwareModule selectedSoftwareModule) { + final String currentBaseSoftwareModuleKey = HawkbitCommonUtil + .getFormattedNameVersion(selectedSoftwareModule.getName(), selectedSoftwareModule.getVersion()); for (final CustomFile customFile : artifactUploadState.getFileSelected()) { final String fileSoftwareModuleKey = HawkbitCommonUtil.getFormattedNameVersion( @@ -594,12 +596,12 @@ public class UploadLayout extends VerticalLayout { private void setConfirmationPopupHeightWidth(final float newWidth, final float newHeight) { if (currentUploadConfirmationwindow != null) { - currentUploadConfirmationwindow.getUploadArtifactDetails().setWidth( - HawkbitCommonUtil.getArtifactUploadPopupWidth(newWidth, - SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), Unit.PIXELS); - currentUploadConfirmationwindow.getUploadDetailsTable().setHeight( - HawkbitCommonUtil.getArtifactUploadPopupHeight(newHeight, - SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), Unit.PIXELS); + currentUploadConfirmationwindow.getUploadArtifactDetails().setWidth(HawkbitCommonUtil + .getArtifactUploadPopupWidth(newWidth, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), + Unit.PIXELS); + currentUploadConfirmationwindow.getUploadDetailsTable().setHeight(HawkbitCommonUtil + .getArtifactUploadPopupHeight(newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), + Unit.PIXELS); } } @@ -616,12 +618,10 @@ public class UploadLayout extends VerticalLayout { && currentUploadConfirmationwindow.getCurrentUploadResultWindow() != null) { final UploadResultWindow uploadResultWindow = currentUploadConfirmationwindow .getCurrentUploadResultWindow(); - uploadResultWindow.getUploadResultsWindow().setWidth( - HawkbitCommonUtil.getArtifactUploadPopupWidth(newWidth, - SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), Unit.PIXELS); - uploadResultWindow.getUploadResultTable().setHeight( - HawkbitCommonUtil.getArtifactUploadPopupHeight(newHeight, - SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), Unit.PIXELS); + uploadResultWindow.getUploadResultsWindow().setWidth(HawkbitCommonUtil.getArtifactUploadPopupWidth(newWidth, + SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_WIDTH), Unit.PIXELS); + uploadResultWindow.getUploadResultTable().setHeight(HawkbitCommonUtil.getArtifactUploadPopupHeight( + newHeight, SPUIDefinitions.MIN_UPLOAD_CONFIRMATION_POPUP_HEIGHT), Unit.PIXELS); } } @@ -632,8 +632,8 @@ public class UploadLayout extends VerticalLayout { } else { currentUploadConfirmationwindow = new UploadConfirmationwindow(this, artifactUploadState); UI.getCurrent().addWindow(currentUploadConfirmationwindow.getUploadConfrimationWindow()); - setConfirmationPopupHeightWidth(Page.getCurrent().getBrowserWindowWidth(), Page.getCurrent() - .getBrowserWindowHeight()); + setConfirmationPopupHeightWidth(Page.getCurrent().getBrowserWindowWidth(), + Page.getCurrent().getBrowserWindowHeight()); } } } @@ -682,7 +682,7 @@ public class UploadLayout extends VerticalLayout { displayDuplicateValidationMessage(); } - private void onUploadStreamingFailure(UploadStatusEvent event) { + private void onUploadStreamingFailure(final UploadStatusEvent event) { /** * If upload interrupted because of duplicate file,do not remove the * file already in upload list @@ -691,13 +691,13 @@ public class UploadLayout extends VerticalLayout { || !getDuplicateFileNamesList().contains(event.getUploadStatus().getFileName())) { final SoftwareModule sw = event.getUploadStatus().getSoftwareModule(); if (sw != null) { - getFileSelected().remove( - new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); + getFileSelected() + .remove(new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); } // failed reason to be updated only if there is error other than // duplicate file error - uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() - .getFailureReason(), event.getUploadStatus().getSoftwareModule()); + uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), + event.getUploadStatus().getFailureReason(), event.getUploadStatus().getSoftwareModule()); increaseNumberOfFileUploadsFailed(); } decreaseNumberOfFileUploadsExpected(); @@ -711,9 +711,9 @@ public class UploadLayout extends VerticalLayout { displayDuplicateValidationMessage(); } - private void onUploadSuccess(UploadStatusEvent event) { - updateFileSize(event.getUploadStatus().getFileName(), event.getUploadStatus().getContentLength(), event - .getUploadStatus().getSoftwareModule()); + private void onUploadSuccess(final UploadStatusEvent event) { + updateFileSize(event.getUploadStatus().getFileName(), event.getUploadStatus().getContentLength(), + event.getUploadStatus().getSoftwareModule()); // recorded that we now one more uploaded increaseNumberOfFilesActuallyUpload(); } @@ -730,8 +730,8 @@ public class UploadLayout extends VerticalLayout { } private boolean isUploadComplete() { - int uploadedCount = artifactUploadState.getNumberOfFilesActuallyUpload().intValue(); - int expectedUploadsCount = artifactUploadState.getNumberOfFileUploadsExpected().intValue(); + final int uploadedCount = artifactUploadState.getNumberOfFilesActuallyUpload().intValue(); + final int expectedUploadsCount = artifactUploadState.getNumberOfFileUploadsExpected().intValue(); return uploadedCount == expectedUploadsCount; } @@ -744,13 +744,13 @@ public class UploadLayout extends VerticalLayout { || !getDuplicateFileNamesList().contains(event.getUploadStatus().getFileName())) { final SoftwareModule sw = event.getUploadStatus().getSoftwareModule(); if (sw != null) { - getFileSelected().remove( - new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); + getFileSelected() + .remove(new CustomFile(event.getUploadStatus().getFileName(), sw.getName(), sw.getVersion())); } // failed reason to be updated only if there is error other than // duplicate file error - uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), event.getUploadStatus() - .getFailureReason(), event.getUploadStatus().getSoftwareModule()); + uploadInfoWindow.uploadFailed(event.getUploadStatus().getFileName(), + event.getUploadStatus().getFailureReason(), event.getUploadStatus().getSoftwareModule()); increaseNumberOfFileUploadsFailed(); decreaseNumberOfFileUploadsExpected(); } @@ -773,8 +773,8 @@ public class UploadLayout extends VerticalLayout { * @param selectedBaseSoftwareModule */ public void refreshArtifactDetailsLayout(final SoftwareModule selectedBaseSoftwareModule) { - eventBus.publish(this, new SoftwareModuleEvent(SoftwareModuleEventType.ARTIFACTS_CHANGED, - selectedBaseSoftwareModule)); + eventBus.publish(this, + new SoftwareModuleEvent(SoftwareModuleEventType.ARTIFACTS_CHANGED, selectedBaseSoftwareModule)); } /** @@ -804,10 +804,10 @@ public class UploadLayout extends VerticalLayout { } void updateStatusButtonCount() { - int uploadsPending = artifactUploadState.getNumberOfFileUploadsExpected().get() + final int uploadsPending = artifactUploadState.getNumberOfFileUploadsExpected().get() - artifactUploadState.getNumberOfFilesActuallyUpload().get(); - int uploadsFailed = artifactUploadState.getNumberOfFileUploadsFailed().get(); - StringBuilder builder = new StringBuilder(""); + final int uploadsFailed = artifactUploadState.getNumberOfFileUploadsFailed().get(); + final StringBuilder builder = new StringBuilder(""); if (uploadsFailed != 0) { if (uploadsPending != 0) { builder.append("
" + uploadsFailed + "
"); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerConstants.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerConstants.java index 06e280e4e..86a986e3a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerConstants.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerConstants.java @@ -14,7 +14,7 @@ import com.vaadin.shared.ui.colorpicker.Color; * Provides color constants for the ColorPickerLayout * */ -public class ColorPickerConstants { +public final class ColorPickerConstants { public static final String DEFAULT_COLOR = "rgb(44,151,32)"; public static final Color START_COLOR = new Color(0, 146, 58); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerHelper.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerHelper.java index 923c58fe3..1f80bf5ab 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerHelper.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/colorpicker/ColorPickerHelper.java @@ -20,7 +20,7 @@ import com.vaadin.ui.Slider.ValueOutOfBoundsException; * Contains helper methods for the ColorPickerLayout to handle the ColorPicker * */ -public class ColorPickerHelper { +public final class ColorPickerHelper { private static final Logger LOG = LoggerFactory.getLogger(ColorPickerHelper.class); @@ -30,7 +30,9 @@ public class ColorPickerHelper { /** * Get color picked value as string. - * + * + * @param preview + * the color picker preview * @return String of color picked value. */ public static String getColorPickedString(final SpColorPickerPreview preview) { @@ -59,7 +61,7 @@ public class ColorPickerHelper { final int green = Integer.parseInt(colors[1]); final int blue = Integer.parseInt(colors[2]); if (colors.length > 3) { - final int alpha = (int) (Double.parseDouble(colors[3]) * 255d); + final int alpha = (int) (Double.parseDouble(colors[3]) * 255D); return new Color(red, green, blue, alpha); } return new Color(red, green, blue); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java index 15f51877d..9a3a54a5e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/tenantconfiguration/polling/DurationConfigField.java @@ -24,7 +24,7 @@ import com.vaadin.ui.GridLayout; * duration in the DurationField or he can configure using the global duration * by changing the CheckBox. */ -public class DurationConfigField extends GridLayout implements ConfigurationItem { +public final class DurationConfigField extends GridLayout implements ConfigurationItem { private static final long serialVersionUID = 1L; @@ -130,45 +130,96 @@ public class DurationConfigField extends GridLayout implements ConfigurationItem configurationChangeListeners.add(listener); } + /** + * Create a DurationConfigFieldBuilder. + * + * @return the builder + */ public static DurationConfigFieldBuilder builder() { return new DurationConfigFieldBuilder(); } - public static class DurationConfigFieldBuilder { + /** + * Builder for the calendar widget. + * + */ + public static final class DurationConfigFieldBuilder { private final DurationConfigField field; - private Duration globalDuration = null; - private Duration tenantDuration = null; + private Duration globalDuration; + private Duration tenantDuration; private DurationConfigFieldBuilder() { field = new DurationConfigField(); - }; + } + /** + * set the checkbox tooltip. + * + * @param label + * the tooltip + * @return the builder + */ public DurationConfigFieldBuilder checkBoxTooltip(final String label) { field.setCheckBoxTooltip(label); return this; } + /** + * set the global duration. + * + * @param globalDuration + * the global duration + * @return the builder + */ public DurationConfigFieldBuilder globalDuration(final Duration globalDuration) { this.globalDuration = globalDuration; return this; } + /** + * set the caption. + * + * @param caption + * the caption + * @return the builder + */ public DurationConfigFieldBuilder caption(final String caption) { field.setCaption(caption); return this; } + /** + * set the range. + * + * @param minDuration + * min duration + * @param maxDuration + * max duration + * @return the builder + */ public DurationConfigFieldBuilder range(final Duration minDuration, final Duration maxDuration) { field.setAllowedRange(minDuration, maxDuration); return this; } + /** + * set the tenant duration. + * + * @param tenantDuration + * the duration + * @return the builder + */ public DurationConfigFieldBuilder tenantDuration(final Duration tenantDuration) { this.tenantDuration = tenantDuration; return this; } + /** + * Create the {@link DurationConfigField}. + * + * @return the {@link DurationConfigField} + */ public DurationConfigField build() { if (globalDuration == null) { throw new IllegalStateException( @@ -178,5 +229,5 @@ public class DurationConfigField extends GridLayout implements ConfigurationItem field.init(globalDuration, tenantDuration); return field; } - }; + } } From 88c1253f6691da391aa3870529a6f531e08d8bfd Mon Sep 17 00:00:00 2001 From: Gaurav Date: Fri, 5 Aug 2016 16:02:20 +0200 Subject: [PATCH 093/118] Fix for the concurrency issue on UI causes on the Nullpointer Exception. Signed-off-by: Gaurav --- .../ui/common/tagdetails/AbstractTagToken.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java index 9d36e3de0..5894e986c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java @@ -12,6 +12,7 @@ import java.io.Serializable; import java.util.HashMap; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; @@ -54,7 +55,7 @@ public abstract class AbstractTagToken implements Serializ protected IndexedContainer container; - protected final transient Map tagDetails = new HashMap<>(); + protected final transient Map tagDetails = new ConcurrentHashMap<>(); protected final transient Map tokensAdded = new HashMap<>(); @@ -140,10 +141,12 @@ public abstract class AbstractTagToken implements Serializ } protected void setContainerPropertValues(final Long tagId, final String tagName, final String tagColor) { - tagDetails.put(tagId, new TagData(tagId, tagName, tagColor)); - final Item item = container.addItem(tagId); - item.getItemProperty("id").setValue(tagId); - updateItem(tagName, tagColor, item); + final TagData tagData = tagDetails.putIfAbsent(tagId, new TagData(tagId, tagName, tagColor)); + if(tagData == null){ + final Item item = container.addItem(tagId); + item.getItemProperty("id").setValue(tagId); + updateItem(tagName, tagColor, item); + } } protected void updateItem(final String tagName, final String tagColor, final Item item) { From 9febe1645339a8dd3060463b85ffc44998e6feb7 Mon Sep 17 00:00:00 2001 From: SirWayne Date: Fri, 5 Aug 2016 16:42:09 +0200 Subject: [PATCH 094/118] Fix sonar issue Signed-off-by: SirWayne --- .../ui/artifacts/upload/UploadLayout.java | 30 +++++++++++-------- .../tagdetails/AbstractTargetTagToken.java | 5 +++- .../ui/common/tagdetails/TargetTagToken.java | 19 +----------- .../ui/components/SPUIComponentProvider.java | 8 ++--- ...orator.java => HeaderLayoutDecorator.java} | 10 +++++-- .../ui/decorators/SPUIButtonDecorator.java | 1 + .../CreateUpdateDistSetTypeLayout.java | 19 ++++-------- .../hawkbit/ui/filter/FilterExpression.java | 4 +-- .../targettable/BulkUploadHandler.java | 15 ++++------ .../TargetBulkUpdateWindowLayout.java | 2 +- .../hawkbit/ui/menu/DashboardMenu.java | 10 +++---- .../rollout/AddUpdateRolloutWindowLayout.java | 11 ++++--- 12 files changed, 59 insertions(+), 75 deletions(-) rename hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/{SPUIHeaderLayoutDecorator.java => HeaderLayoutDecorator.java} (72%) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java index a7e5bd670..71b041c9e 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/artifacts/upload/UploadLayout.java @@ -76,6 +76,11 @@ import com.vaadin.ui.VerticalLayout; @SpringComponent public class UploadLayout extends VerticalLayout { + /** + * + */ + private static final String HTML_DIV = ""; + private static final long serialVersionUID = -566164756606779220L; private static final Logger LOG = LoggerFactory.getLogger(UploadLayout.class); @@ -408,18 +413,12 @@ public class UploadLayout extends VerticalLayout { return checkIfSoftwareModuleIsSelected(); } - private boolean isFilesDropped(final DragAndDropEvent event) { + private static boolean isFilesDropped(final DragAndDropEvent event) { if (event.getTransferable() instanceof WrapperTransferable) { final Html5File[] files = ((WrapperTransferable) event.getTransferable()).getFiles(); - // other components can also be wrapped in WrapperTransferable , so - // additional check on files - if (files == null) { - return false; - } - return true; - } else { - return false; + return files != null; } + return false; } Boolean checkIfSoftwareModuleIsSelected() { @@ -443,6 +442,8 @@ public class UploadLayout extends VerticalLayout { * * @param name * file name + * @param selectedSoftwareModule + * the current selected sm module * @return Boolean */ public Boolean checkIfFileIsDuplicate(final String name, final SoftwareModule selectedSoftwareModule) { @@ -475,7 +476,7 @@ public class UploadLayout extends VerticalLayout { void updateActionCount() { if (!artifactUploadState.getFileSelected().isEmpty()) { processBtn.setCaption(SPUILabelDefinitions.PROCESS + "
" - + artifactUploadState.getFileSelected().size() + "
"); + + artifactUploadState.getFileSelected().size() + HTML_DIV); } else { processBtn.setCaption(SPUILabelDefinitions.PROCESS); } @@ -504,6 +505,9 @@ public class UploadLayout extends VerticalLayout { return message.toString(); } + /** + * Show the duplicated message. + */ public void showDuplicateMessage() { uiNotification.displayValidationError(getDuplicateFileValidationMessage()); } @@ -810,13 +814,13 @@ public class UploadLayout extends VerticalLayout { final StringBuilder builder = new StringBuilder(""); if (uploadsFailed != 0) { if (uploadsPending != 0) { - builder.append("
" + uploadsFailed + "
"); + builder.append("
" + uploadsFailed + HTML_DIV); } else { - builder.append("
" + uploadsFailed + "
"); + builder.append("
" + uploadsFailed + HTML_DIV); } } if (uploadsPending != 0) { - builder.append("
" + uploadsPending + "
"); + builder.append("
" + uploadsPending + HTML_DIV); } uploadStatusButton.setCaption(builder.toString()); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTargetTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTargetTagToken.java index e74a331af..81ea9154c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTargetTagToken.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTargetTagToken.java @@ -18,7 +18,10 @@ import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.annotation.EventBusListenerMethod; /** - * Abstract class for target tag token layout. + * /** Abstract class for target tag token layout. + * + * @param + * the entity type */ public abstract class AbstractTargetTagToken extends AbstractTagToken { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java index 2cd4ec978..34b931c1b 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.ui.common.tagdetails; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -23,7 +22,6 @@ import org.eclipse.hawkbit.repository.model.TargetTagAssignmentResult; import org.eclipse.hawkbit.ui.management.event.ManagementUIEvent; import org.eclipse.hawkbit.ui.management.event.TargetTableEvent; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; -import org.eclipse.hawkbit.ui.utils.UINotification; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.spring.events.EventScope; import org.vaadin.spring.events.annotation.EventBusListenerMethod; @@ -46,9 +44,6 @@ public class TargetTagToken extends AbstractTargetTagToken { // To Be Done : have to set this value based on view??? private static final Boolean NOTAGS_SELECTED = Boolean.FALSE; - @Autowired - private UINotification uinotification; - @Autowired private transient TargetManagement targetManagement; @@ -85,23 +80,11 @@ public class TargetTagToken extends AbstractTargetTagToken { @Override protected void unassignTag(final String tagName) { final TargetTagAssignmentResult result = toggleAssignment(tagName); - if (result.getUnassigned() >= 1 && (isClickedTagListEmpty() || getClickedTagList().contains(tagName))) { + if (result.getUnassigned() >= 1) { eventBus.publish(this, ManagementUIEvent.UNASSIGN_TARGET_TAG); } } - private Boolean isClickedTagListEmpty() { - if (getClickedTagList() == null || getClickedTagList() != null && !getClickedTagList().isEmpty()) { - return true; - } - return false; - } - - /* To Be Done : this implementation will vary in views */ - private List getClickedTagList() { - return new ArrayList<>(); - } - @Override protected Boolean isToggleTagAssignmentAllowed() { return checker.hasUpdateTargetPermission(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java index f3f5c5a06..8161c2895 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/SPUIComponentProvider.java @@ -17,7 +17,7 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.ui.common.UserDetailsFormatter; import org.eclipse.hawkbit.ui.decorators.SPUIButtonDecorator; import org.eclipse.hawkbit.ui.decorators.SPUIComboBoxDecorator; -import org.eclipse.hawkbit.ui.decorators.SPUIHeaderLayoutDecorator; +import org.eclipse.hawkbit.ui.decorators.HeaderLayoutDecorator; import org.eclipse.hawkbit.ui.decorators.SPUILabelDecorator; import org.eclipse.hawkbit.ui.decorators.SPUITextAreaDecorator; import org.eclipse.hawkbit.ui.decorators.SPUITextFieldDecorator; @@ -104,7 +104,7 @@ public final class SPUIComponentProvider { * @return */ public static HorizontalLayout getHeaderLayout( - final Class tableHeaderLayoutDecorator) { + final Class tableHeaderLayoutDecorator) { // Do we really need this??? HorizontalLayout hLayout = getHorizontalLayout(new SPUIHorizontalLayout().getUiHorizontalLayout().getClass()); @@ -113,11 +113,11 @@ public final class SPUIComponentProvider { } try { - final SPUIHeaderLayoutDecorator layoutDecorator = tableHeaderLayoutDecorator.newInstance(); + final HeaderLayoutDecorator layoutDecorator = tableHeaderLayoutDecorator.newInstance(); hLayout = layoutDecorator.decorate(hLayout); } catch (final InstantiationException | IllegalAccessException exception) { - LOG.error("Error occured while creating horizontal decorator " + SPUIHeaderLayoutDecorator.class, + LOG.error("Error occured while creating horizontal decorator " + HeaderLayoutDecorator.class, exception); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIHeaderLayoutDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/HeaderLayoutDecorator.java similarity index 72% rename from hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIHeaderLayoutDecorator.java rename to hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/HeaderLayoutDecorator.java index f7de09ad7..a71bc9031 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIHeaderLayoutDecorator.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/HeaderLayoutDecorator.java @@ -13,13 +13,17 @@ import com.vaadin.ui.HorizontalLayout; /** * * - * + * Ui header layout decorater. */ -public interface SPUIHeaderLayoutDecorator { +@FunctionalInterface +public interface HeaderLayoutDecorator { /** + * decorate the header + * * @param layout - * @return + * the layout + * @return the decorated layout */ HorizontalLayout decorate(HorizontalLayout layout); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonDecorator.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonDecorator.java index dd6f928d7..05d1f8a0a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonDecorator.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/decorators/SPUIButtonDecorator.java @@ -17,6 +17,7 @@ import com.vaadin.ui.Button; * * */ +@FunctionalInterface public interface SPUIButtonDecorator { /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java index 2a12bc859..65e52d448 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/disttype/CreateUpdateDistSetTypeLayout.java @@ -9,7 +9,6 @@ package org.eclipse.hawkbit.ui.distributions.disttype; import java.util.List; -import java.util.Map; import java.util.Set; import org.eclipse.hawkbit.repository.DistributionSetManagement; @@ -27,8 +26,6 @@ import org.eclipse.hawkbit.ui.layouts.CreateUpdateTypeLayout; import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; @@ -59,8 +56,6 @@ import com.vaadin.ui.themes.ValoTheme; public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { private static final long serialVersionUID = -5169398523815877767L; - private static final Logger LOG = LoggerFactory.getLogger(CreateUpdateDistSetTypeLayout.class); - private static final String DIST_TYPE_NAME = "name"; private static final String DIST_TYPE_DESCRIPTION = "description"; private static final String DIST_TYPE_MANDATORY = "mandatory"; @@ -84,8 +79,6 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { private IndexedContainer originalSelectedTableContainer; - private Map mandatoryCheckboxMap; - @Override protected void createRequiredComponents() { @@ -152,9 +145,9 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { twinColumnLayout.setComponentAlignment(sourceTable, Alignment.MIDDLE_LEFT); twinColumnLayout.setComponentAlignment(selectButtonLayout, Alignment.MIDDLE_CENTER); twinColumnLayout.setComponentAlignment(selectedTable, Alignment.MIDDLE_RIGHT); - twinColumnLayout.setExpandRatio(sourceTable, 0.45f); - twinColumnLayout.setExpandRatio(selectButtonLayout, 0.07f); - twinColumnLayout.setExpandRatio(selectedTable, 0.48f); + twinColumnLayout.setExpandRatio(sourceTable, 0.45F); + twinColumnLayout.setExpandRatio(selectButtonLayout, 0.07F); + twinColumnLayout.setExpandRatio(selectedTable, 0.48F); sourceTable.setVisibleColumns(new Object[] { DIST_TYPE_NAME }); return twinColumnLayout; } @@ -226,7 +219,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { sourceTable.setVisibleColumns(new Object[] { DIST_TYPE_NAME }); sourceTable.setColumnHeaders(i18n.get("header.dist.twintable.available")); - sourceTable.setColumnExpandRatio(DIST_TYPE_NAME, 1.0f); + sourceTable.setColumnExpandRatio(DIST_TYPE_NAME, 1.0F); getSourceTableData(); addTooltip(); sourceTable.select(sourceTable.firstItemId()); @@ -413,7 +406,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { } } - private void checkMandatoryAndAddMandatoryModuleType(final DistributionSetType updateDistSetType, + private static void checkMandatoryAndAddMandatoryModuleType(final DistributionSetType updateDistSetType, final Boolean isMandatory, final SoftwareModuleType swModuleType) { if (isMandatory) { updateDistSetType.addMandatoryModuleType(swModuleType); @@ -488,7 +481,7 @@ public class CreateUpdateDistSetTypeLayout extends CreateUpdateTypeLayout { * * @return */ - private LazyQueryContainer getDistSetTypeLazyQueryContainer() { + private static LazyQueryContainer getDistSetTypeLazyQueryContainer() { final LazyQueryContainer disttypeContainer = HawkbitCommonUtil.createLazyQueryContainer( new BeanQueryFactory(DistributionSetTypeBeanQuery.class)); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filter/FilterExpression.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filter/FilterExpression.java index 1aaafd905..853c6f095 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filter/FilterExpression.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/filter/FilterExpression.java @@ -13,11 +13,9 @@ package org.eclipse.hawkbit.ui.filter; * mechanism. The filter expression can evaluate if e.g. Targets should * currently be added to the target list or if the current enabled filtered will * filter the target and not show the newly created target. - * - * - * * */ +@FunctionalInterface public interface FilterExpression { /** diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index ee062493e..4cc4d37f4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -43,7 +43,6 @@ import org.eclipse.hawkbit.ui.utils.HawkbitCommonUtil; import org.eclipse.hawkbit.ui.utils.I18N; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SpringContextHelper; -import org.eclipse.hawkbit.ui.utils.UINotification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.vaadin.spring.events.EventBus; @@ -83,9 +82,7 @@ public class BulkUploadHandler extends CustomComponent private final transient DeploymentManagement deploymentManagement; private final transient DistributionSetManagement distributionSetManagement; - private final UINotification uINotification; - - protected File tempFile = null; + protected File tempFile; private Upload upload; private final ProgressBar progressBar; @@ -93,8 +90,8 @@ public class BulkUploadHandler extends CustomComponent private final TargetBulkTokenTags targetBulkTokenTags; private final Label targetsCountLabel; - private long failedTargetCount = 0; - private long successfullTargetCount = 0; + private long failedTargetCount; + private long successfullTargetCount; private final transient Executor executor; private transient EventBus.SessionEventBus eventBus; @@ -109,12 +106,11 @@ public class BulkUploadHandler extends CustomComponent * @param targetManagement * @param managementUIState * @param deploymentManagement - * @param uINotification * @param i18n */ public BulkUploadHandler(final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout, final TargetManagement targetManagement, final ManagementUIState managementUIState, - final DeploymentManagement deploymentManagement, final UINotification uINotification, final I18N i18n) { + final DeploymentManagement deploymentManagement, final I18N i18n) { this.targetBulkUpdateWindowLayout = targetBulkUpdateWindowLayout; this.comboBox = targetBulkUpdateWindowLayout.getDsNamecomboBox(); this.descTextArea = targetBulkUpdateWindowLayout.getDescTextArea(); @@ -122,7 +118,6 @@ public class BulkUploadHandler extends CustomComponent this.progressBar = targetBulkUpdateWindowLayout.getProgressBar(); this.managementUIState = managementUIState; this.deploymentManagement = deploymentManagement; - this.uINotification = uINotification; this.targetsCountLabel = targetBulkUpdateWindowLayout.getTargetsCountLabel(); this.targetBulkTokenTags = targetBulkUpdateWindowLayout.getTargetBulkTokenTags(); this.i18n = i18n; @@ -396,7 +391,7 @@ public class BulkUploadHandler extends CustomComponent } - private void setTargetValues(final Target target, final String name, final String description) { + private static void setTargetValues(final Target target, final String name, final String description) { if (null == name) { target.setName(target.getControllerId()); } else { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java index e806e4f30..f8e273232 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java @@ -178,7 +178,7 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { private BulkUploadHandler getBulkUploadHandler() { final BulkUploadHandler bulkUploadHandler = new BulkUploadHandler(this, targetManagement, managementUIState, - deploymentManagement, uINotification, i18n); + deploymentManagement, i18n); bulkUploadHandler.buildLayout(); bulkUploadHandler.addStyleName(SPUIStyleDefinitions.BULK_UPLOAD_BUTTON); return bulkUploadHandler; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java index 1caafe307..defcc82c0 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/menu/DashboardMenu.java @@ -56,6 +56,11 @@ import com.vaadin.ui.themes.ValoTheme; @UIScope public final class DashboardMenu extends CustomComponent { + private static final String STYLE_VISIBLE = "valo-menu-visible"; + public static final String ID = "dashboard-menu"; + public static final String REPORTS_BADGE_ID = "dashboard-menu-reports-badge"; + public static final String NOTIFICATIONS_BADGE_ID = "dashboard-menu-notifications-badge"; + @Autowired private I18N i18n; @@ -67,11 +72,6 @@ public final class DashboardMenu extends CustomComponent { private static final long serialVersionUID = 5394474618559481462L; - public static final String ID = "dashboard-menu"; - public static final String REPORTS_BADGE_ID = "dashboard-menu-reports-badge"; - public static final String NOTIFICATIONS_BADGE_ID = "dashboard-menu-notifications-badge"; - private static final String STYLE_VISIBLE = "valo-menu-visible"; - // this should be resolved when we introduce event bus on UI to just inform // the buttons directly via events private final List menuButtons = new ArrayList<>(); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java index 05eabf249..8a7d11df1 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/rollout/rollout/AddUpdateRolloutWindowLayout.java @@ -44,8 +44,6 @@ import org.eclipse.hawkbit.ui.utils.SPUIDefinitions; import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions; import org.eclipse.hawkbit.ui.utils.SPUIStyleDefinitions; import org.eclipse.hawkbit.ui.utils.UINotification; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.vaadin.addons.lazyquerycontainer.BeanQueryFactory; import org.vaadin.addons.lazyquerycontainer.LazyQueryContainer; @@ -80,8 +78,6 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { private static final long serialVersionUID = 2999293468801479916L; - private static final Logger LOG = LoggerFactory.getLogger(AddUpdateRolloutWindowLayout.class); - private static final String MESSAGE_ROLLOUT_FIELD_VALUE_RANGE = "message.rollout.field.value.range"; private static final String MESSAGE_ENTER_NUMBER = "message.enter.number"; @@ -154,6 +150,13 @@ public class AddUpdateRolloutWindowLayout extends GridLayout { buildLayout(); } + /** + * Get the window. + * + * @param rolloutId + * the rollout id + * @return the window + */ public CommonDialogWindow getWindow(final Long rolloutId) { window = getWindow(); populateData(rolloutId); From b3702672a32644c56fae8f91fc8f22cf35ffd4f4 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 8 Aug 2016 09:14:48 +0200 Subject: [PATCH 095/118] add javadoc Signed-off-by: Michael Hirsch --- .../repository/jpa/model/EntityPropertyChangeListener.java | 3 ++- .../hawkbit/repository/jpa/model/EventAwareEntity.java | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java index 13b1507db..27fbc687e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EntityPropertyChangeListener.java @@ -13,7 +13,8 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; import org.eclipse.persistence.descriptors.DescriptorEventAdapter; /** - * Listens to change in property values of an entity. + * Listens to change in property values of an entity and calls the corresponding + * {@link EventAwareEntity}. * */ public class EntityPropertyChangeListener extends DescriptorEventAdapter { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java index 95a14a979..889a61796 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/EventAwareEntity.java @@ -10,22 +10,29 @@ package org.eclipse.hawkbit.repository.jpa.model; import org.eclipse.persistence.descriptors.DescriptorEvent; +/** + * Interfaces which can be implemented by entities to be called when the entity + * should fire an event because the entity has been created, updated or deleted. + */ public interface EventAwareEntity { /** * Fired for the Entity creation. + * * @param descriptorEvent */ void fireCreateEvent(DescriptorEvent descriptorEvent); /** * Fired for the Entity updation. + * * @param descriptorEvent */ void fireUpdateEvent(DescriptorEvent descriptorEvent); /** * Fired for the Entity deletion. + * * @param descriptorEvent */ void fireDeleteEvent(DescriptorEvent descriptorEvent); From 8fa2a60a7177cc3801382b755b0af5faa0aec082 Mon Sep 17 00:00:00 2001 From: Gaurav Date: Mon, 8 Aug 2016 13:30:16 +0200 Subject: [PATCH 096/118] Formatted the code. Signed-off-by: Gaurav --- .../eventbus/event/TargetUpdatedEvent.java | 18 ++++---- .../jpa/model/DescriptorEventDetails.java | 44 ++++++++++--------- .../helper/EntityPropertyChangeHelper.java | 25 ++++------- 3 files changed, 42 insertions(+), 45 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java index 4896f4ca8..8ae5718e9 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/eventbus/event/TargetUpdatedEvent.java @@ -16,14 +16,16 @@ import org.eclipse.hawkbit.repository.model.Target; */ public class TargetUpdatedEvent extends AbstractBaseEntityEvent { - private static final long serialVersionUID = 5665118668865832477L; + private static final long serialVersionUID = 5665118668865832477L; - /** - * Constructor - * @param baseEntity Target entity - */ - public TargetUpdatedEvent(final Target baseEntity) { - super(baseEntity); - } + /** + * Constructor + * + * @param baseEntity + * Target entity + */ + public TargetUpdatedEvent(final Target baseEntity) { + super(baseEntity); + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java index a80891604..091b2eb77 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java @@ -17,31 +17,33 @@ import org.eclipse.persistence.descriptors.DescriptorEvent; */ public class DescriptorEventDetails { - enum ActionType { - CREATE, UPDATE; - } + enum ActionType { + CREATE, UPDATE; + } - private final DescriptorEvent descriptorEvent; + private final DescriptorEvent descriptorEvent; - private final ActionType actiontype; + private final ActionType actiontype; - /** - * Constructor - * @param actionType Action type - * @param descriptorEvent Descriptor Event - */ - public DescriptorEventDetails(final ActionType actionType, - final DescriptorEvent descriptorEvent) { - this.descriptorEvent = descriptorEvent; - this.actiontype = actionType; - } + /** + * Constructor + * + * @param actionType + * Action type + * @param descriptorEvent + * Descriptor Event + */ + public DescriptorEventDetails(final ActionType actionType, final DescriptorEvent descriptorEvent) { + this.descriptorEvent = descriptorEvent; + this.actiontype = actionType; + } - public DescriptorEvent getDescriptorEvent() { - return descriptorEvent; - } + public DescriptorEvent getDescriptorEvent() { + return descriptorEvent; + } - public ActionType getActiontype() { - return actiontype; - } + public ActionType getActiontype() { + return actiontype; + } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java index 0697bcead..2be398e24 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/helper/EntityPropertyChangeHelper.java @@ -19,15 +19,15 @@ import org.eclipse.persistence.queries.UpdateObjectQuery; import org.eclipse.persistence.sessions.changesets.DirectToFieldChangeRecord; /** - *Helper class to get the change set for the property changes in the Entity. + * Helper class to get the change set for the property changes in the Entity. * * @param */ -public class EntityPropertyChangeHelper { - - +public class EntityPropertyChangeHelper { + /** * To get the map of entity property change set + * * @param clazz * @param event * @return the map of the changeSet @@ -35,19 +35,12 @@ public class EntityPropertyChangeHelper { public static Map.Values> getChangeSet( final Class clazz, final DescriptorEvent event) { final T rolloutGroup = clazz.cast(event.getObject()); - final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()) - .getObjectChangeSet(); - return changeSet - .getChanges() - .stream() - .filter(record -> record instanceof DirectToFieldChangeRecord) + final ObjectChangeSet changeSet = ((UpdateObjectQuery) event.getQuery()).getObjectChangeSet(); + return changeSet.getChanges().stream().filter(record -> record instanceof DirectToFieldChangeRecord) .map(record -> (DirectToFieldChangeRecord) record) - .collect( - Collectors.toMap( - record -> record.getAttribute(), - record -> new AbstractPropertyChangeEvent( - rolloutGroup, null).new Values(record - .getOldValue(), record.getNewValue()))); + .collect(Collectors.toMap(record -> record.getAttribute(), + record -> new AbstractPropertyChangeEvent(rolloutGroup, null).new Values( + record.getOldValue(), record.getNewValue()))); } } From adafaa9489aaff7ff76b8909dbe2e9de57e5e368 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 8 Aug 2016 16:15:15 +0200 Subject: [PATCH 097/118] clear the tagDetails map as well Signed-off-by: Michael Hirsch --- .../eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java | 2 +- .../hawkbit/ui/common/tagdetails/DistributionTagToken.java | 1 + .../eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java index 5894e986c..2df040c65 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java @@ -142,7 +142,7 @@ public abstract class AbstractTagToken implements Serializ protected void setContainerPropertValues(final Long tagId, final String tagName, final String tagColor) { final TagData tagData = tagDetails.putIfAbsent(tagId, new TagData(tagId, tagName, tagColor)); - if(tagData == null){ + if (tagData == null) { final Item item = container.addItem(tagId); item.getItemProperty("id").setValue(tagId); updateItem(tagName, tagColor, item); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java index 88467d838..273dd3bf3 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/DistributionTagToken.java @@ -121,6 +121,7 @@ public class DistributionTagToken extends AbstractTagToken { @Override protected void populateContainer() { container.removeAllItems(); + tagDetails.clear(); for (final DistributionSetTag tag : tagManagement.findAllDistributionSetTags()) { setContainerPropertValues(tag.getId(), tag.getName(), tag.getColour()); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java index 2cd4ec978..bd91302cf 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/TargetTagToken.java @@ -120,6 +120,7 @@ public class TargetTagToken extends AbstractTargetTagToken { @Override protected void populateContainer() { container.removeAllItems(); + tagDetails.clear(); for (final TargetTag tag : tagManagement.findAllTargetTags()) { setContainerPropertValues(tag.getId(), tag.getName(), tag.getColour()); } From 8a1207337b6ce764cc1a4068702efa4ed9cfe299 Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Mon, 8 Aug 2016 16:15:55 +0200 Subject: [PATCH 098/118] Changed buildNotification method that error log dosn't have to be displayed in all cases Signed-off-by: Jonathan Philip Knoblauch --- .../hawkbit/ui/components/HawkbitUIErrorHandler.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index a860b7ff4..7729b72a4 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -36,8 +36,6 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { @Override public void error(final ErrorEvent event) { - LOG.error("Error in UI: ", event.getThrowable()); - final Optional originError = getPageOriginError(event); if (originError.isPresent()) { @@ -72,7 +70,11 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { } protected HawkbitErrorNotificationMessage buildNotification(final Throwable exception) { + LOG.error("Error in UI: ", exception); + return createHawkbitErrorNotificationMessage(exception); + } + protected HawkbitErrorNotificationMessage createHawkbitErrorNotificationMessage(final Throwable exception) { final I18N i18n = SpringContextHelper.getBean(I18N.class); return new HawkbitErrorNotificationMessage(STYLE, i18n.get("caption.error"), i18n.get("message.error.temp", exception.getClass().getSimpleName()), false); From 9cb1fe170b5caf20326cd701e1ef30533b1933c5 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 9 Aug 2016 11:50:18 +0200 Subject: [PATCH 099/118] clear tagDetails in BulkUpload Signed-off-by: Michael Hirsch --- .../hawkbit/ui/management/targettable/TargetBulkTokenTags.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkTokenTags.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkTokenTags.java index 1587951dd..bbcba62ff 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkTokenTags.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkTokenTags.java @@ -96,6 +96,7 @@ public class TargetBulkTokenTags extends AbstractTargetTagToken { @Override protected void populateContainer() { container.removeAllItems(); + tagDetails.clear(); for (final TargetTag tag : tagManagement.findAllTargetTags()) { setContainerPropertValues(tag.getId(), tag.getName(), tag.getColour()); } From df315bb42cfc73c42c66e62e4297cdc5cf7e80f7 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 9 Aug 2016 11:50:59 +0200 Subject: [PATCH 100/118] remove tagToken from map Signed-off-by: Michael Hirsch --- .../eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java | 1 + 1 file changed, 1 insertion(+) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java index 2df040c65..6d52b78d8 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/common/tagdetails/AbstractTagToken.java @@ -250,6 +250,7 @@ public abstract class AbstractTagToken implements Serializ protected void removeTokenItem(final Long tokenId, final String name) { tokenField.removeToken(tokenId); + tagDetails.remove(tokenId); setContainerPropertValues(tokenId, name, tokensAdded.get(tokenId).getColor()); } From 913692f94724449ff6647bdddb074a705ca377e8 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 10 Aug 2016 09:22:57 +0200 Subject: [PATCH 101/118] lock session on error showing error notification Signed-off-by: Michael Hirsch --- .../hawkbit/ui/components/HawkbitUIErrorHandler.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index 7729b72a4..bd56aba42 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -21,6 +21,7 @@ import com.google.common.base.Optional; import com.vaadin.server.DefaultErrorHandler; import com.vaadin.server.ErrorEvent; import com.vaadin.server.Page; +import com.vaadin.server.VaadinSession; import com.vaadin.ui.Component; /** @@ -40,7 +41,13 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { if (originError.isPresent()) { final HawkbitErrorNotificationMessage message = buildNotification(getRootExceptionFrom(event)); - message.show(originError.get()); + final VaadinSession current = VaadinSession.getCurrent(); + current.lock(); + try { + message.show(originError.get()); + } finally { + current.unlock(); + } } } From b53f4fc74fa3948c679c7d148be9f429b1c14208 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Wed, 10 Aug 2016 14:42:03 +0200 Subject: [PATCH 102/118] add json-creator to DdiDeploymentBase Signed-off-by: Michael Hirsch --- .../eclipse/hawkbit/ddi/json/model/DdiDeploymentBase.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeploymentBase.java b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeploymentBase.java index a058fd24a..a8f5ee72b 100644 --- a/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeploymentBase.java +++ b/hawkbit-ddi-api/src/main/java/org/eclipse/hawkbit/ddi/json/model/DdiDeploymentBase.java @@ -12,6 +12,7 @@ import javax.validation.constraints.NotNull; import org.springframework.hateoas.ResourceSupport; +import com.fasterxml.jackson.annotation.JsonCreator; import com.fasterxml.jackson.annotation.JsonProperty; /** @@ -34,7 +35,9 @@ public class DdiDeploymentBase extends ResourceSupport { * @param deployment * details. */ - public DdiDeploymentBase(final String id, final DdiDeployment deployment) { + @JsonCreator + public DdiDeploymentBase(@JsonProperty("id") final String id, + @JsonProperty("deplyomentId") final DdiDeployment deployment) { this.deplyomentId = id; this.deployment = deployment; } From 25fb8e55143b0c7d7d9470bc04a1f0e0c5427923 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Thu, 11 Aug 2016 09:50:38 +0200 Subject: [PATCH 103/118] introduce property to disable amqp interface in simulator Signed-off-by: Michael Hirsch --- examples/hawkbit-device-simulator/README.md | 6 +++++ .../simulator/SimulationController.java | 23 +++++++++++++------ .../simulator/amqp/AmqpConfiguration.java | 4 ++++ .../simulator/amqp/AmqpProperties.java | 19 +++++++++++++++ .../simulator/amqp/SpReceiverService.java | 4 ++++ .../hawkbit/simulator/ui/GenerateDialog.java | 14 ++++++++--- .../hawkbit/simulator/ui/SimulatorView.java | 6 ++++- .../src/main/resources/application.properties | 1 + 8 files changed, 66 insertions(+), 11 deletions(-) diff --git a/examples/hawkbit-device-simulator/README.md b/examples/hawkbit-device-simulator/README.md index 1ba29bb7e..ba241601a 100644 --- a/examples/hawkbit-device-simulator/README.md +++ b/examples/hawkbit-device-simulator/README.md @@ -24,6 +24,12 @@ The simulator has user authentication enabled in **cloud profile**. Default cred This can be configured/disabled by spring boot properties +## hawkBit APIs + +The simulator supports `DDI` as well as the `DMF` integration APIs. +In case there is no AMQP message broker (like rabbitMQ) running, you can disable the AMQP support for the device simulator, so the simulator is not trying to connect to a amqp message broker. +Configuration property `hawkbit.device.simulator.amqp.enabled=true` + ## Usage ### Graphical User Interface diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java index 43f954c00..b100cb28f 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulationController.java @@ -8,11 +8,13 @@ */ package org.eclipse.hawkbit.simulator; +import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX; + import java.net.MalformedURLException; import java.net.URL; import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Protocol; -import org.eclipse.hawkbit.simulator.amqp.SpSenderService; +import org.eclipse.hawkbit.simulator.amqp.AmqpProperties; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestMapping; @@ -21,22 +23,19 @@ import org.springframework.web.bind.annotation.RestController; /** * REST endpoint for controlling the device simulator. - * - * - * */ @RestController public class SimulationController { - @Autowired - private SpSenderService spSenderService; - @Autowired private DeviceSimulatorRepository repository; @Autowired private SimulatedDeviceFactory deviceFactory; + @Autowired + private AmqpProperties amqpProperties; + /** * The start resource to start a device creation. * @@ -82,6 +81,12 @@ public class SimulationController { return ResponseEntity.badRequest().body("query param api only allows value of 'dmf' or 'ddi'"); } + if (protocol == Protocol.DMF_AMQP && isDmfDisabled()) { + return ResponseEntity.badRequest() + .body("The AMQP interface has been disabled, to use DMF protocol you need to enable the AMQP interface via '" + + CONFIGURATION_PREFIX + ".enabled=true'"); + } + for (int i = 0; i < amount; i++) { final String deviceId = name + i; repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant, protocol, pollDelay, new URL(endpoint), @@ -90,4 +95,8 @@ public class SimulationController { return ResponseEntity.ok("Updated " + amount + " DMF connected targets!"); } + + private boolean isDmfDisabled() { + return !amqpProperties.isEnabled(); + } } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java index edaf9d11a..5e9b3e049 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpConfiguration.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.simulator.amqp; +import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX; + import java.time.Duration; import java.util.HashMap; import java.util.Map; @@ -27,6 +29,7 @@ import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.amqp.RabbitProperties; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -39,6 +42,7 @@ import org.springframework.retry.support.RetryTemplate; */ @Configuration @EnableConfigurationProperties(AmqpProperties.class) +@ConditionalOnProperty(prefix = CONFIGURATION_PREFIX, name = "enabled") public class AmqpConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger(AmqpConfiguration.class); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java index 8fba3ac5b..3730a3350 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/AmqpProperties.java @@ -19,6 +19,17 @@ import org.springframework.stereotype.Component; @Component @ConfigurationProperties("hawkbit.device.simulator.amqp") public class AmqpProperties { + + /** + * The prefix for this configuration. + */ + public static final String CONFIGURATION_PREFIX = "hawkbit.device.simulator.amqp"; + + /** + * Indicates if the AMQP interface is enabled for the device simulator. + */ + private boolean enabled; + /** * Queue for receiving DMF messages from update server. */ @@ -84,4 +95,12 @@ public class AmqpProperties { public void setDeadLetterTtl(final int deadLetterTtl) { this.deadLetterTtl = deadLetterTtl; } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + } } diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java index 7d55fb375..8dac6d4bc 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/amqp/SpReceiverService.java @@ -8,6 +8,8 @@ */ package org.eclipse.hawkbit.simulator.amqp; +import static org.eclipse.hawkbit.simulator.amqp.AmqpProperties.CONFIGURATION_PREFIX; + import java.util.Map; import org.eclipse.hawkbit.dmf.amqp.api.EventTopic; @@ -22,6 +24,7 @@ import org.springframework.amqp.core.MessageProperties; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.messaging.handler.annotation.Header; import org.springframework.stereotype.Component; @@ -32,6 +35,7 @@ import com.google.common.collect.Lists; * */ @Component +@ConditionalOnProperty(prefix = CONFIGURATION_PREFIX, name = "enabled") public class SpReceiverService extends ReceiverService { private static final Logger LOGGER = LoggerFactory.getLogger(ReceiverService.class); diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java index b50098829..6d1806463 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/GenerateDialog.java @@ -52,6 +52,7 @@ public class GenerateDialog extends Window { private final TextField gatewayTokenTextField; private OptionGroup protocolGroup; private Button buttonOk; + private final boolean dmfEnabled; /** * Creates a new pop window for setting the configuration of simulating @@ -60,9 +61,12 @@ public class GenerateDialog extends Window { * @param callback * the callback which is called when the dialog has been * successfully confirmed. + * @param dmfEnabled + * indicates if the AMQP/DMF interface is enabled by + * configuration and if the option DMF should be enabled or not */ - public GenerateDialog(final GenerateDialogCallback callback) { - + public GenerateDialog(final GenerateDialogCallback callback, final boolean dmfEnabled) { + this.dmfEnabled = dmfEnabled; formLayout.setSpacing(true); formLayout.setMargin(true); @@ -187,15 +191,19 @@ public class GenerateDialog extends Window { this.protocolGroup = new OptionGroup("Simulated Device Protocol"); protocolGroup.addItem(Protocol.DMF_AMQP); protocolGroup.addItem(Protocol.DDI_HTTP); + protocolGroup.select(Protocol.DMF_AMQP); protocolGroup.setItemCaption(Protocol.DMF_AMQP, "Device Management Federation API (AMQP push)"); protocolGroup.setItemCaption(Protocol.DDI_HTTP, "Direct Device Interface (HTTP poll)"); protocolGroup.setNullSelectionAllowed(false); - protocolGroup.select(Protocol.DMF_AMQP); protocolGroup.addValueChangeListener(event -> { final boolean directDeviceOptionSelected = event.getProperty().getValue().equals(Protocol.DDI_HTTP); pollUrlTextField.setVisible(directDeviceOptionSelected); gatewayTokenTextField.setVisible(directDeviceOptionSelected); }); + protocolGroup.setItemEnabled(Protocol.DMF_AMQP, dmfEnabled); + if (!dmfEnabled) { + protocolGroup.select(Protocol.DDI_HTTP); + } } private void createOkButton(final GenerateDialogCallback callback) { diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java index 686945407..25e575cf1 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java @@ -17,6 +17,7 @@ import org.eclipse.hawkbit.simulator.AbstractSimulatedDevice.Status; import org.eclipse.hawkbit.simulator.DeviceSimulatorRepository; import org.eclipse.hawkbit.simulator.SimulatedDeviceFactory; import org.eclipse.hawkbit.simulator.UpdateStatus.ResponseStatus; +import org.eclipse.hawkbit.simulator.amqp.AmqpProperties; import org.eclipse.hawkbit.simulator.amqp.SpSenderService; import org.eclipse.hawkbit.simulator.event.InitUpdate; import org.eclipse.hawkbit.simulator.event.NextPollCounterUpdate; @@ -90,6 +91,9 @@ public class SimulatorView extends VerticalLayout implements View { @Autowired private transient EventBus eventbus; + @Autowired + private transient AmqpProperties amqpProperties; + private final Label caption = new Label("DMF/DDI Simulated Devices"); private final HorizontalLayout toolbar = new HorizontalLayout(); private final Grid grid = new Grid(); @@ -268,7 +272,7 @@ public class SimulatorView extends VerticalLayout implements View { tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken))); spSenderService.createOrUpdateThing(tenant, deviceId); } - })); + }, amqpProperties.isEnabled())); } private ProtocolConverter createProtocolConverter() { diff --git a/examples/hawkbit-device-simulator/src/main/resources/application.properties b/examples/hawkbit-device-simulator/src/main/resources/application.properties index 5d3f04be7..60fa817e2 100644 --- a/examples/hawkbit-device-simulator/src/main/resources/application.properties +++ b/examples/hawkbit-device-simulator/src/main/resources/application.properties @@ -8,6 +8,7 @@ # ## Configuration for DMF communication +hawkbit.device.simulator.amqp.enabled=true hawkbit.device.simulator.amqp.receiverConnectorQueueFromSp=simulator_receiver hawkbit.device.simulator.amqp.deadLetterQueue=simulator_deadletter hawkbit.device.simulator.amqp.deadLetterExchange=simulator.deadletter From 9cc63ce1281e8f7818a6e9ad4ab803b2af789478 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 11 Aug 2016 13:25:24 +0200 Subject: [PATCH 104/118] Refactor UI Error Handler. Need to put UI in constructor. So the message is shown in the same browser window. Signed-off-by: Melanie Retter --- .../ui/components/HawkbitUIErrorHandler.java | 24 ++++++++++++++++--- .../targettable/BulkUploadHandler.java | 9 ++++--- .../TargetBulkUpdateWindowLayout.java | 3 ++- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index 7729b72a4..643d662eb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -18,10 +18,15 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.google.common.base.Optional; +import com.vaadin.server.ClientConnector.ConnectorErrorEvent; import com.vaadin.server.DefaultErrorHandler; import com.vaadin.server.ErrorEvent; import com.vaadin.server.Page; +import com.vaadin.shared.Connector; +import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.Component; +import com.vaadin.ui.Notification.Type; +import com.vaadin.ui.UI; /** * Default handler for SP UI. @@ -38,10 +43,23 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { final Optional originError = getPageOriginError(event); + final HawkbitErrorNotificationMessage message = buildNotification(getRootExceptionFrom(event)); + if (originError.isPresent()) { - final HawkbitErrorNotificationMessage message = buildNotification(getRootExceptionFrom(event)); - message.show(originError.get()); + final Connector connector = ((ConnectorErrorEvent) event).getConnector(); + // in case of BulkUpload + if (connector instanceof UI) { + ((UI) (((ConnectorErrorEvent) event).getConnector())).access(() -> message.show(originError.get())); + return; + } + // Other UI components + if (connector instanceof AbstractComponent) { + ((AbstractComponent) connector).getUI().access(() -> message.show(originError.get())); + return; + } } + // Default + HawkbitErrorNotificationMessage.show(message.getCaption(), message.getDescription(), Type.HUMANIZED_MESSAGE); } private static Throwable getRootExceptionFrom(final ErrorEvent event) { @@ -66,7 +84,7 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { return Optional.fromNullable(errorOrigin.getUI().getPage()); } - return Optional.of(Page.getCurrent()); + return Optional.absent(); } protected HawkbitErrorNotificationMessage buildNotification(final Throwable exception) { diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java index 83082be01..116853afb 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/BulkUploadHandler.java @@ -100,6 +100,7 @@ public class BulkUploadHandler extends CustomComponent final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout; private transient EntityFactory entityFactory; + private final UI uiInstance; /** * @@ -111,8 +112,9 @@ public class BulkUploadHandler extends CustomComponent */ public BulkUploadHandler(final TargetBulkUpdateWindowLayout targetBulkUpdateWindowLayout, final TargetManagement targetManagement, final ManagementUIState managementUIState, - final DeploymentManagement deploymentManagement, final I18N i18n) { + final DeploymentManagement deploymentManagement, final I18N i18n, final UI uiInstance) { this.targetBulkUpdateWindowLayout = targetBulkUpdateWindowLayout; + this.uiInstance = uiInstance; this.comboBox = targetBulkUpdateWindowLayout.getDsNamecomboBox(); this.descTextArea = targetBulkUpdateWindowLayout.getDescTextArea(); this.targetManagement = targetManagement; @@ -213,7 +215,6 @@ public class BulkUploadHandler extends CustomComponent * below event. */ eventBus.publish(this, new TargetTableEvent(TargetComponentEvent.BULK_UPLOAD_PROCESS_STARTED)); - while ((line = reader.readLine()) != null) { innerCounter++; readEachLine(line, innerCounter, totalFileSize); @@ -222,9 +223,7 @@ public class BulkUploadHandler extends CustomComponent } catch (final IOException e) { LOG.error("Error reading file {}", tempFile.getName(), e); } catch (final RuntimeException e) { - if (UI.getCurrent() != null) { - UI.getCurrent().getErrorHandler().error(new com.vaadin.server.ErrorEvent(e)); - } + uiInstance.getErrorHandler().error(new ConnectorErrorEvent(uiInstance, e)); } finally { deleteFile(); } diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java index b77576411..bfc889e7f 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/targettable/TargetBulkUpdateWindowLayout.java @@ -52,6 +52,7 @@ import com.vaadin.ui.Label; import com.vaadin.ui.Link; import com.vaadin.ui.ProgressBar; import com.vaadin.ui.TextArea; +import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; @@ -174,7 +175,7 @@ public class TargetBulkUpdateWindowLayout extends CustomComponent { private BulkUploadHandler getBulkUploadHandler() { final BulkUploadHandler bulkUploadHandler = new BulkUploadHandler(this, targetManagement, managementUIState, - deploymentManagement, i18n); + deploymentManagement, i18n, UI.getCurrent()); bulkUploadHandler.buildLayout(); bulkUploadHandler.addStyleName(SPUIStyleDefinitions.BULK_UPLOAD_BUTTON); return bulkUploadHandler; From 6205126279ef807ada376a1577a6a52edb1b651b Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 11 Aug 2016 13:54:28 +0200 Subject: [PATCH 105/118] Lock is only needed when BulkUpload Signed-off-by: Melanie Retter --- .../hawkbit/ui/components/HawkbitUIErrorHandler.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index 6eb37df3d..dcea17f8a 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -23,7 +23,6 @@ import com.vaadin.server.DefaultErrorHandler; import com.vaadin.server.ErrorEvent; import com.vaadin.server.Page; import com.vaadin.shared.Connector; -import com.vaadin.ui.AbstractComponent; import com.vaadin.ui.Component; import com.vaadin.ui.Notification.Type; import com.vaadin.ui.UI; @@ -47,16 +46,14 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { if (originError.isPresent()) { final Connector connector = ((ConnectorErrorEvent) event).getConnector(); - // in case of BulkUpload + // in case of BulkUpload: BulkUpload needs a look to show the + // notification if (connector instanceof UI) { ((UI) (((ConnectorErrorEvent) event).getConnector())).access(() -> message.show(originError.get())); return; } - // Other UI components - if (connector instanceof AbstractComponent) { - ((AbstractComponent) connector).getUI().access(() -> message.show(originError.get())); - return; - } + message.show(originError.get()); + return; } // Default HawkbitErrorNotificationMessage.show(message.getCaption(), message.getDescription(), Type.HUMANIZED_MESSAGE); From 4534ece86047da37683781c6747be8f9082e7c0a Mon Sep 17 00:00:00 2001 From: Gaurav Date: Thu, 11 Aug 2016 14:03:40 +0200 Subject: [PATCH 106/118] Fixed the issue of refreshing the tag details section for the distributions. Signed-off-by: Gaurav --- .../hawkbit/ui/distributions/dstable/DistributionSetTable.java | 2 +- .../hawkbit/ui/management/dstable/DistributionTable.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java index 3695ef488..6cda2cd16 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/dstable/DistributionSetTable.java @@ -137,7 +137,7 @@ public class DistributionSetTable extends AbstractNamedVersionTable e.getId().equals(ds.getId())).findFirst().isPresent()) { // update the name/version details visible in table UI.getCurrent().access(() -> updateDistributionInTable(event.getEntity())); diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java index 6e4714e14..e4313dd80 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/management/dstable/DistributionTable.java @@ -155,7 +155,7 @@ public class DistributionTable extends AbstractNamedVersionTable Date: Thu, 11 Aug 2016 14:15:19 +0200 Subject: [PATCH 107/118] Correct typo Signed-off-by: Melanie Retter --- .../eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index dcea17f8a..127063243 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -46,7 +46,7 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { if (originError.isPresent()) { final Connector connector = ((ConnectorErrorEvent) event).getConnector(); - // in case of BulkUpload: BulkUpload needs a look to show the + // in case of BulkUpload: BulkUpload needs a lock to show the // notification if (connector instanceof UI) { ((UI) (((ConnectorErrorEvent) event).getConnector())).access(() -> message.show(originError.get())); From 0d632d598a07a0918197e701cfd3155a43042bd5 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 11 Aug 2016 14:33:34 +0200 Subject: [PATCH 108/118] Delete empty rows in Java Doc Signed-off-by: Melanie Retter --- .../eclipse/hawkbit/repository/jpa/RolloutManagementTest.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/RolloutManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/RolloutManagementTest.java index b5cc84c9e..a23ada6e6 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/RolloutManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/RolloutManagementTest.java @@ -56,9 +56,6 @@ import ru.yandex.qatools.allure.annotations.Stories; /** * Junit tests for RolloutManagment. - * - * @author Michael Hirsch - * */ @Features("Component Tests - Repository") @Stories("Rollout Management") @@ -923,7 +920,6 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { private void validateStatus(final TotalTargetCountStatus totalTargetCountStatus, final Map expectedTotalCountStates) { - for (final Map.Entry entry : expectedTotalCountStates.entrySet()) { final Long countReady = totalTargetCountStatus.getTotalTargetCountByStatus(entry.getKey()); assertThat(countReady).isEqualTo(entry.getValue()); From 92fb82129acdf5e15ad07a083c8552d9971894c6 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 11 Aug 2016 16:05:22 +0200 Subject: [PATCH 109/118] Refactoring HawkbitUiErrorHandler Signed-off-by: Melanie Retter --- .../hawkbit/ui/components/HawkbitUIErrorHandler.java | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index 127063243..209e84790 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -46,16 +46,13 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { if (originError.isPresent()) { final Connector connector = ((ConnectorErrorEvent) event).getConnector(); - // in case of BulkUpload: BulkUpload needs a lock to show the - // notification if (connector instanceof UI) { - ((UI) (((ConnectorErrorEvent) event).getConnector())).access(() -> message.show(originError.get())); + ((UI) connector).access(() -> message.show(originError.get())); return; } message.show(originError.get()); return; } - // Default HawkbitErrorNotificationMessage.show(message.getCaption(), message.getDescription(), Type.HUMANIZED_MESSAGE); } @@ -86,10 +83,6 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { protected HawkbitErrorNotificationMessage buildNotification(final Throwable exception) { LOG.error("Error in UI: ", exception); - return createHawkbitErrorNotificationMessage(exception); - } - - protected HawkbitErrorNotificationMessage createHawkbitErrorNotificationMessage(final Throwable exception) { final I18N i18n = SpringContextHelper.getBean(I18N.class); return new HawkbitErrorNotificationMessage(STYLE, i18n.get("caption.error"), i18n.get("message.error.temp", exception.getClass().getSimpleName()), false); From 643eb238395c5b9e5df7e8922e6f9ce687ea18d4 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 11 Aug 2016 16:25:12 +0200 Subject: [PATCH 110/118] Revert method deletion Signed-off-by: Melanie Retter --- .../eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index 209e84790..15159cc8c 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -83,6 +83,10 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { protected HawkbitErrorNotificationMessage buildNotification(final Throwable exception) { LOG.error("Error in UI: ", exception); + return createHawkbitErrorNotificationMessage(exception); + } + + protected HawkbitErrorNotificationMessage createHawkbitErrorNotificationMessage(final Throwable exception) { final I18N i18n = SpringContextHelper.getBean(I18N.class); return new HawkbitErrorNotificationMessage(STYLE, i18n.get("caption.error"), i18n.get("message.error.temp", exception.getClass().getSimpleName()), false); From c3145bed58885f8675b38e06ac6025dad316cc57 Mon Sep 17 00:00:00 2001 From: Melanie Retter Date: Thu, 11 Aug 2016 17:51:39 +0200 Subject: [PATCH 111/118] Refactor: Log message can be overwritten Signed-off-by: Melanie Retter --- .../ui/components/HawkbitUIErrorHandler.java | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index 15159cc8c..229f85bf5 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -61,13 +61,13 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { return getRootCauseOf(event.getThrowable()); } - private static Throwable getRootCauseOf(final Throwable exception) { + private static Throwable getRootCauseOf(final Throwable ex) { - if (exception.getCause() != null) { - return getRootCauseOf(exception.getCause()); + if (ex.getCause() != null) { + return getRootCauseOf(ex.getCause()); } - return exception; + return ex; } private static Optional getPageOriginError(final ErrorEvent event) { @@ -81,15 +81,16 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { return Optional.absent(); } - protected HawkbitErrorNotificationMessage buildNotification(final Throwable exception) { - LOG.error("Error in UI: ", exception); - return createHawkbitErrorNotificationMessage(exception); - } + protected HawkbitErrorNotificationMessage buildNotification(final Throwable ex) { + + log(ex); - protected HawkbitErrorNotificationMessage createHawkbitErrorNotificationMessage(final Throwable exception) { final I18N i18n = SpringContextHelper.getBean(I18N.class); return new HawkbitErrorNotificationMessage(STYLE, i18n.get("caption.error"), - i18n.get("message.error.temp", exception.getClass().getSimpleName()), false); + i18n.get("message.error.temp", ex.getClass().getSimpleName()), false); } + protected void log(final Throwable exception) { + LOG.error("Error in UI: ", exception); + } } From e8393af749d8a93606ea21ae08f5c8dd8c675312 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Fri, 12 Aug 2016 09:54:18 +0200 Subject: [PATCH 112/118] adapt manifest Signed-off-by: Michael Hirsch --- examples/hawkbit-device-simulator/cf/manifest.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/hawkbit-device-simulator/cf/manifest.yml b/examples/hawkbit-device-simulator/cf/manifest.yml index 51a43ace6..188ef7780 100644 --- a/examples/hawkbit-device-simulator/cf/manifest.yml +++ b/examples/hawkbit-device-simulator/cf/manifest.yml @@ -17,6 +17,4 @@ applications: services: - dmf-rabbit env: - SPRING_PROFILES_ACTIVE: cloud,amqp - CF_STAGING_TIMEOUT: 15 - CF_STARTUP_TIMEOUT: 15 + SPRING_PROFILES_ACTIVE: cloud From 5d250a03be89f0e3601d2c17ce786e02f6bd1e3f Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Fri, 12 Aug 2016 14:28:25 +0200 Subject: [PATCH 113/118] Refactoring for error handler Signed-off-by: Jonathan Philip Knoblauch --- .../ui/components/HawkbitUIErrorHandler.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index 229f85bf5..964ed3646 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -41,19 +41,22 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { public void error(final ErrorEvent event) { final Optional originError = getPageOriginError(event); - final HawkbitErrorNotificationMessage message = buildNotification(getRootExceptionFrom(event)); - if (originError.isPresent()) { + if (!originError.isPresent()) { + HawkbitErrorNotificationMessage.show(message.getCaption(), message.getDescription(), + Type.HUMANIZED_MESSAGE); + return; + } + + if (event instanceof ConnectorErrorEvent) { final Connector connector = ((ConnectorErrorEvent) event).getConnector(); if (connector instanceof UI) { ((UI) connector).access(() -> message.show(originError.get())); return; } - message.show(originError.get()); - return; } - HawkbitErrorNotificationMessage.show(message.getCaption(), message.getDescription(), Type.HUMANIZED_MESSAGE); + message.show(originError.get()); } private static Throwable getRootExceptionFrom(final ErrorEvent event) { From 971b0aecb6058ce56ded8dac4ac7296c93176e60 Mon Sep 17 00:00:00 2001 From: Jonathan Philip Knoblauch Date: Fri, 12 Aug 2016 16:08:44 +0200 Subject: [PATCH 114/118] Refactoring error handler Signed-off-by: Jonathan Philip Knoblauch --- .../ui/components/HawkbitUIErrorHandler.java | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java index 964ed3646..cdbd04034 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/components/HawkbitUIErrorHandler.java @@ -40,27 +40,26 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { @Override public void error(final ErrorEvent event) { - final Optional originError = getPageOriginError(event); final HawkbitErrorNotificationMessage message = buildNotification(getRootExceptionFrom(event)); - - if (!originError.isPresent()) { - HawkbitErrorNotificationMessage.show(message.getCaption(), message.getDescription(), - Type.HUMANIZED_MESSAGE); - return; - } - if (event instanceof ConnectorErrorEvent) { final Connector connector = ((ConnectorErrorEvent) event).getConnector(); if (connector instanceof UI) { - ((UI) connector).access(() -> message.show(originError.get())); + final UI uiInstance = (UI) connector; + uiInstance.access(() -> message.show(uiInstance.getPage())); return; } } - message.show(originError.get()); + + final Optional originError = getPageOriginError(event); + if (originError.isPresent()) { + message.show(originError.get()); + return; + } + + HawkbitErrorNotificationMessage.show(message.getCaption(), message.getDescription(), Type.HUMANIZED_MESSAGE); } private static Throwable getRootExceptionFrom(final ErrorEvent event) { - return getRootCauseOf(event.getThrowable()); } @@ -84,16 +83,18 @@ public class HawkbitUIErrorHandler extends DefaultErrorHandler { return Optional.absent(); } + /** + * Method to build a notification based on an exception. + * + * @param ex + * the throwable + * @return a hawkbit error notification message + */ protected HawkbitErrorNotificationMessage buildNotification(final Throwable ex) { - - log(ex); - + LOG.error("Error in UI: ", ex); final I18N i18n = SpringContextHelper.getBean(I18N.class); return new HawkbitErrorNotificationMessage(STYLE, i18n.get("caption.error"), i18n.get("message.error.temp", ex.getClass().getSimpleName()), false); } - protected void log(final Throwable exception) { - LOG.error("Error in UI: ", exception); - } } From 196ce5643e02bc90ccf0b4c38bb2f636defb6474 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 15 Aug 2016 14:33:03 +0200 Subject: [PATCH 115/118] don't send amqp message when protocol is DDI Signed-off-by: Michael Hirsch --- .../org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java | 1 + .../java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java index 8d5c5e0b1..3a8690cb3 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatedDeviceFactory.java @@ -72,6 +72,7 @@ public class SimulatedDeviceFactory { final int pollDelaySec, final URL baseEndpoint, final String gatewayToken) { switch (protocol) { case DMF_AMQP: + spSenderService.createOrUpdateThing(tenant, id); return new DMFSimulatedDevice(id, tenant, spSenderService, pollDelaySec); case DDI_HTTP: final ControllerResource controllerResource = Feign.builder().logger(new Logger.ErrorLogger()) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java index 25e575cf1..4a81547c5 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/ui/SimulatorView.java @@ -270,7 +270,6 @@ public class SimulatorView extends VerticalLayout implements View { final String deviceId = namePrefix + index; beanContainer.addBean(repository.add(deviceFactory.createSimulatedDevice(deviceId, tenant.toLowerCase(), protocol, pollDelay, basePollUrl, gatewayToken))); - spSenderService.createOrUpdateThing(tenant, deviceId); } }, amqpProperties.isEnabled())); } From 9d54aa8c34c28754b714923131bb716153040445 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 15 Aug 2016 15:16:02 +0200 Subject: [PATCH 116/118] grammar corrected Signed-off-by: Michael Hirsch --- examples/hawkbit-device-simulator/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/hawkbit-device-simulator/README.md b/examples/hawkbit-device-simulator/README.md index ba241601a..0d73f3f3f 100644 --- a/examples/hawkbit-device-simulator/README.md +++ b/examples/hawkbit-device-simulator/README.md @@ -27,7 +27,7 @@ This can be configured/disabled by spring boot properties ## hawkBit APIs The simulator supports `DDI` as well as the `DMF` integration APIs. -In case there is no AMQP message broker (like rabbitMQ) running, you can disable the AMQP support for the device simulator, so the simulator is not trying to connect to a amqp message broker. +In case there is no AMQP message broker (like rabbitMQ) running, you can disable the AMQP support for the device simulator, so the simulator is not trying to connect to an amqp message broker. Configuration property `hawkbit.device.simulator.amqp.enabled=true` ## Usage From 7164b33e941f950da25488874e62474561db7b05 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Mon, 15 Aug 2016 15:33:18 +0200 Subject: [PATCH 117/118] don't generate amqp devices at startup if amqp is disabled Signed-off-by: Michael Hirsch --- .../hawkbit/simulator/SimulatorStartup.java | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java index 486eb4b5e..69ff765d0 100644 --- a/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java +++ b/examples/hawkbit-device-simulator/src/main/java/org/eclipse/hawkbit/simulator/SimulatorStartup.java @@ -11,7 +11,7 @@ package org.eclipse.hawkbit.simulator; import java.net.MalformedURLException; import java.net.URL; -import org.eclipse.hawkbit.simulator.amqp.SpSenderService; +import org.eclipse.hawkbit.simulator.amqp.AmqpProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -32,24 +32,27 @@ public class SimulatorStartup implements ApplicationListener { for (int i = 0; i < autostart.getAmount(); i++) { final String deviceId = autostart.getName() + i; try { - repository.add(deviceFactory.createSimulatedDevice(deviceId, autostart.getTenant(), - autostart.getApi(), autostart.getPollDelay(), new URL(autostart.getEndpoint()), - autostart.getGatewayToken())); + if (amqpProperties.isEnabled()) { + repository.add(deviceFactory.createSimulatedDevice(deviceId, autostart.getTenant(), + autostart.getApi(), autostart.getPollDelay(), new URL(autostart.getEndpoint()), + autostart.getGatewayToken())); + } + } catch (final MalformedURLException e) { LOGGER.error("Creation of simulated device at startup failed.", e); } From 79e0cccfa9ebe85c84b3905941f57e957d86cf88 Mon Sep 17 00:00:00 2001 From: Michael Hirsch Date: Tue, 16 Aug 2016 12:29:14 +0200 Subject: [PATCH 118/118] remove not used class Signed-off-by: Michael Hirsch --- .../jpa/model/DescriptorEventDetails.java | 49 ------------------- 1 file changed, 49 deletions(-) delete mode 100644 hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java deleted file mode 100644 index 091b2eb77..000000000 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/model/DescriptorEventDetails.java +++ /dev/null @@ -1,49 +0,0 @@ -/** - * 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.jpa.model; - -import org.eclipse.persistence.descriptors.DescriptorEvent; - -/** - * - * Holds details of action(Create/Update) and @link{DescriptorEvent}. - * - */ -public class DescriptorEventDetails { - - enum ActionType { - CREATE, UPDATE; - } - - private final DescriptorEvent descriptorEvent; - - private final ActionType actiontype; - - /** - * Constructor - * - * @param actionType - * Action type - * @param descriptorEvent - * Descriptor Event - */ - public DescriptorEventDetails(final ActionType actionType, final DescriptorEvent descriptorEvent) { - this.descriptorEvent = descriptorEvent; - this.actiontype = actionType; - } - - public DescriptorEvent getDescriptorEvent() { - return descriptorEvent; - } - - public ActionType getActiontype() { - return actiontype; - } - -}