diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpAuthenticationMessageHandler.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpAuthenticationMessageHandler.java index a3f7e4351..5394a4cd3 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpAuthenticationMessageHandler.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpAuthenticationMessageHandler.java @@ -13,20 +13,18 @@ import java.util.Optional; import java.util.UUID; import org.eclipse.hawkbit.api.HostnameResolver; -import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact; -import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash; import org.eclipse.hawkbit.cache.DownloadArtifactCache; import org.eclipse.hawkbit.cache.DownloadIdCache; import org.eclipse.hawkbit.cache.DownloadType; import org.eclipse.hawkbit.dmf.json.model.DmfArtifact; import org.eclipse.hawkbit.dmf.json.model.DmfArtifactHash; import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.model.Artifact; +import org.eclipse.hawkbit.security.DmfTenantSecurityToken; +import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.tenancy.TenantAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -188,54 +186,53 @@ public class AmqpAuthenticationMessageHandler extends BaseAmqpService { return Optional.empty(); } - private static DmfArtifact convertDbArtifact(final AbstractDbArtifact dbArtifact) { + private static DmfArtifact convertDbArtifact(final Artifact dbArtifact) { final DmfArtifact artifact = new DmfArtifact(); artifact.setSize(dbArtifact.getSize()); - final DbArtifactHash dbArtifactHash = dbArtifact.getHashes(); - artifact.setHashes(new DmfArtifactHash(dbArtifactHash.getSha1(), dbArtifactHash.getMd5())); + artifact.setHashes(new DmfArtifactHash(dbArtifact.getSha1Hash(), dbArtifact.getMd5Hash())); return artifact; } private Message handleAuthenticationMessage(final Message message) { - final DmfDownloadResponse authentificationResponse = new DmfDownloadResponse(); + final DmfDownloadResponse authenticationResponse = new DmfDownloadResponse(); final DmfTenantSecurityToken secruityToken = convertMessage(message, DmfTenantSecurityToken.class); final FileResource fileResource = secruityToken.getFileResource(); try { SecurityContextHolder.getContext().setAuthentication(authenticationManager.doAuthenticate(secruityToken)); - final String sha1Hash = findArtifactByFileResource(fileResource).map(Artifact::getSha1Hash) + final Artifact artifact = findArtifactByFileResource(fileResource) .orElseThrow(EntityNotFoundException::new); - checkIfArtifactIsAssignedToTarget(secruityToken, sha1Hash); + checkIfArtifactIsAssignedToTarget(secruityToken, artifact.getSha1Hash()); - final DmfArtifact artifact = convertDbArtifact(artifactManagement.loadArtifactBinary(sha1Hash) - .orElseThrow(() -> new EntityNotFoundException(Artifact.class, sha1Hash))); + final DmfArtifact dmfArtifact = convertDbArtifact(artifact); - authentificationResponse.setArtifact(artifact); + authenticationResponse.setArtifact(dmfArtifact); final String downloadId = UUID.randomUUID().toString(); // SHA1 key is set, download by SHA1 - final DownloadArtifactCache downloadCache = new DownloadArtifactCache(DownloadType.BY_SHA1, sha1Hash); + final DownloadArtifactCache downloadCache = new DownloadArtifactCache(DownloadType.BY_SHA1, + artifact.getSha1Hash()); cache.put(downloadId, downloadCache); - authentificationResponse.setDownloadUrl(UriComponentsBuilder + authenticationResponse.setDownloadUrl(UriComponentsBuilder .fromUri(hostnameResolver.resolveHostname().toURI()).path("/api/v1/downloadserver/downloadId/") .path(tenantAware.getCurrentTenant()).path("/").path(downloadId).build().toUriString()); - authentificationResponse.setResponseCode(HttpStatus.OK.value()); + authenticationResponse.setResponseCode(HttpStatus.OK.value()); } catch (final BadCredentialsException | AuthenticationServiceException | CredentialsExpiredException e) { LOG.error("Login failed", e); - authentificationResponse.setResponseCode(HttpStatus.FORBIDDEN.value()); - authentificationResponse.setMessage("Login failed"); + authenticationResponse.setResponseCode(HttpStatus.FORBIDDEN.value()); + authenticationResponse.setMessage("Login failed"); } catch (final URISyntaxException e) { LOG.error("URI build exception", e); - authentificationResponse.setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); - authentificationResponse.setMessage("Building download URI failed"); + authenticationResponse.setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value()); + authenticationResponse.setMessage("Building download URI failed"); } catch (final EntityNotFoundException e) { final String errorMessage = "Artifact for resource " + fileResource + "not found "; LOG.warn(errorMessage, e); - authentificationResponse.setResponseCode(HttpStatus.NOT_FOUND.value()); - authentificationResponse.setMessage(errorMessage); + authenticationResponse.setResponseCode(HttpStatus.NOT_FOUND.value()); + authenticationResponse.setMessage(errorMessage); } - return getMessageConverter().toMessage(authentificationResponse, message.getMessageProperties()); + return getMessageConverter().toMessage(authenticationResponse, message.getMessageProperties()); } } diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java index 66b12f9cb..a840e6747 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpConfiguration.java @@ -17,6 +17,7 @@ import org.eclipse.hawkbit.cache.DownloadIdCache; import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ControllerManagement; +import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.EntityFactory; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TargetManagement; @@ -305,31 +306,14 @@ public class AmqpConfiguration { tenantAware, ddiSecruityProperties, systemSecurityContext); } - /** - * Create the dispatcher bean. - * - * @param rabbitTemplate - * the rabbitTemplate - * @param amqpSenderService - * to send AMQP message - * @param artifactUrlHandler - * for generating download URLs - * @param systemSecurityContext - * for execution with system permissions - * @param systemManagement - * the systemManagement - * @param targetManagement - * to access target information - * @return the bean - */ @Bean @ConditionalOnMissingBean(AmqpMessageDispatcherService.class) - public AmqpMessageDispatcherService amqpMessageDispatcherService(final RabbitTemplate rabbitTemplate, + AmqpMessageDispatcherService amqpMessageDispatcherService(final RabbitTemplate rabbitTemplate, final AmqpMessageSenderService amqpSenderService, final ArtifactUrlHandler artifactUrlHandler, final SystemSecurityContext systemSecurityContext, final SystemManagement systemManagement, - final TargetManagement targetManagement) { + final TargetManagement targetManagement, final DistributionSetManagement distributionSetManagement) { return new AmqpMessageDispatcherService(rabbitTemplate, amqpSenderService, artifactUrlHandler, - systemSecurityContext, systemManagement, targetManagement, serviceMatcher); + systemSecurityContext, systemManagement, targetManagement, serviceMatcher, distributionSetManagement); } private static Map getTTLMaxArgsAuthenticationQueue() { diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentication.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentication.java index 581d0dea8..91c089f78 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentication.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthentication.java @@ -12,7 +12,6 @@ import java.util.List; import javax.annotation.PostConstruct; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.SystemManagement; @@ -23,6 +22,7 @@ import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter; import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter; import org.eclipse.hawkbit.security.DdiSecurityProperties; +import org.eclipse.hawkbit.security.DmfTenantSecurityToken; import org.eclipse.hawkbit.security.PreAuthTokenSourceTrustAuthenticationProvider; import org.eclipse.hawkbit.security.PreAuthentificationFilter; import org.eclipse.hawkbit.security.SystemSecurityContext; diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java index efc3e4ab8..38ea6a66a 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherService.java @@ -26,6 +26,7 @@ import org.eclipse.hawkbit.dmf.json.model.DmfArtifact; import org.eclipse.hawkbit.dmf.json.model.DmfArtifactHash; import org.eclipse.hawkbit.dmf.json.model.DmfDownloadAndUpdateRequest; import org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule; +import org.eclipse.hawkbit.repository.DistributionSetManagement; import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; @@ -64,6 +65,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService { private final SystemManagement systemManagement; private final TargetManagement targetManagement; private final ServiceMatcher serviceMatcher; + private final DistributionSetManagement distributionSetManagement; /** * Constructor. @@ -83,11 +85,14 @@ public class AmqpMessageDispatcherService extends BaseAmqpService { * @param serviceMatcher * to check in cluster case if the message is from the same * cluster node + * @param distributionSetManagement + * to retrieve modules */ - public AmqpMessageDispatcherService(final RabbitTemplate rabbitTemplate, + protected AmqpMessageDispatcherService(final RabbitTemplate rabbitTemplate, final AmqpMessageSenderService amqpSenderService, final ArtifactUrlHandler artifactUrlHandler, final SystemSecurityContext systemSecurityContext, final SystemManagement systemManagement, - final TargetManagement targetManagement, final ServiceMatcher serviceMatcher) { + final TargetManagement targetManagement, final ServiceMatcher serviceMatcher, + final DistributionSetManagement distributionSetManagement) { super(rabbitTemplate); this.artifactUrlHandler = artifactUrlHandler; this.amqpSenderService = amqpSenderService; @@ -95,6 +100,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService { this.systemManagement = systemManagement; this.targetManagement = targetManagement; this.serviceMatcher = serviceMatcher; + this.distributionSetManagement = distributionSetManagement; } /** @@ -105,21 +111,54 @@ public class AmqpMessageDispatcherService extends BaseAmqpService { * the object to be send. */ @EventListener(classes = TargetAssignDistributionSetEvent.class) - public void targetAssignDistributionSet(final TargetAssignDistributionSetEvent assignedEvent) { + protected void targetAssignDistributionSet(final TargetAssignDistributionSetEvent assignedEvent) { if (isNotFromSelf(assignedEvent)) { return; } - LOG.debug("targetAssignDistributionSet retrieved for controller {}. I will forward it to DMF broker.", - assignedEvent.getControllerId()); + LOG.debug("targetAssignDistributionSet retrieved. I will forward it to DMF broker."); - targetManagement.getByControllerID(assignedEvent.getControllerId()) - .ifPresent(target -> sendUpdateMessageToTarget(assignedEvent.getTenant(), target, - assignedEvent.getActionId(), assignedEvent.getModules())); + distributionSetManagement.get(assignedEvent.getDistributionSetId()).ifPresent(set -> + targetManagement.getByControllerID(assignedEvent.getActions().keySet()) + .forEach(target -> sendUpdateMessageToTarget(assignedEvent.getTenant(), target, + assignedEvent.getActions().get(target.getControllerId()), set.getModules()))); } - void sendUpdateMessageToTarget(final String tenant, final Target target, final Long actionId, + /** + * Method to send a message to a RabbitMQ Exchange after the assignment of + * the Distribution set to a Target has been canceled. + * + * @param cancelEvent + * the object to be send. + */ + @EventListener(classes = CancelTargetAssignmentEvent.class) + protected void targetCancelAssignmentToDistributionSet(final CancelTargetAssignmentEvent cancelEvent) { + if (isNotFromSelf(cancelEvent)) { + return; + } + + sendCancelMessageToTarget(cancelEvent.getTenant(), cancelEvent.getEntity().getControllerId(), + cancelEvent.getActionId(), cancelEvent.getEntity().getAddress()); + } + + /** + * Method to send a message to a RabbitMQ Exchange after a Target was + * deleted. + * + * @param deleteEvent + * the TargetDeletedEvent which holds the necessary data for + * sending a target delete message. + */ + @EventListener(classes = TargetDeletedEvent.class) + protected void targetDelete(final TargetDeletedEvent deleteEvent) { + if (isNotFromSelf(deleteEvent)) { + return; + } + sendDeleteMessage(deleteEvent.getTenant(), deleteEvent.getControllerId(), deleteEvent.getTargetAddress()); + } + + protected void sendUpdateMessageToTarget(final String tenant, final Target target, final Long actionId, final Collection modules) { final URI targetAdress = target.getAddress(); @@ -144,7 +183,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService { amqpSenderService.sendMessage(message, targetAdress); } - void sendPingReponseToDmfReceiver(final Message ping, final String tenant, final String virtualHost) { + protected void sendPingReponseToDmfReceiver(final Message ping, final String tenant, final String virtualHost) { final Message message = MessageBuilder.withBody(String.valueOf(System.currentTimeMillis()).getBytes()) .setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN) .setCorrelationId(ping.getMessageProperties().getCorrelationId()) @@ -155,40 +194,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService { IpUtil.createAmqpUri(virtualHost, ping.getMessageProperties().getReplyTo())); } - /** - * Method to send a message to a RabbitMQ Exchange after the assignment of - * the Distribution set to a Target has been canceled. - * - * @param cancelEvent - * the object to be send. - */ - @EventListener(classes = CancelTargetAssignmentEvent.class) - public void targetCancelAssignmentToDistributionSet(final CancelTargetAssignmentEvent cancelEvent) { - if (isNotFromSelf(cancelEvent)) { - return; - } - - sendCancelMessageToTarget(cancelEvent.getTenant(), cancelEvent.getEntity().getControllerId(), - cancelEvent.getActionId(), cancelEvent.getEntity().getAddress()); - } - - /** - * Method to send a message to a RabbitMQ Exchange after a Target was - * deleted. - * - * @param deleteEvent - * the TargetDeletedEvent which holds the necessary data for - * sending a target delete message. - */ - @EventListener(classes = TargetDeletedEvent.class) - public void targetDelete(final TargetDeletedEvent deleteEvent) { - if (isNotFromSelf(deleteEvent)) { - return; - } - sendDeleteMessage(deleteEvent.getTenant(), deleteEvent.getControllerId(), deleteEvent.getTargetAddress()); - } - - void sendDeleteMessage(final String tenant, final String controllerId, final String targetAddress) { + protected void sendDeleteMessage(final String tenant, final String controllerId, final String targetAddress) { if (!hasValidAddress(targetAddress)) { return; @@ -206,7 +212,7 @@ public class AmqpMessageDispatcherService extends BaseAmqpService { return serviceMatcher != null && !serviceMatcher.isFromSelf(event); } - void sendCancelMessageToTarget(final String tenant, final String controllerId, final Long actionId, + protected void sendCancelMessageToTarget(final String tenant, final String controllerId, final Long actionId, final URI address) { if (!IpUtil.isAmqpUri(address)) { return; diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java index 075650ee5..b7bb911b9 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpControllerAuthenticationTest.java @@ -28,8 +28,6 @@ import org.eclipse.hawkbit.cache.DownloadIdCache; import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey; import org.eclipse.hawkbit.dmf.amqp.api.MessageType; import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.SystemManagement; @@ -42,7 +40,9 @@ import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; import org.eclipse.hawkbit.repository.model.TenantMetaData; import org.eclipse.hawkbit.security.DdiSecurityProperties; +import org.eclipse.hawkbit.security.DmfTenantSecurityToken; import org.eclipse.hawkbit.security.DdiSecurityProperties.Authentication.Anonymous; +import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.security.DdiSecurityProperties.Rp; import org.eclipse.hawkbit.security.SecurityContextTenantAware; import org.eclipse.hawkbit.security.SystemSecurityContext; diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java index 9481430bd..483ff6eba 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageDispatcherServiceTest.java @@ -108,28 +108,14 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTest { when(systemManagement.getTenantMetadata()).thenReturn(tenantMetaData); amqpMessageDispatcherService = new AmqpMessageDispatcherService(rabbitTemplate, senderService, - artifactUrlHandlerMock, systemSecurityContext, systemManagement, targetManagement, serviceMatcher); + artifactUrlHandlerMock, systemSecurityContext, systemManagement, targetManagement, serviceMatcher, + distributionSetManagement); } - @Test - @Description("Verifies that download and install event with no software modul works") - public void testSendDownloadRequesWithEmptySoftwareModules() { - - final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent = new TargetAssignDistributionSetEvent( - "DEFAULT", 1L, 1L, CONTROLLER_ID, serviceMatcher.getServiceId()); - amqpMessageDispatcherService.targetAssignDistributionSet(targetAssignDistributionSetEvent); - - final Message sendMessage = getCaptureAdressEvent(targetAssignDistributionSetEvent); - final DmfDownloadAndUpdateRequest downloadAndUpdateRequest = assertDownloadAndInstallMessage(sendMessage, 1L); - assertThat(downloadAndUpdateRequest.getTargetSecurityToken()).isEqualTo(TEST_TOKEN); - assertTrue("No softwaremmodule should be contained in the request", - downloadAndUpdateRequest.getSoftwareModules().isEmpty()); - } - private Message getCaptureAdressEvent(final TargetAssignDistributionSetEvent targetAssignDistributionSetEvent) { - final Target target = targetManagement.getByControllerID(targetAssignDistributionSetEvent.getControllerId()) - .get(); + final Target target = targetManagement + .getByControllerID(targetAssignDistributionSetEvent.getActions().keySet().iterator().next()).get(); final Message sendMessage = createArgumentCapture(target.getAddress()); return sendMessage; } diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java index a70e11c1d..7b8e8c44e 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerServiceTest.java @@ -28,8 +28,6 @@ import java.util.Optional; import org.eclipse.hawkbit.api.HostnameResolver; import org.eclipse.hawkbit.artifact.repository.ArtifactRepository; -import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact; -import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash; import org.eclipse.hawkbit.cache.DownloadIdCache; import org.eclipse.hawkbit.dmf.amqp.api.EventTopic; import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey; @@ -38,8 +36,6 @@ import org.eclipse.hawkbit.dmf.json.model.DmfActionStatus; import org.eclipse.hawkbit.dmf.json.model.DmfActionUpdateStatus; import org.eclipse.hawkbit.dmf.json.model.DmfAttributeUpdate; import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.repository.ArtifactManagement; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.EntityFactory; @@ -52,6 +48,8 @@ import org.eclipse.hawkbit.repository.model.Action.Status; import org.eclipse.hawkbit.repository.model.Artifact; import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.Target; +import org.eclipse.hawkbit.security.DmfTenantSecurityToken; +import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.security.SecurityTokenGenerator; import org.eclipse.hawkbit.tenancy.TenantAware; import org.junit.Before; @@ -370,15 +368,12 @@ public class AmqpMessageHandlerServiceTest { // mock final Artifact localArtifactMock = mock(Artifact.class); when(localArtifactMock.getSha1Hash()).thenReturn(SHA1); + when(localArtifactMock.getMd5Hash()).thenReturn("md5"); + when(localArtifactMock.getSize()).thenReturn(1L); - final AbstractDbArtifact dbArtifactMock = mock(AbstractDbArtifact.class); when(artifactManagementMock.findFirstBySHA1(SHA1)).thenReturn(Optional.of(localArtifactMock)); when(controllerManagementMock.hasTargetArtifactAssigned(securityToken.getControllerId(), SHA1)) .thenReturn(true); - when(artifactManagementMock.loadArtifactBinary(anyString())).thenReturn(Optional.of(dbArtifactMock)); - when(dbArtifactMock.getArtifactId()).thenReturn("artifactId"); - when(dbArtifactMock.getSize()).thenReturn(1L); - when(dbArtifactMock.getHashes()).thenReturn(new DbArtifactHash(SHA1, "md5")); when(hostnameResolverMock.resolveHostname()).thenReturn(new URL("http://localhost")); // test diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpAuthenticationMessageHandlerIntegrationTest.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpAuthenticationMessageHandlerIntegrationTest.java index 0c93c514c..ef7749a76 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpAuthenticationMessageHandlerIntegrationTest.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpAuthenticationMessageHandlerIntegrationTest.java @@ -18,8 +18,6 @@ import org.eclipse.hawkbit.amqp.AmqpProperties; import org.eclipse.hawkbit.amqp.DmfApiConfiguration; import org.eclipse.hawkbit.dmf.amqp.api.AmqpSettings; import org.eclipse.hawkbit.dmf.json.model.DmfDownloadResponse; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.rabbitmq.test.AbstractAmqpIntegrationTest; import org.eclipse.hawkbit.rabbitmq.test.AmqpTestConfiguration; import org.eclipse.hawkbit.repository.jpa.RepositoryApplicationConfiguration; @@ -28,6 +26,8 @@ import org.eclipse.hawkbit.repository.model.DistributionSet; 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.DmfTenantSecurityToken; +import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.junit.Before; import org.junit.Test; 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 d70cd7406..f81b4a393 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 @@ -21,9 +21,8 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; +import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.tenancy.TenantAware; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java index 30f4c2786..eb90ebd87 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/DeploymentManagement.java @@ -407,7 +407,8 @@ public interface DeploymentManagement { * @return the amount of started actions */ @PreAuthorize(SpringEvalExpressions.HAS_AUTH_READ_TARGET) - long startScheduledActionsByRolloutGroupParent(@NotNull Long rolloutId, Long rolloutGroupParentId); + long startScheduledActionsByRolloutGroupParent(@NotNull Long rolloutId, @NotNull Long distributionSetId, + Long rolloutGroupParentId); /** * All {@link ActionStatus} entries in the repository. diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/TargetAssignDistributionSetEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/TargetAssignDistributionSetEvent.java index a1fcd8158..8829ee9c0 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/TargetAssignDistributionSetEvent.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/TargetAssignDistributionSetEvent.java @@ -8,15 +8,13 @@ */ package org.eclipse.hawkbit.repository.event.remote; -import java.util.Collection; -import java.util.Collections; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.DistributionSet; -import org.eclipse.hawkbit.repository.model.SoftwareModule; -import org.eclipse.hawkbit.repository.model.Target; - -import com.fasterxml.jackson.annotation.JsonIgnore; /** * TenantAwareEvent that gets sent when a distribution set gets assigned to a @@ -26,13 +24,9 @@ public class TargetAssignDistributionSetEvent extends RemoteTenantAwareEvent { private static final long serialVersionUID = 1L; - private Long actionId; + private long distributionSetId; - private Long distributionSetId; - - private String controllerId; - - private transient Collection modules; + private final Map actions = new HashMap<>(); /** * Default constructor. @@ -43,61 +37,35 @@ public class TargetAssignDistributionSetEvent extends RemoteTenantAwareEvent { /** * Constructor. - * - * @param action - * the action + * + * @param tenant + * of the event + * @param distributionSetId + * of the set that was assigned + * @param a + * the actions and the targets * @param applicationId * the application id. */ - public TargetAssignDistributionSetEvent(final Action action, final String applicationId) { - this(action.getTenant(), action.getId(), action.getDistributionSet().getId(), - action.getTarget().getControllerId(), applicationId); - this.modules = action.getDistributionSet().getModules(); - - } - - /** - * Constructor. - * - * @param tenant - * the event belongs to - * @param actionId - * to the action - * @param distributionSetId - * of the assigned {@link DistributionSet} - * @param controllerId - * of the assignment {@link Target} - * @param applicationId - */ - public TargetAssignDistributionSetEvent(final String tenant, final Long actionId, final Long distributionSetId, - final String controllerId, final String applicationId) { - super(actionId, tenant, applicationId); - this.actionId = actionId; + public TargetAssignDistributionSetEvent(final String tenant, final long distributionSetId, final List a, + final String applicationId) { + super(distributionSetId, tenant, applicationId); this.distributionSetId = distributionSetId; - this.controllerId = controllerId; + actions.putAll(a.stream().filter(action -> action.getDistributionSet().getId().longValue() == distributionSetId) + .collect(Collectors.toMap(action -> action.getTarget().getControllerId(), Action::getId))); + } - public Long getActionId() { - return actionId; - } - - public String getControllerId() { - return controllerId; + public TargetAssignDistributionSetEvent(final Action action, final String applicationId) { + this(action.getTenant(), action.getDistributionSet().getId(), Arrays.asList(action), applicationId); } public Long getDistributionSetId() { return distributionSetId; } - /** - * @return modules if Event has been published by same node otherwise empty. - */ - @JsonIgnore - public Collection getModules() { - if (modules == null) { - return Collections.emptyList(); - } - - return modules; + public Map getActions() { + return actions; } + } diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/BusProtoStuffMessageConverter.java b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/BusProtoStuffMessageConverter.java index 8a6adbd5d..438f45445 100644 --- a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/BusProtoStuffMessageConverter.java +++ b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/BusProtoStuffMessageConverter.java @@ -19,7 +19,6 @@ import org.springframework.util.MimeType; import io.protostuff.LinkedBuffer; import io.protostuff.ProtobufIOUtil; -import io.protostuff.ProtostuffIOUtil; import io.protostuff.Schema; import io.protostuff.runtime.RuntimeSchema; @@ -127,7 +126,7 @@ public class BusProtoStuffMessageConverter extends AbstractMessageConverter { @SuppressWarnings("unchecked") final Schema schema = (Schema) RuntimeSchema.getSchema(serializeClass); final LinkedBuffer buffer = LinkedBuffer.allocate(); - return writeProtoBuf(payload, schema, buffer); + return ProtobufIOUtil.toByteArray(payload, schema, buffer); } private static byte[] writeClassHeader(final Class clazz) { @@ -140,17 +139,6 @@ public class BusProtoStuffMessageConverter extends AbstractMessageConverter { final Schema schema = (Schema) RuntimeSchema .getSchema((Class) EventType.class); final LinkedBuffer buffer = LinkedBuffer.allocate(); - return writeProtoBuf(clazzEventType, schema, buffer); - } - - private static byte[] writeProtoBuf(final Object payload, final Schema schema, final LinkedBuffer buffer) { - final byte[] serializeByte; - try { - serializeByte = ProtostuffIOUtil.toByteArray(payload, schema, buffer); - } finally { - buffer.clear(); - } - - return serializeByte; + return ProtobufIOUtil.toByteArray(clazzEventType, schema, buffer); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/AbstractDsAssignmentStrategy.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/AbstractDsAssignmentStrategy.java index bd52a5f5d..ffa5da1ae 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/AbstractDsAssignmentStrategy.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/AbstractDsAssignmentStrategy.java @@ -31,6 +31,7 @@ import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetWithActionType; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationEventPublisher; +import org.springframework.util.CollectionUtils; /** * {@link DistributionSet} to {@link Target} assignment strategy as utility for @@ -109,6 +110,8 @@ public abstract class AbstractDsAssignmentStrategy { /** * Handles event sending related to the assignment. * + * @param set + * that has been assigned * @param targets * to send events for * @param targetIdsCancelList @@ -117,12 +120,17 @@ public abstract class AbstractDsAssignmentStrategy { * mapping of {@link Target#getControllerId()} to new * {@link Action} that was created as part of the assignment. */ - abstract void sendAssignmentEvents(final List targets, final Set targetIdsCancelList, - final Map controllerIdsToActions); + abstract void sendAssignmentEvents(DistributionSet set, final List targets, + final Set targetIdsCancelList, final Map controllerIdsToActions); - protected void sendTargetAssignDistributionSetEvent(final Action action) { - afterCommit.afterCommit(() -> eventPublisher - .publishEvent(new TargetAssignDistributionSetEvent(action, applicationContext.getId()))); + protected void sendTargetAssignDistributionSetEvent(final String tenant, final long distributionSetId, + final List actions) { + if (CollectionUtils.isEmpty(actions)) { + return; + } + + afterCommit.afterCommit(() -> eventPublisher.publishEvent( + new TargetAssignDistributionSetEvent(tenant, distributionSetId, actions, applicationContext.getId()))); } protected void sendTargetUpdatedEvent(final JpaTarget target) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java index d2ed67bcf..9cc70e95b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaDeploymentManagement.java @@ -13,6 +13,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.function.Function; @@ -24,7 +25,6 @@ import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.JoinType; import javax.persistence.criteria.ListJoin; import javax.persistence.criteria.Root; -import javax.validation.constraints.NotNull; import org.eclipse.hawkbit.repository.ActionFields; import org.eclipse.hawkbit.repository.DeploymentManagement; @@ -80,6 +80,7 @@ import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.DefaultTransactionDefinition; import org.springframework.transaction.support.TransactionTemplate; +import org.springframework.util.CollectionUtils; import org.springframework.validation.annotation.Validated; import com.google.common.collect.Lists; @@ -306,7 +307,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { // detaching as the entity has been updated by the JPQL query above targets.forEach(entityManager::detach); - assignmentStrategy.sendAssignmentEvents(targets, targetIdsCancellList, targetIdsToActions); + assignmentStrategy.sendAssignmentEvents(set, targets, targetIdsCancellList, targetIdsToActions); return new DistributionSetAssignmentResult( targets.stream().map(Target::getControllerId).collect(Collectors.toList()), targets.size(), @@ -373,13 +374,13 @@ public class JpaDeploymentManagement implements DeploymentManagement { } @Override - public long startScheduledActionsByRolloutGroupParent(@NotNull final Long rolloutId, + public long startScheduledActionsByRolloutGroupParent(final Long rolloutId, final Long distributionSetId, final Long rolloutGroupParentId) { long totalActionsCount = 0L; long lastStartedActionsCount; do { lastStartedActionsCount = startScheduledActionsByRolloutGroupParentInNewTransaction(rolloutId, - rolloutGroupParentId, ACTION_PAGE_LIMIT); + distributionSetId, rolloutGroupParentId, ACTION_PAGE_LIMIT); totalActionsCount += lastStartedActionsCount; } while (lastStartedActionsCount > 0); @@ -387,7 +388,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { } private long startScheduledActionsByRolloutGroupParentInNewTransaction(final Long rolloutId, - final Long rolloutGroupParentId, final int limit) { + final Long distributionSetId, final Long rolloutGroupParentId, final int limit) { final DefaultTransactionDefinition def = new DefaultTransactionDefinition(); def.setName("startScheduledActions-" + rolloutId); def.setReadOnly(false); @@ -396,7 +397,21 @@ public class JpaDeploymentManagement implements DeploymentManagement { final Page rolloutGroupActions = findActionsByRolloutAndRolloutGroupParent(rolloutId, rolloutGroupParentId, limit); - rolloutGroupActions.map(action -> (JpaAction) action).forEach(this::startScheduledAction); + if (rolloutGroupActions.getContent().isEmpty()) { + return 0L; + } + + final String tenant = rolloutGroupActions.getContent().get(0).getTenant(); + + final List targetAssignments = rolloutGroupActions.getContent().stream() + .map(action -> (JpaAction) action).map(this::closeActionIfSetWasAlreadyAssigned) + .filter(Objects::nonNull).map(this::startScheduledActionIfNoCancelationHasToBeHandledFirst) + .filter(Objects::nonNull).collect(Collectors.toList()); + + if (!CollectionUtils.isEmpty(targetAssignments)) { + afterCommit.afterCommit(() -> eventPublisher.publishEvent(new TargetAssignDistributionSetEvent(tenant, + distributionSetId, targetAssignments, applicationContext.getId()))); + } return rolloutGroupActions.getTotalElements(); }); @@ -415,9 +430,8 @@ public class JpaDeploymentManagement implements DeploymentManagement { } } - private void startScheduledAction(final JpaAction action) { - JpaTarget target = (JpaTarget) action.getTarget(); - + private JpaAction closeActionIfSetWasAlreadyAssigned(final JpaAction action) { + final JpaTarget target = (JpaTarget) action.getTarget(); if (target.getAssignedDistributionSet() != null && action.getDistributionSet().getId().equals(target.getAssignedDistributionSet().getId())) { // the target has already the distribution set assigned, we don't @@ -426,9 +440,13 @@ public class JpaDeploymentManagement implements DeploymentManagement { action.setActive(false); setSkipActionStatus(action); actionRepository.save(action); - return; + return null; } + return action; + } + + private JpaAction startScheduledActionIfNoCancelationHasToBeHandledFirst(final JpaAction action) { // check if we need to override running update actions final List overrideObsoleteUpdateActions = onlineDsAssignmentStrategy .overrideObsoleteUpdateActions(Collections.singletonList(action.getTarget().getId())); @@ -439,7 +457,7 @@ public class JpaDeploymentManagement implements DeploymentManagement { actionStatusRepository.save(onlineDsAssignmentStrategy.createActionStatus(savedAction, null)); - target = (JpaTarget) entityManager.merge(savedAction.getTarget()); + final JpaTarget target = (JpaTarget) entityManager.merge(savedAction.getTarget()); target.setAssignedDistributionSet(savedAction.getDistributionSet()); target.setUpdateStatus(TargetUpdateStatus.PENDING); @@ -447,10 +465,11 @@ public class JpaDeploymentManagement implements DeploymentManagement { // in case we canceled an action before for this target, then don't fire // assignment event - if (!overrideObsoleteUpdateActions.contains(savedAction.getId())) { - afterCommit.afterCommit(() -> eventPublisher - .publishEvent(new TargetAssignDistributionSetEvent(savedAction, applicationContext.getId()))); + if (overrideObsoleteUpdateActions.contains(savedAction.getId())) { + return null; } + + return savedAction; } private void setSkipActionStatus(final JpaAction action) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java index 7996656f6..244349994 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/JpaRolloutManagement.java @@ -367,8 +367,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement { RolloutGroupStatus.READY, group); final long targetsInGroupFilter = runInNewTransaction("countAllTargetsByTargetFilterQueryAndNotInRolloutGroups", - count -> targetManagement.countByRsqlAndNotInRolloutGroups(readyGroups, - groupTargetFilter)); + count -> targetManagement.countByRsqlAndNotInRolloutGroups(readyGroups, groupTargetFilter)); final long expectedInGroup = Math.round(group.getTargetPercentage() / 100 * (double) targetsInGroupFilter); final long currentlyInGroup = runInNewTransaction("countRolloutTargetGroupByRolloutGroup", count -> rolloutTargetGroupRepository.countByRolloutGroup(group)); @@ -408,8 +407,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement { final PageRequest pageRequest = new PageRequest(0, Math.toIntExact(limit)); final List readyGroups = RolloutHelper.getGroupsByStatusIncludingGroup(rollout.getRolloutGroups(), RolloutGroupStatus.READY, group); - final Page targets = targetManagement - .findByTargetFilterQueryAndNotInRolloutGroups(pageRequest, readyGroups, targetFilter); + final Page targets = targetManagement.findByTargetFilterQueryAndNotInRolloutGroups(pageRequest, + readyGroups, targetFilter); createAssignmentOfTargetsToGroup(targets, group); @@ -461,7 +460,8 @@ public class JpaRolloutManagement extends AbstractRolloutManagement { throw new RolloutIllegalStateException("First Group is not the first group."); } - deploymentManagement.startScheduledActionsByRolloutGroupParent(rollout.getId(), null); + deploymentManagement.startScheduledActionsByRolloutGroupParent(rollout.getId(), + rollout.getDistributionSet().getId(), null); rolloutGroup.setStatus(RolloutGroupStatus.RUNNING); rolloutGroupRepository.save(rolloutGroup); @@ -530,8 +530,7 @@ public class JpaRolloutManagement extends AbstractRolloutManagement { final ActionType actionType = rollout.getActionType(); final long forceTime = rollout.getForcedTime(); - final Page targets = targetManagement.findByInRolloutGroupWithoutAction(pageRequest, - groupId); + final Page targets = targetManagement.findByInRolloutGroupWithoutAction(pageRequest, groupId); if (targets.getTotalElements() > 0) { createScheduledAction(targets.getContent(), distributionSet, actionType, forceTime, rollout, group); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/OfflineDsAssignmentStrategy.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/OfflineDsAssignmentStrategy.java index 1fb831718..0888c222d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/OfflineDsAssignmentStrategy.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/OfflineDsAssignmentStrategy.java @@ -25,6 +25,7 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.specifications.SpecificationsBuilder; import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications; import org.eclipse.hawkbit.repository.model.Action.Status; +import org.eclipse.hawkbit.repository.model.DistributionSet; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TargetWithActionType; import org.springframework.context.ApplicationContext; @@ -48,8 +49,8 @@ public class OfflineDsAssignmentStrategy extends AbstractDsAssignmentStrategy { } @Override - void sendAssignmentEvents(final List targets, final Set targetIdsCancellList, - final Map targetIdsToActions) { + void sendAssignmentEvents(final DistributionSet set, final List targets, + final Set targetIdsCancellList, final Map targetIdsToActions) { targets.forEach(target -> { target.setUpdateStatus(TargetUpdateStatus.IN_SYNC); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/OnlineDsAssignmentStrategy.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/OnlineDsAssignmentStrategy.java index 4f42987bf..bddac629b 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/OnlineDsAssignmentStrategy.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/OnlineDsAssignmentStrategy.java @@ -21,7 +21,10 @@ import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; import org.eclipse.hawkbit.repository.jpa.model.JpaDistributionSet; import org.eclipse.hawkbit.repository.jpa.model.JpaTarget; import org.eclipse.hawkbit.repository.jpa.specifications.TargetSpecifications; +import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.Status; +import org.eclipse.hawkbit.repository.model.DistributionSet; +import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.repository.model.TargetUpdateStatus; import org.eclipse.hawkbit.repository.model.TargetWithActionType; import org.springframework.context.ApplicationContext; @@ -44,18 +47,19 @@ public class OnlineDsAssignmentStrategy extends AbstractDsAssignmentStrategy { } @Override - void sendAssignmentEvents(final List targets, final Set targetIdsCancellList, - final Map targetIdsToActions) { + void sendAssignmentEvents(final DistributionSet set, final List targets, + final Set targetIdsCancellList, final Map targetIdsToActions) { - targets.forEach(target -> { + final List actions = targets.stream().map(target -> { target.setUpdateStatus(TargetUpdateStatus.PENDING); sendTargetUpdatedEvent(target); - if (targetIdsCancellList.contains(target.getId())) { - return; - } - sendTargetAssignDistributionSetEvent(targetIdsToActions.get(target.getControllerId())); - }); + return target; + }).filter(target -> !targetIdsCancellList.contains(target.getId())).map(Target::getControllerId) + .map(targetIdsToActions::get).collect(Collectors.toList()); + + sendTargetAssignDistributionSetEvent(set.getTenant(), set.getId(), actions); + } @Override diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rollout/condition/StartNextGroupRolloutGroupSuccessAction.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rollout/condition/StartNextGroupRolloutGroupSuccessAction.java index d3ad783b1..420787582 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rollout/condition/StartNextGroupRolloutGroupSuccessAction.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/rollout/condition/StartNextGroupRolloutGroupSuccessAction.java @@ -56,8 +56,8 @@ public class StartNextGroupRolloutGroupSuccessAction implements RolloutGroupActi // retrieve all actions according to the parent group of the finished // rolloutGroup, so retrieve all child-group actions which need to be // started. - final long countOfStartedActions = deploymentManagement - .startScheduledActionsByRolloutGroupParent(rollout.getId(), rolloutGroup.getId()); + final long countOfStartedActions = deploymentManagement.startScheduledActionsByRolloutGroupParent( + rollout.getId(), rollout.getDistributionSet().getId(), rolloutGroup.getId()); logger.debug("{} Next actions started for rollout {} and parent group {}", countOfStartedActions, rollout, rolloutGroup); if (countOfStartedActions > 0) { diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEventTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEventTest.java index df8828ab5..46a776f41 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEventTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantAwareEventTest.java @@ -10,6 +10,10 @@ package org.eclipse.hawkbit.repository.event.remote; import static org.assertj.core.api.Assertions.assertThat; +import java.util.AbstractMap.SimpleImmutableEntry; +import java.util.Arrays; +import java.util.Map.Entry; + import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionType; @@ -50,8 +54,8 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest { generateAction.setStatus(Status.RUNNING); final Action action = actionRepository.save(generateAction); - final TargetAssignDistributionSetEvent assignmentEvent = new TargetAssignDistributionSetEvent(action, - serviceMatcher.getServiceId()); + final TargetAssignDistributionSetEvent assignmentEvent = new TargetAssignDistributionSetEvent( + action.getTenant(), dsA.getId(), Arrays.asList(action), serviceMatcher.getServiceId()); TargetAssignDistributionSetEvent underTest = (TargetAssignDistributionSetEvent) createProtoStuffEvent( assignmentEvent); @@ -63,12 +67,11 @@ public class RemoteTenantAwareEventTest extends AbstractRemoteEventTest { private void assertTargetAssignDistributionSetEvent(final Action action, final TargetAssignDistributionSetEvent underTest) { - assertThat(underTest.getActionId()).isNotNull(); - assertThat(underTest.getControllerId()).isNotNull(); - assertThat(underTest.getDistributionSetId()).isNotNull(); - assertThat(underTest.getActionId()).isEqualTo(action.getId()); - assertThat(underTest.getControllerId()).isEqualTo(action.getTarget().getControllerId()); + final Entry entry = new SimpleImmutableEntry(action.getTarget().getControllerId(), + action.getId()); + + assertThat(underTest.getActions()).containsExactly(entry); assertThat(underTest.getDistributionSetId()).isEqualTo(action.getDistributionSet().getId()); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DeploymentManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DeploymentManagementTest.java index 3a7f21016..21de98ad7 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DeploymentManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/DeploymentManagementTest.java @@ -237,7 +237,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Description("Test verifies that an assignment with automatic cancelation works correctly even if the update is split into multiple partitions on the database.") @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10), @Expect(type = TargetUpdatedEvent.class, count = 2 * (Constants.MAX_ENTRIES_IN_STATEMENT + 10)), - @Expect(type = TargetAssignDistributionSetEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10), + @Expect(type = TargetAssignDistributionSetEvent.class, count = 1), @Expect(type = ActionCreatedEvent.class, count = 2 * (Constants.MAX_ENTRIES_IN_STATEMENT + 10)), @Expect(type = CancelTargetAssignmentEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10), @Expect(type = ActionUpdatedEvent.class, count = Constants.MAX_ENTRIES_IN_STATEMENT + 10), @@ -437,7 +437,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Expect(type = TargetUpdatedEvent.class, count = 20), @Expect(type = ActionCreatedEvent.class, count = 20), @Expect(type = DistributionSetCreatedEvent.class, count = 2), @Expect(type = SoftwareModuleCreatedEvent.class, count = 6), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 10) }) + @Expect(type = TargetAssignDistributionSetEvent.class, count = 1) }) public void assignedDistributionSet() { final List controllerIds = testdataFactory.createTargets(10).stream().map(Target::getControllerId) .collect(Collectors.toList()); @@ -468,7 +468,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Expect(type = ActionUpdatedEvent.class, count = 10), @Expect(type = DistributionSetCreatedEvent.class, count = 2), @Expect(type = SoftwareModuleCreatedEvent.class, count = 6), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 20) }) + @Expect(type = TargetAssignDistributionSetEvent.class, count = 2) }) public void assigneDistributionSetAndAutoCloseActiveActions() { tenantConfigurationManagement .addOrUpdateConfiguration(TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED, true); @@ -517,7 +517,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Test @Description("Simple deployment or distribution set to target assignment test.") public void assignDistributionSet2Targets() throws InterruptedException { - eventHandlerStub.setExpectedNumberOfEvents(20); + eventHandlerStub.setExpectedNumberOfEvents(1); final String myCtrlIDPref = "myCtrlID"; final Iterable savedNakedTargets = testdataFactory.createTargets(10, myCtrlIDPref, "first description"); @@ -595,7 +595,7 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest { final DistributionSet nowComplete = distributionSetManagement.assignSoftwareModules(incomplete.getId(), Sets.newHashSet(os.getId())); - eventHandlerStub.setExpectedNumberOfEvents(10); + eventHandlerStub.setExpectedNumberOfEvents(1); assertThat(assignDistributionSet(nowComplete, targets).getAssigned()).as("assign ds doesn't work") .isEqualTo(10); @@ -606,6 +606,14 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest { @Test @Description("Multiple deployments or distribution set to target assignment test. Expected behaviour is that a new deployment " + "overides unfinished old one which are canceled as part of the operation.") + @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 5 + 4), + @Expect(type = TargetUpdatedEvent.class, count = 3 * 4), + @Expect(type = ActionCreatedEvent.class, count = 3 * 4), + @Expect(type = ActionUpdatedEvent.class, count = 4 * 2), + @Expect(type = CancelTargetAssignmentEvent.class, count = 4 * 2), + @Expect(type = DistributionSetCreatedEvent.class, count = 3), + @Expect(type = SoftwareModuleCreatedEvent.class, count = 9), + @Expect(type = TargetAssignDistributionSetEvent.class, count = 1) }) public void mutipleDeployments() throws InterruptedException { final String undeployedTargetPrefix = "undep-T"; final int noOfUndeployedTargets = 5; @@ -615,8 +623,8 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest { final int noOfDistributionSets = 3; - // Each of the four targets get one assignment (4 * 1 = 4) - final int expectedNumberOfEventsForAssignment = 4; + // One assigment per DS + final int expectedNumberOfEventsForAssignment = 1; eventHandlerStub.setExpectedNumberOfEvents(expectedNumberOfEventsForAssignment); // Each of the four targets get two more assignment the which are @@ -641,10 +649,10 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest { // only records retrieved from the DB can be evaluated to be sure that // all fields are // populated; - final Iterable allFoundTargets = targetRepository.findAll(); + final List allFoundTargets = targetRepository.findAll(); - final Iterable deployedTargetsFromDB = targetRepository.findAll(deployedTargetIDs); - final Iterable undeployedTargetsFromDB = targetRepository.findAll(undeployedTargetIDs); + final List deployedTargetsFromDB = targetRepository.findAll(deployedTargetIDs); + final List undeployedTargetsFromDB = targetRepository.findAll(undeployedTargetIDs); // test that number of Targets assertThat(allFoundTargets.spliterator().getExactSizeIfKnown()).as("number of target is wrong") @@ -1029,33 +1037,23 @@ public class DeploymentManagementTest extends AbstractJpaIntegrationTest { deployedTargets = assignDistributionSet(ds, deployedTargets).getAssignedEntity(); } - final DeploymentResult deploymentResult = new DeploymentResult(deployedTargets, nakedTargets, dsList, - deployedTargetPrefix, undeployedTargetPrefix, distributionSetPrefix); - return deploymentResult; + return new DeploymentResult(deployedTargets, nakedTargets, dsList, deployedTargetPrefix, undeployedTargetPrefix, + distributionSetPrefix); } private void assertTargetAssignDistributionSetEvents(final List targets, final DistributionSet ds, final List events) { - assertThat(events).isNotEmpty(); - for (final Target myt : targets) { - boolean found = false; - for (final TargetAssignDistributionSetEvent event : events) { - if (event.getControllerId().equals(myt.getControllerId())) { - found = true; - final List activeActionsByTarget = deploymentManagement - .findActiveActionsByTarget(PAGE, myt.getControllerId()).getContent(); - assertThat(activeActionsByTarget).as("size of active actions for target is wrong").isNotEmpty(); - assertThat(event.getActionId()).as("Action id in database and event do not match") - .isEqualTo(activeActionsByTarget.get(0).getId()); + assertThat(events).hasSize(1); + final TargetAssignDistributionSetEvent event = events.get(0); + assertThat(event).isNotNull(); + assertThat(event.getDistributionSetId()).isEqualTo(ds.getId()); - assertThat(distributionSetManagement.get(event.getDistributionSetId()).get().getModules()) - .as("softwaremodule size is not correct") - .containsOnly(ds.getModules().toArray(new SoftwareModule[ds.getModules().size()])); - } - } - assertThat(found).as("No event found for controller " + myt.getControllerId()).isTrue(); - } + assertThat(event.getActions()).isEqualTo(targets.stream() + .map(target -> deploymentManagement.findActiveActionsByTarget(PAGE, target.getControllerId()) + .getContent()) + .flatMap(List::stream) + .collect(Collectors.toMap(action -> action.getTarget().getControllerId(), Action::getId))); } private class DeploymentResult { 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 18032ddb9..4f126e1c9 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 @@ -164,8 +164,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { amountOtherTargets, amountGroups, successCondition, errorCondition); // verify the split of the target and targetGroup - final Page rolloutGroups = rolloutGroupManagement - .findByRollout(PAGE, createdRollout.getId()); + final Page rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId()); // we have total of #amountTargetsForRollout in rollouts splitted in // group size #groupSize assertThat(rolloutGroups).hasSize(amountGroups); @@ -183,8 +182,9 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { successCondition, errorCondition); // verify first group is running - final RolloutGroup firstGroup = rolloutGroupManagement.findByRollout(new OffsetBasedPageRequest(0, 1, new Sort(Direction.ASC, "id")), - createdRollout.getId()).getContent().get(0); + final RolloutGroup firstGroup = rolloutGroupManagement + .findByRollout(new OffsetBasedPageRequest(0, 1, new Sort(Direction.ASC, "id")), createdRollout.getId()) + .getContent().get(0); assertThat(firstGroup.getStatus()).isEqualTo(RolloutGroupStatus.RUNNING); // verify other groups are scheduled @@ -224,15 +224,17 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { rolloutManagement.handleRollouts(); // verify that now the first and the second group are in running state - final List runningRolloutGroups = rolloutGroupManagement.findByRollout( - new OffsetBasedPageRequest(0, 2, new Sort(Direction.ASC, "id")), createdRollout.getId()).getContent(); + final List runningRolloutGroups = rolloutGroupManagement + .findByRollout(new OffsetBasedPageRequest(0, 2, new Sort(Direction.ASC, "id")), createdRollout.getId()) + .getContent(); runningRolloutGroups.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.RUNNING) .as("group should be in running state because it should be started but it is in " + group.getStatus() + " state")); // verify that the other groups are still in schedule state - final List scheduledRolloutGroups = rolloutGroupManagement.findByRollout( - new OffsetBasedPageRequest(2, 10, new Sort(Direction.ASC, "id")), createdRollout.getId()).getContent(); + final List scheduledRolloutGroups = rolloutGroupManagement + .findByRollout(new OffsetBasedPageRequest(2, 10, new Sort(Direction.ASC, "id")), createdRollout.getId()) + .getContent(); scheduledRolloutGroups.forEach(group -> assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.SCHEDULED) .as("group should be in scheduled state because it should not be started but it is in " + group.getStatus() + " state")); @@ -293,8 +295,9 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { @Step("Check the status of the rollout groups, second group should be in running status") private void checkSecondGroupStatusIsRunning(final Rollout createdRollout) { rolloutManagement.handleRollouts(); - final List runningRolloutGroups = rolloutGroupManagement.findByRollout( - new OffsetBasedPageRequest(0, 10, new Sort(Direction.ASC, "id")), createdRollout.getId()).getContent(); + final List runningRolloutGroups = rolloutGroupManagement + .findByRollout(new OffsetBasedPageRequest(0, 10, new Sort(Direction.ASC, "id")), createdRollout.getId()) + .getContent(); assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED); assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.RUNNING); assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.SCHEDULED); @@ -330,8 +333,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { assertThat(runningRolloutGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED); assertThat(runningRolloutGroups.get(1).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED); assertThat(runningRolloutGroups.get(2).getStatus()).isEqualTo(RolloutGroupStatus.FINISHED); - assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus()) - .isEqualTo(RolloutStatus.FINISHED); + assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus()).isEqualTo(RolloutStatus.FINISHED); } @@ -370,8 +372,9 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { assertThat(rollout.getStatus()).isEqualTo(RolloutStatus.PAUSED); // the first rollout group should be in error state - final List errorGroup = rolloutGroupManagement.findByRollout( - new OffsetBasedPageRequest(0, 1, new Sort(Direction.ASC, "id")), createdRollout.getId()).getContent(); + final List errorGroup = rolloutGroupManagement + .findByRollout(new OffsetBasedPageRequest(0, 1, new Sort(Direction.ASC, "id")), createdRollout.getId()) + .getContent(); assertThat(errorGroup).hasSize(1); assertThat(errorGroup.get(0).getStatus()).isEqualTo(RolloutGroupStatus.ERROR); @@ -418,15 +421,15 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { rolloutManagement.resumeRollout(createdRollout.getId()); // the rollout should be running again - assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus()) - .isEqualTo(RolloutStatus.RUNNING); + assertThat(rolloutManagement.get(createdRollout.getId()).get().getStatus()).isEqualTo(RolloutStatus.RUNNING); // checking rollouts again rolloutManagement.handleRollouts(); // next group should be running again after resuming the rollout - final List resumedGroups = rolloutGroupManagement.findByRollout( - new OffsetBasedPageRequest(1, 1, new Sort(Direction.ASC, "id")), createdRollout.getId()).getContent(); + final List resumedGroups = rolloutGroupManagement + .findByRollout(new OffsetBasedPageRequest(1, 1, new Sort(Direction.ASC, "id")), createdRollout.getId()) + .getContent(); assertThat(resumedGroups).hasSize(1); assertThat(resumedGroups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.RUNNING); } @@ -590,8 +593,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { // round(5/2)=3 targets SCHEDULED (Group 3) // round(2/1)=2 targets SCHEDULED (Group 4) createdRollout = rolloutManagement.get(createdRollout.getId()).get(); - final List rolloutGroups = rolloutGroupManagement - .findByRollout(PAGE, createdRollout.getId()).getContent(); + final List rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId()) + .getContent(); Map expectedTargetCountStatus = createInitStatusMap(); expectedTargetCountStatus.put(TotalTargetCountStatus.Status.FINISHED, 2L); @@ -630,9 +633,10 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { assertThat(runningActions.size()).isEqualTo(5); // 5 targets are in the group and the DS has been assigned - final List rolloutGroups = rolloutGroupManagement - .findByRollout(PAGE, createdRollout.getId()).getContent(); - final Page targets = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, rolloutGroups.get(0).getId()); + final List rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, createdRollout.getId()) + .getContent(); + final Page targets = rolloutGroupManagement.findTargetsOfRolloutGroup(PAGE, + rolloutGroups.get(0).getId()); final List targetList = targets.getContent(); assertThat(targetList.size()).isEqualTo(5); @@ -769,8 +773,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { changeStatusForRunningActions(rolloutOne, Status.FINISHED, 3); rolloutManagement.handleRollouts(); // verify: 40% error but 60% finished -> should move to next group - final List rolloutGruops = rolloutGroupManagement - .findByRollout(PAGE, rolloutOne.getId()).getContent(); + final List rolloutGruops = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId()) + .getContent(); final Map expectedTargetCountStatus = createInitStatusMap(); expectedTargetCountStatus.put(TotalTargetCountStatus.Status.RUNNING, 5L); validateRolloutGroupActionStatus(rolloutGruops.get(1), expectedTargetCountStatus); @@ -795,8 +799,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { rolloutManagement.handleRollouts(); // verify: 40% error and 60% finished -> should not move to next group // because successCondition 80% - final List rolloutGruops = rolloutGroupManagement - .findByRollout(PAGE, rolloutOne.getId()).getContent(); + final List rolloutGruops = rolloutGroupManagement.findByRollout(PAGE, rolloutOne.getId()) + .getContent(); final Map expectedTargetCountStatus = createInitStatusMap(); expectedTargetCountStatus.put(TotalTargetCountStatus.Status.SCHEDULED, 5L); validateRolloutGroupActionStatus(rolloutGruops.get(1), expectedTargetCountStatus); @@ -868,8 +872,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { changeStatusForAllRunningActions(rolloutD, Status.FINISHED); rolloutManagement.handleRollouts(); - final Page rolloutPage = rolloutManagement.findAllWithDetailedStatus( - new OffsetBasedPageRequest(0, 100, new Sort(Direction.ASC, "name")), false); + final Page rolloutPage = rolloutManagement + .findAllWithDetailedStatus(new OffsetBasedPageRequest(0, 100, new Sort(Direction.ASC, "name")), false); final List rolloutList = rolloutPage.getContent(); // validate rolloutA -> 6 running and 6 ready @@ -1003,8 +1007,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { myRollout = rolloutManagement.get(myRollout.getId()).get(); float percent = rolloutGroupManagement - .getWithDetailedStatus(rolloutGroupManagement - .findByRollout(PAGE, myRollout.getId()).getContent().get(0).getId()) + .getWithDetailedStatus( + rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent().get(0).getId()) .get().getTotalTargetCountStatus().getFinishedPercent(); assertThat(percent).isEqualTo(40); @@ -1012,8 +1016,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { rolloutManagement.handleRollouts(); percent = rolloutGroupManagement - .getWithDetailedStatus(rolloutGroupManagement - .findByRollout(PAGE, myRollout.getId()).getContent().get(0).getId()) + .getWithDetailedStatus( + rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent().get(0).getId()) .get().getTotalTargetCountStatus().getFinishedPercent(); assertThat(percent).isEqualTo(100); @@ -1022,8 +1026,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { rolloutManagement.handleRollouts(); percent = rolloutGroupManagement - .getWithDetailedStatus(rolloutGroupManagement - .findByRollout(PAGE, myRollout.getId()).getContent().get(1).getId()) + .getWithDetailedStatus( + rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent().get(1).getId()) .get().getTotalTargetCountStatus().getFinishedPercent(); assertThat(percent).isEqualTo(80); } @@ -1054,25 +1058,25 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { "Target belongs into rollout"); myRollout = rolloutManagement.get(myRollout.getId()).get(); - final List rolloutGroups = rolloutGroupManagement - .findByRollout(PAGE, myRollout.getId()).getContent(); + final List rolloutGroups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()) + .getContent(); - Page targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100), - rolloutGroups.get(0).getId(), rsqlParam); + Page targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql( + new OffsetBasedPageRequest(0, 100), rolloutGroups.get(0).getId(), rsqlParam); final List targetlistGroup1 = targetPage.getContent(); assertThat(targetlistGroup1.size()).isEqualTo(5); assertThat(targetlistGroup1.stream().map(Target::getControllerId).collect(Collectors.toList())) .are(targetBelongsInRollout); - targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100), rolloutGroups.get(1).getId(), - rsqlParam); + targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100), + rolloutGroups.get(1).getId(), rsqlParam); final List targetlistGroup2 = targetPage.getContent(); assertThat(targetlistGroup2.size()).isEqualTo(5); assertThat(targetlistGroup2.stream().map(Target::getControllerId).collect(Collectors.toList())) .are(targetBelongsInRollout); - targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100), rolloutGroups.get(2).getId(), - rsqlParam); + targetPage = rolloutGroupManagement.findTargetsOfRolloutGroupByRsql(new OffsetBasedPageRequest(0, 100), + rolloutGroups.get(2).getId(), rsqlParam); final List targetlistGroup3 = targetPage.getContent(); assertThat(targetlistGroup3.size()).isEqualTo(5); assertThat(targetlistGroup3.stream().map(Target::getControllerId).collect(Collectors.toList())) @@ -1135,8 +1139,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY); - final List groups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()) - .getContent(); + final List groups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent(); assertThat(groups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.READY); assertThat(groups.get(0).getTotalTargets()).isEqualTo(1); @@ -1228,8 +1231,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY); // schedule rollout auto start into the future - rolloutManagement.update( - entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis() + 60000)); + rolloutManagement + .update(entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis() + 60000)); rolloutManagement.handleRollouts(); // rollout should not have been started @@ -1237,8 +1240,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY); // schedule to now - rolloutManagement - .update(entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis())); + rolloutManagement.update(entityFactory.rollout().update(myRollout.getId()).startAt(System.currentTimeMillis())); rolloutManagement.handleRollouts(); myRollout = rolloutManagement.get(myRollout.getId()).get(); @@ -1292,8 +1294,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { myRollout = rolloutManagement.get(myRollout.getId()).get(); assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.CREATING); - for (final RolloutGroup group : rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()) - .getContent()) { + for (final RolloutGroup group : rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent()) { assertThat(group.getStatus()).isEqualTo(RolloutGroupStatus.CREATING); } @@ -1308,8 +1309,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { assertThat(myRollout.getStatus()).isEqualTo(RolloutStatus.READY); assertThat(myRollout.getTotalTargets()).isEqualTo(amountTargetsInGroup1and2 + amountTargetsInGroup1); - final List groups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()) - .getContent(); + final List groups = rolloutGroupManagement.findByRollout(PAGE, myRollout.getId()).getContent(); ; assertThat(groups.get(0).getStatus()).isEqualTo(RolloutGroupStatus.READY); assertThat(groups.get(0).getTotalTargets()).isEqualTo(amountTargetsInGroup1); @@ -1446,7 +1446,7 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { @Expect(type = RolloutUpdatedEvent.class, count = 6), @Expect(type = DistributionSetCreatedEvent.class, count = 1), @Expect(type = TargetCreatedEvent.class, count = 25), @Expect(type = TargetUpdatedEvent.class, count = 2), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 2), + @Expect(type = TargetAssignDistributionSetEvent.class, count = 1), @Expect(type = RolloutGroupCreatedEvent.class, count = 5), @Expect(type = RolloutGroupDeletedEvent.class, count = 5), @Expect(type = ActionCreatedEvent.class, count = 10), @Expect(type = ActionUpdatedEvent.class, count = 2), @@ -1485,8 +1485,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { assertThat(rolloutManagement.findAll(PAGE, true).getContent()).hasSize(1); assertThat(rolloutManagement.findAll(PAGE, false).getContent()).hasSize(0); - assertThat(rolloutGroupManagement.findByRolloutWithDetailedStatus(PAGE, createdRollout.getId()) - .getContent()).hasSize(amountGroups); + assertThat(rolloutGroupManagement.findByRolloutWithDetailedStatus(PAGE, createdRollout.getId()).getContent()) + .hasSize(amountGroups); // verify that all scheduled actions are deleted assertThat(actionRepository.findByRolloutIdAndStatus(PAGE, deletedRollout.getId(), Status.SCHEDULED) @@ -1516,8 +1516,8 @@ public class RolloutManagementTest extends AbstractJpaIntegrationTest { private void validateRolloutGroupActionStatus(final RolloutGroup rolloutGroup, final Map expectedTargetCountStatus) { - final RolloutGroup rolloutGroupWithDetail = rolloutGroupManagement - .getWithDetailedStatus(rolloutGroup.getId()).get(); + final RolloutGroup rolloutGroupWithDetail = rolloutGroupManagement.getWithDetailedStatus(rolloutGroup.getId()) + .get(); validateStatus(rolloutGroupWithDetail.getTotalTargetCountStatus(), expectedTargetCountStatus); } diff --git a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java index 6fabea24d..08406a89c 100644 --- a/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java +++ b/hawkbit-repository/hawkbit-repository-test/src/main/java/org/eclipse/hawkbit/repository/test/matcher/EventVerifier.java @@ -132,8 +132,7 @@ public class EventVerifier extends AbstractTestExecutionListener { } if (event instanceof TargetAssignDistributionSetEvent) { - assertThat(((TargetAssignDistributionSetEvent) event).getActionId()).isNotNull(); - assertThat(((TargetAssignDistributionSetEvent) event).getControllerId()).isNotEmpty(); + assertThat(((TargetAssignDistributionSetEvent) event).getActions()).isNotEmpty(); assertThat(((TargetAssignDistributionSetEvent) event).getDistributionSetId()).isNotNull(); } diff --git a/hawkbit-security-integration/pom.xml b/hawkbit-security-integration/pom.xml index fe931ac88..11cacf953 100644 --- a/hawkbit-security-integration/pom.xml +++ b/hawkbit-security-integration/pom.xml @@ -26,11 +26,6 @@ hawkbit-repository-api ${project.version} - - org.eclipse.hawkbit - hawkbit-dmf-api - ${project.version} - org.springframework.security spring-security-web diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java index 79b77142f..66a3b814c 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/AbstractControllerAuthenticationFilter.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.security; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; import org.slf4j.Logger; diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java index 9fab33fd1..7a9c7b5ae 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticateSecurityTokenFilter.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.security; import java.util.Optional; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; import org.eclipse.hawkbit.repository.ControllerManagement; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.Target; diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownload.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownload.java index 4d8f9490a..a9564810f 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownload.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousDownload.java @@ -11,7 +11,6 @@ package org.eclipse.hawkbit.security; import java.util.Arrays; import java.util.Collection; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousFilter.java index 270229f1b..8f21a0ba5 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedAnonymousFilter.java @@ -8,8 +8,6 @@ */ package org.eclipse.hawkbit.security; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; - /** * An anonymous controller filter which is only enabled in case of anonymous * access is granted. This should only be for development purposes. diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java index 8b386e7f7..2b669ef39 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedGatewaySecurityTokenFilter.java @@ -8,7 +8,6 @@ */ package org.eclipse.hawkbit.security; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java index 6a06d9589..86f4b34b0 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilter.java @@ -12,7 +12,6 @@ import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.tenancy.TenantAware; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; diff --git a/hawkbit-dmf/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DmfTenantSecurityToken.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/DmfTenantSecurityToken.java similarity index 99% rename from hawkbit-dmf/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DmfTenantSecurityToken.java rename to hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/DmfTenantSecurityToken.java index 2f7b26ea5..7074aa4d4 100644 --- a/hawkbit-dmf/hawkbit-dmf-api/src/main/java/org/eclipse/hawkbit/dmf/json/model/DmfTenantSecurityToken.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/DmfTenantSecurityToken.java @@ -6,7 +6,7 @@ * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ -package org.eclipse.hawkbit.dmf.json.model; +package org.eclipse.hawkbit.security; import java.util.Collections; import java.util.Map; diff --git a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthentificationFilter.java b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthentificationFilter.java index 272daa011..17e70e069 100644 --- a/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthentificationFilter.java +++ b/hawkbit-security-integration/src/main/java/org/eclipse/hawkbit/security/PreAuthentificationFilter.java @@ -11,7 +11,6 @@ package org.eclipse.hawkbit.security; import java.util.Collection; import java.util.Collections; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.GrantedAuthority; diff --git a/hawkbit-security-integration/src/test/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilterTest.java b/hawkbit-security-integration/src/test/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilterTest.java index 8225cb970..ab521ae89 100644 --- a/hawkbit-security-integration/src/test/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilterTest.java +++ b/hawkbit-security-integration/src/test/java/org/eclipse/hawkbit/security/ControllerPreAuthenticatedSecurityHeaderFilterTest.java @@ -15,10 +15,9 @@ import static org.mockito.Mockito.when; import java.util.Collection; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken; -import org.eclipse.hawkbit.dmf.json.model.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.repository.TenantConfigurationManagement; import org.eclipse.hawkbit.repository.model.TenantConfigurationValue; +import org.eclipse.hawkbit.security.DmfTenantSecurityToken.FileResource; import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey; import org.junit.Before; import org.junit.Test; diff --git a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java index 417a2d154..d2f2554d7 100644 --- a/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java +++ b/hawkbit-ui/src/main/java/org/eclipse/hawkbit/ui/distributions/DistributionsView.java @@ -276,7 +276,7 @@ public class DistributionsView extends AbstractNotificationView implements Brows @Override protected Map, RefreshableContainer> getSupportedPushEvents() { - final Map, RefreshableContainer> supportedEvents = Maps.newHashMapWithExpectedSize(2); + final Map, RefreshableContainer> supportedEvents = Maps.newHashMapWithExpectedSize(4); supportedEvents.put(DistributionSetCreatedEventContainer.class, distributionTableLayout.getTable()); supportedEvents.put(DistributionSetDeletedEventContainer.class, distributionTableLayout.getTable()); diff --git a/pom.xml b/pom.xml index 738e4e1b7..763714c40 100644 --- a/pom.xml +++ b/pom.xml @@ -164,7 +164,7 @@ 20141113 2.1.0 1.7.0 - 1.5.3 + 1.5.6