diff --git a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java index 7ceba62e8e..8be19c64fe 100644 --- a/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java +++ b/hawkbit-core/src/main/java/org/eclipse/hawkbit/exception/SpServerError.java @@ -155,7 +155,7 @@ public enum SpServerError { SP_CONFIGURATION_VALUE_CHANGE_NOT_ALLOWED( "hawkbit.server.error.repo.tenantConfigurationValueChangeNotAllowed", "The requested tenant configuration value modification is not allowed."), - SP_MULTIASSIGNMENT_NOT_ENABLED( + SP_MULTIASSIGNMENT( "hawkbit.server.error.multiAssignmentNotEnabled", "The requested operation requires multi assignments to be enabled."), SP_NO_WEIGHT_PROVIDED_IN_MULTIASSIGNMENT_MODE( diff --git a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java index ab21e1a383..56ec4cdb96 100644 --- a/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java +++ b/hawkbit-ddi/hawkbit-ddi-resource/src/test/java/org/eclipse/hawkbit/ddi/rest/resource/DdiRootControllerTest.java @@ -687,23 +687,6 @@ void downloadAndUpdateStatusDuringMaintenanceWindow() throws Exception { .andExpect(jsonPath("$.deployment.maintenanceWindow", equalTo("available"))); } - /** - * Assign multiple DS in multi-assignment mode. The earliest active Action is exposed to the controller. - */ - @Test - void earliestActionIsExposedToControllerInMultiAssignMode() throws Exception { - enableMultiAssignments(); - final Target target = testdataFactory.createTarget(); - final DistributionSet ds1 = testdataFactory.createDistributionSet(UUID.randomUUID().toString()); - final DistributionSet ds2 = testdataFactory.createDistributionSet(UUID.randomUUID().toString()); - final Action action1 = getFirstAssignedAction(assignDistributionSet(ds1.getId(), target.getControllerId(), 56)); - final Long action2Id = getFirstAssignedActionId(assignDistributionSet(ds2.getId(), target.getControllerId(), 34)); - - assertDeploymentActionIsExposedToTarget(target.getControllerId(), action1.getId()); - sendDeploymentActionFeedback(target, action1, "closed", "success"); - assertDeploymentActionIsExposedToTarget(target.getControllerId(), action2Id); - } - /** * The system should not create a new target because of a too long controller id. */ @@ -759,16 +742,6 @@ private ResultActions sendDeploymentActionFeedback(final Target target, final Ac return sendDeploymentActionFeedback(target, action, execution, finished, null); } - private void assertDeploymentActionIsExposedToTarget(final String controllerId, final long expectedActionId) throws Exception { - final String expectedDeploymentBaseLink = String.format( - "/%s/controller/v1/%s/deploymentBase/%d", - AccessContext.tenant(), controllerId, expectedActionId); - mvc.perform(get(CONTROLLER_BASE, AccessContext.tenant(), controllerId).accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("$._links.deploymentBase.href", containsString(expectedDeploymentBaseLink))); - } - private void withPollingTime(final String pollingTime, final Callable runnable) throws Exception { getAs(withUser("tenantadmin", TENANT_CONFIGURATION), () -> { 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 e64f714681..dd37afc511 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 @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.amqp; import static org.eclipse.hawkbit.context.AccessContext.asSystem; -import static org.eclipse.hawkbit.repository.RepositoryConstants.MAX_ACTION_COUNT; import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.BATCH_ASSIGNMENTS_ENABLED; import java.net.URI; @@ -43,7 +42,6 @@ import org.eclipse.hawkbit.dmf.json.model.DmfConfirmRequest; import org.eclipse.hawkbit.dmf.json.model.DmfDownloadAndUpdateRequest; import org.eclipse.hawkbit.dmf.json.model.DmfMetadata; -import org.eclipse.hawkbit.dmf.json.model.DmfMultiActionRequest; import org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule; import org.eclipse.hawkbit.dmf.json.model.DmfTarget; import org.eclipse.hawkbit.repository.DeploymentManagement; @@ -53,14 +51,10 @@ import org.eclipse.hawkbit.repository.SystemManagement; import org.eclipse.hawkbit.repository.TargetManagement; import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.service.CancelTargetAssignmentServiceEvent; -import org.eclipse.hawkbit.repository.event.remote.service.MultiActionAssignServiceEvent; -import org.eclipse.hawkbit.repository.event.remote.service.MultiActionCancelServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistributionSetServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetAttributesRequestedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetDeletedServiceEvent; @@ -142,30 +136,6 @@ protected void targetAssignDistributionSet(final TargetAssignDistributionSetServ } } - /** - * Listener for Multi-Action events. - * - * @param multiActionAssignServiceEvent the Multi-Action event to be processed - */ - @EventListener(classes = MultiActionAssignServiceEvent.class) - protected void onMultiActionAssign(final MultiActionAssignServiceEvent multiActionAssignServiceEvent) { - final MultiActionAssignEvent multiActionAssignEvent = multiActionAssignServiceEvent.getRemoteEvent(); - log.debug("MultiActionAssignEvent received for {}", multiActionAssignEvent.getControllerIds()); - sendMultiActionRequestMessages(multiActionAssignEvent.getControllerIds()); - } - - /** - * Listener for Multi-Action events. - * - * @param multiActionCancelServiceEvent the Multi-Action event to be processed - */ - @EventListener(classes = MultiActionCancelServiceEvent.class) - protected void onMultiActionCancel(final MultiActionCancelServiceEvent multiActionCancelServiceEvent) { - final MultiActionCancelEvent multiActionCancelEvent = multiActionCancelServiceEvent.getRemoteEvent(); - log.debug("MultiActionCancelEvent received for {}", multiActionCancelEvent.getControllerIds()); - sendMultiActionRequestMessages(multiActionCancelEvent.getControllerIds()); - } - protected void sendUpdateMessageToTarget( final ActionProperties actionsProps, final Target target, final Map> softwareModules) { @@ -247,39 +217,6 @@ protected DmfConfirmRequest createConfirmRequest( return new DmfConfirmRequest(actionId, asSystem(target::getSecurityToken), convertToAmqpSoftwareModules(target, softwareModules)); } - void sendMultiActionRequestToTarget( - final Target target, final List actions, - final Function> getSoftwareModuleMetaData) { - final URI targetAddress = IpUtil.addressToUri(target.getAddress()); - if (!IpUtil.isAmqpUri(targetAddress) || CollectionUtils.isEmpty(actions)) { - return; - } - - final DmfMultiActionRequest multiActionRequest = new DmfMultiActionRequest( - actions.stream() - .map(action -> { - final DmfActionRequest actionRequest = createDmfActionRequest( - target, action, - action.getDistributionSet().getModules().stream() - .collect(Collectors.toMap(Function.identity(), module -> { - final Map softwareModuleMetadata = getSoftwareModuleMetaData.apply(module); - return softwareModuleMetadata == null ? Collections.emptyMap() : softwareModuleMetadata; - }))); - final int weight = getWeightConsideringDefault(action); - return new DmfMultiActionRequest.DmfMultiActionElement(getEventTypeForAction(action), actionRequest, weight); - }) - .toList()); - - final Message message = getMessageConverter().toMessage( - multiActionRequest, - createConnectorMessagePropertiesEvent(target.getTenant(), target.getControllerId(), EventTopic.MULTI_ACTION)); - amqpSenderService.sendMessage(message, targetAddress); - } - - private int getWeightConsideringDefault(final Action action) { - return action.getWeight().orElse(repositoryProperties.getActionWeightIfAbsent()); - } - /** * Method to get the type of event depending on whether the action is a DOWNLOAD_ONLY action or if it has a valid maintenance window * available or not based on defined maintenance schedule. In case of no maintenance schedule or if there is a valid window available, @@ -297,19 +234,6 @@ private static EventTopic getEventTypeForTarget(final ActionProperties action) { : EventTopic.DOWNLOAD_AND_INSTALL; } - /** - * Determines the {@link EventTopic} for the given {@link Action}, depending on its action type. - * - * @param action to obtain the corresponding {@link EventTopic} for - * @return the {@link EventTopic} for this action - */ - private static EventTopic getEventTypeForAction(final Action action) { - if (action.isCancelingOrCanceled()) { - return EventTopic.CANCEL_DOWNLOAD; - } - return getEventTypeForTarget(new ActionProperties(action)); - } - private static List partitionedParallelExecution( final Collection controllerIds, final Function, List> loadingFunction) { // Ensure not exceeding the max value of MAX_PROCESSING_SIZE @@ -412,40 +336,6 @@ private void sendUpdateMessageToTargets( } } - private void sendMultiActionRequestMessages(final List controllerIds) { - final Map> controllerIdToActions = controllerIds.stream() - .collect(Collectors.toMap( - Function.identity(), - controllerId -> deploymentManagement.findActiveActionsWithHighestWeight(controllerId, MAX_ACTION_COUNT))); - - // gets all software modules for all action at once - final Set allSmIds = controllerIdToActions.values().stream() - .flatMap(actions -> actions.stream() - .map(Action::getDistributionSet) - .flatMap(ds -> ds.getModules().stream()) - .map(SoftwareModule::getId)) - .collect(Collectors.toSet()); - final Map> getSoftwareModuleMetadata = - allSmIds.isEmpty() - ? Collections.emptyMap() - : softwareModuleManagement.findMetaDataBySoftwareModuleIdsAndTargetVisible(allSmIds); - - targetManagement.findByControllerId(controllerIds).forEach(target -> - sendMultiActionRequestToTarget( - target, controllerIdToActions.get(target.getControllerId()), module -> getSoftwareModuleMetadata.get(module.getId()))); - } - - private DmfActionRequest createDmfActionRequest( - final Target target, final Action action, - final Map> softwareModules) { - if (action.isCancelingOrCanceled()) { - return new DmfActionRequest(action.getId()); - } else if (action.isWaitingConfirmation()) { - return createConfirmRequest(target, action.getId(), softwareModules); - } - return createDownloadAndUpdateRequest(target, action.getId(), softwareModules); - } - private void sendSingleUpdateMessage( final ActionProperties action, final Target target, final Map> modules) { final String tenant = action.getTenant(); diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java index af15d676e1..46c0a1cd3d 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/main/java/org/eclipse/hawkbit/amqp/AmqpMessageHandlerService.java @@ -9,15 +9,12 @@ */ package org.eclipse.hawkbit.amqp; -import static org.eclipse.hawkbit.repository.RepositoryConstants.MAX_ACTION_COUNT; - import java.net.URI; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Set; import java.util.UUID; import java.util.function.Function; import java.util.stream.Collectors; @@ -42,7 +39,6 @@ import org.eclipse.hawkbit.repository.UpdateMode; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.EntityAlreadyExistsException; -import org.eclipse.hawkbit.repository.helper.TenantConfigHelper; import org.eclipse.hawkbit.repository.model.Action; import org.eclipse.hawkbit.repository.model.Action.ActionStatusCreate; import org.eclipse.hawkbit.repository.model.Action.ActionStatusCreate.ActionStatusCreateBuilder; @@ -52,7 +48,6 @@ import org.eclipse.hawkbit.repository.model.SoftwareModule; import org.eclipse.hawkbit.repository.model.Target; import org.eclipse.hawkbit.tenancy.TenantAwareAuthenticationDetails; -import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties; import org.eclipse.hawkbit.utils.IpUtil; import org.springframework.amqp.AmqpRejectAndDontRequeueException; import org.springframework.amqp.core.Message; @@ -315,29 +310,7 @@ private void registerTarget(final Message message, final String virtualHost) { } private void sendUpdateCommandToTarget(final Target target) { - if (TenantConfigHelper.getAsSystem(TenantConfigurationProperties.TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED, Boolean.class)) { - sendCurrentActionsAsMultiActionToTarget(target); - } else { - sendOldestActionToTarget(target); - } - } - - private void sendCurrentActionsAsMultiActionToTarget(final Target target) { - final List actions = controllerManagement.findActiveActionsWithHighestWeight(target.getControllerId(), MAX_ACTION_COUNT); - - // gets all software modules for all action at once - final Set allSmIds = actions.stream() - .map(Action::getDistributionSet) - .flatMap(ds -> ds.getModules().stream()) - .map(SoftwareModule::getId) - .collect(Collectors.toSet()); - final Map> getSoftwareModuleMetadata = - allSmIds.isEmpty() ? Collections.emptyMap() : controllerManagement.findTargetVisibleMetaDataBySoftwareModuleId(allSmIds); - - amqpMessageDispatcherService.sendMultiActionRequestToTarget(target, actions, module -> getSoftwareModuleMetadata.get(module.getId())); - } - - private void sendOldestActionToTarget(final Target target) { + // send oldest action to Target final Optional actionOptional = controllerManagement.findActiveActionWithHighestWeight(target.getControllerId()); if (actionOptional.isEmpty()) { return; 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 4a9168e5f3..09bbaad29a 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 @@ -11,7 +11,6 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; -import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.ArgumentMatchers.anyString; @@ -112,10 +111,6 @@ void before() { TenantConfigHelper.setTenantConfigurationManagement(tenantConfigurationManagement); messageConverter = new Jackson2JsonMessageConverter(); lenient().when(rabbitTemplate.getMessageConverter()).thenReturn(messageConverter); - final TenantConfigurationValue multiAssignmentConfig = TenantConfigurationValue.builder().value(Boolean.FALSE) - .global(Boolean.FALSE).build(); - lenient().when(tenantConfigurationManagement.getConfigurationValue(MULTI_ASSIGNMENTS_ENABLED, Boolean.class)) - .thenReturn(multiAssignmentConfig); amqpMessageHandlerService = new AmqpMessageHandlerService( rabbitTemplate, amqpMessageDispatcherServiceMock, controllerManagementMock, confirmationManagementMock); diff --git a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageDispatcherServiceIntegrationTest.java b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageDispatcherServiceIntegrationTest.java index 2a76dfe113..b5850151b0 100644 --- a/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageDispatcherServiceIntegrationTest.java +++ b/hawkbit-dmf/hawkbit-dmf-amqp/src/test/java/org/eclipse/hawkbit/integration/AmqpMessageDispatcherServiceIntegrationTest.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.integration; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.eclipse.hawkbit.dmf.amqp.api.EventTopic.BATCH_DOWNLOAD; import static org.eclipse.hawkbit.dmf.amqp.api.EventTopic.BATCH_DOWNLOAD_AND_INSTALL; import static org.eclipse.hawkbit.dmf.amqp.api.EventTopic.DOWNLOAD; @@ -23,7 +22,6 @@ import java.util.Collections; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -41,8 +39,6 @@ import org.eclipse.hawkbit.dmf.json.model.DmfSoftwareModule; import org.eclipse.hawkbit.dmf.json.model.DmfTarget; import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent; @@ -212,294 +208,6 @@ void assignDistributionSetMultipleTimes() { assertDownloadAndInstallMessage(distributionSet2.getModules(), controllerId); } - /** - * If multi assignment is enabled multi-action messages are sent. - */ - @Test - @ExpectEvents({ - @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = MultiActionAssignEvent.class, count = 2), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 0), - @Expect(type = CancelTargetAssignmentEvent.class, count = 0), - @Expect(type = ActionCreatedEvent.class, count = 2), - @Expect(type = ActionUpdatedEvent.class, count = 0), - @Expect(type = DistributionSetCreatedEvent.class, count = 2), - @Expect(type = SoftwareModuleCreatedEvent.class, count = 6), - @Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock - @Expect(type = TargetUpdatedEvent.class, count = 2), - @Expect(type = TargetPollEvent.class, count = 1), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) - void assignMultipleDsInMultiAssignMode() { - enableMultiAssignments(); - final String controllerId = TARGET_PREFIX + "assignMultipleDsInMultiAssignMode"; - registerAndAssertTargetWithExistingTenant(controllerId); - - final Long actionId1 = assignNewDsToTarget(controllerId, 450); - final SimpleEntry action1Install = new SimpleEntry<>(actionId1, EventTopic.DOWNLOAD_AND_INSTALL); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); - assertLatestMultiActionMessage(controllerId, Collections.singletonList(action1Install)); - - final Long actionId2 = assignNewDsToTarget(controllerId, 111); - final SimpleEntry action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); - assertLatestMultiActionMessage(controllerId, Arrays.asList(action1Install, action2Install)); - } - - /** - * Verify payload of multi action messages. - */ - @Test - void assertMultiActionMessagePayloads() { - final int expectedWeightIfNotSet = 1000; - final int weight1 = 600; - final String controllerId = UUID.randomUUID().toString(); - registerAndAssertTargetWithExistingTenant(controllerId); - final DistributionSet ds = testdataFactory.createDistributionSet(); - testdataFactory.addSoftwareModuleMetadata(ds); - - final Long installActionId = makeAssignment(DeploymentRequest.builder(controllerId, ds.getId()) - .actionType(ActionType.FORCED).build()).getAssignedEntity().get(0).getId(); - enableMultiAssignments(); - final Long downloadActionId = makeAssignment(DeploymentRequest.builder(controllerId, ds.getId()) - .actionType(ActionType.DOWNLOAD_ONLY).weight(weight1).build()).getAssignedEntity().get(0).getId(); - final Long cancelActionId = makeAssignment( - DeploymentRequest.builder(controllerId, ds.getId()).weight(DEFAULT_TEST_WEIGHT).build()) - .getAssignedEntity().get(0).getId(); - // make sure the latest message in the queue is the one triggered by the - // cancellation - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.DOWNLOAD_AND_INSTALL, EventTopic.MULTI_ACTION, - EventTopic.MULTI_ACTION); - deploymentManagement.cancelAction(cancelActionId); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); - - final List multiActionMessages = getLatestMultiActionMessages(controllerId); - assertThat(multiActionMessages).hasSize(3); - final DmfMultiActionElement installMessage = multiActionMessages.stream() - .filter(message -> message.getTopic().equals(EventTopic.DOWNLOAD_AND_INSTALL)).findFirst().get(); - final DmfMultiActionElement downloadMessage = multiActionMessages.stream() - .filter(message -> message.getTopic().equals(EventTopic.DOWNLOAD)).findFirst().get(); - final DmfMultiActionElement cancelMessage = multiActionMessages.stream() - .filter(message -> message.getTopic().equals(EventTopic.CANCEL_DOWNLOAD)).findFirst().get(); - assertThat(installMessage.getWeight()).isEqualTo(expectedWeightIfNotSet); - assertThat(downloadMessage.getWeight()).isEqualTo(weight1); - assertThat(cancelMessage.getWeight()).isEqualTo(DEFAULT_TEST_WEIGHT); - - assertThat(installMessage.getAction()).isExactlyInstanceOf(DmfDownloadAndUpdateRequest.class) - .hasFieldOrPropertyWithValue("actionId", installActionId); - assertThat(downloadMessage.getAction()).isExactlyInstanceOf(DmfDownloadAndUpdateRequest.class) - .hasFieldOrPropertyWithValue("actionId", downloadActionId); - assertThat(cancelMessage.getAction()).isExactlyInstanceOf(DmfActionRequest.class) - .hasFieldOrPropertyWithValue("actionId", cancelActionId); - assertDmfDownloadAndUpdateRequest((DmfDownloadAndUpdateRequest) installMessage.getAction(), ds.getModules(), - controllerId); - assertDmfDownloadAndUpdateRequest((DmfDownloadAndUpdateRequest) downloadMessage.getAction(), ds.getModules(), - controllerId); - } - - /** - * Handle cancelation process of an action in multi assignment mode. - */ - @Test - @ExpectEvents({ - @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = TargetUpdatedEvent.class, count = 2), - @Expect(type = TargetPollEvent.class, count = 1), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1), - @Expect(type = MultiActionCancelEvent.class, count = 1), - @Expect(type = MultiActionAssignEvent.class, count = 2), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 0), - @Expect(type = CancelTargetAssignmentEvent.class, count = 0), - @Expect(type = ActionCreatedEvent.class, count = 2), - @Expect(type = ActionUpdatedEvent.class, count = 2), - @Expect(type = DistributionSetCreatedEvent.class, count = 2), - @Expect(type = SoftwareModuleCreatedEvent.class, count = 6), - @Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 6) // implicit lock - }) - void cancelActionInMultiAssignMode() { - enableMultiAssignments(); - final String controllerId = TARGET_PREFIX + "cancelActionInMultiAssignMode"; - registerAndAssertTargetWithExistingTenant(controllerId); - - final long actionId1 = assignNewDsToTarget(controllerId, 675); - final long actionId2 = assignNewDsToTarget(controllerId, 343); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION, EventTopic.MULTI_ACTION); - deploymentManagement.cancelAction(actionId1); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); - - final SimpleEntry action1Cancel = new SimpleEntry<>(actionId1, EventTopic.CANCEL_DOWNLOAD); - final SimpleEntry action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL); - - assertLatestMultiActionMessage(controllerId, Arrays.asList(action1Cancel, action2Install)); - updateActionViaDmfClient(controllerId, actionId1, DmfActionStatus.CANCELED); - - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); - assertLatestMultiActionMessage(controllerId, Collections.singletonList(action2Install)); - } - - /** - * Handle finishing an action in multi assignment mode. - */ - @Test - @ExpectEvents({ - @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = MultiActionAssignEvent.class, count = 2), - @Expect(type = TargetAttributesRequestedEvent.class, count = 1), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 0), - @Expect(type = CancelTargetAssignmentEvent.class, count = 0), - @Expect(type = ActionCreatedEvent.class, count = 2), - @Expect(type = ActionUpdatedEvent.class, count = 1), - @Expect(type = DistributionSetCreatedEvent.class, count = 2), - @Expect(type = SoftwareModuleCreatedEvent.class, count = 6), - @Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock - @Expect(type = TargetUpdatedEvent.class, count = 3), - @Expect(type = TargetPollEvent.class, count = 1), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) - void finishActionInMultiAssignMode() { - enableMultiAssignments(); - final String controllerId = TARGET_PREFIX + "finishActionInMultiAssignMode"; - registerAndAssertTargetWithExistingTenant(controllerId); - - final long actionId1 = assignNewDsToTarget(controllerId, 66); - final long actionId2 = assignNewDsToTarget(controllerId, 767); - final SimpleEntry action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION, EventTopic.MULTI_ACTION); - - updateActionViaDmfClient(controllerId, actionId1, DmfActionStatus.FINISHED); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.REQUEST_ATTRIBUTES_UPDATE, EventTopic.MULTI_ACTION); - assertRequestAttributesUpdateMessage(controllerId); - assertLatestMultiActionMessage(controllerId, Collections.singletonList(action2Install)); - } - - /** - * If multi assignment is enabled assigning a DS multiple times creates a new action every time. - */ - @Test - @ExpectEvents({ - @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = MultiActionAssignEvent.class, count = 2), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 0), - @Expect(type = CancelTargetAssignmentEvent.class, count = 0), - @Expect(type = ActionCreatedEvent.class, count = 2), - @Expect(type = ActionUpdatedEvent.class, count = 0), - @Expect(type = DistributionSetCreatedEvent.class, count = 1), - @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), - @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = TargetUpdatedEvent.class, count = 2), - @Expect(type = TargetPollEvent.class, count = 1), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) - void assignDsMultipleTimesInMultiAssignMode() { - enableMultiAssignments(); - final String controllerId = TARGET_PREFIX + "assignDsMultipleTimesInMultiAssignMode"; - registerAndAssertTargetWithExistingTenant(controllerId); - final Long dsId = testdataFactory.createDistributionSet().getId(); - - final Long actionId1 = getFirstAssignedAction(assignDistributionSet(dsId, controllerId, 344)).getId(); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); - final Long actionId2 = getFirstAssignedAction(assignDistributionSet(dsId, controllerId, 775)).getId(); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); - - final SimpleEntry action1Install = new SimpleEntry<>(actionId1, EventTopic.DOWNLOAD_AND_INSTALL); - final SimpleEntry action2Install = new SimpleEntry<>(actionId2, EventTopic.DOWNLOAD_AND_INSTALL); - assertLatestMultiActionMessage(controllerId, Arrays.asList(action1Install, action2Install)); - } - - /** - * If multi assignment is enabled multiple rollouts with the same DS lead to multiple actions. - */ - @Test - @ExpectEvents({ - @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = MultiActionAssignEvent.class, count = 2), - @Expect(type = TargetAssignDistributionSetEvent.class, count = 0), - @Expect(type = CancelTargetAssignmentEvent.class, count = 0), - @Expect(type = ActionCreatedEvent.class, count = 2), - @Expect(type = ActionUpdatedEvent.class, count = 2), - @Expect(type = DistributionSetCreatedEvent.class, count = 1), - @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), - @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = TargetUpdatedEvent.class, count = 1), - @Expect(type = TargetPollEvent.class, count = 1), - @Expect(type = RolloutCreatedEvent.class, count = 2), - @Expect(type = RolloutUpdatedEvent.class, count = 6), - @Expect(type = RolloutGroupCreatedEvent.class, count = 2), - @Expect(type = RolloutGroupUpdatedEvent.class, count = 6), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) - void startRolloutsWithSameDsInMultiAssignMode() { - enableMultiAssignments(); - final String controllerId = TARGET_PREFIX + "startRolloutsWithSameDsInMultiAssignMode"; - - registerAndAssertTargetWithExistingTenant(controllerId); - final DistributionSet ds = testdataFactory.createDistributionSet(); - final Set smIds = getSoftwareModuleIds(ds); - final String filterQuery = "controllerId==" + controllerId; - - createAndStartRollout(ds, filterQuery, 122); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); - assertLatestMultiActionMessageContainsInstallMessages(controllerId, Collections.singletonList(smIds)); - - createAndStartRollout(ds, filterQuery, 43); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); - assertLatestMultiActionMessageContainsInstallMessages(controllerId, Arrays.asList(smIds, smIds)); - } - - /** - * If multi assignment is enabled finishing one rollout does not affect other rollouts of the target. - */ - @Test - @ExpectEvents({ - @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = MultiActionAssignEvent.class, count = 3), - @Expect(type = ActionCreatedEvent.class, count = 3), - @Expect(type = ActionUpdatedEvent.class, count = 5), - @Expect(type = DistributionSetCreatedEvent.class, count = 2), - @Expect(type = SoftwareModuleCreatedEvent.class, count = 6), - @Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock - @Expect(type = TargetUpdatedEvent.class, count = 5), - @Expect(type = TargetPollEvent.class, count = 1), - @Expect(type = TargetAttributesRequestedEvent.class, count = 2), - @Expect(type = RolloutCreatedEvent.class, count = 3), - @Expect(type = RolloutUpdatedEvent.class, count = 9), - @Expect(type = RolloutGroupCreatedEvent.class, count = 3), - @Expect(type = RolloutGroupUpdatedEvent.class, count = 9), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) - void startMultipleRolloutsAndFinishInMultiAssignMode() { - enableMultiAssignments(); - final String controllerId = TARGET_PREFIX + "startMultipleRolloutsAndFinishInMultiAssignMode"; - - registerAndAssertTargetWithExistingTenant(controllerId); - final String filterQuery = "controllerId==" + controllerId; - final DistributionSet ds1 = testdataFactory.createDistributionSet(); - final Set smIds1 = getSoftwareModuleIds(ds1); - final DistributionSet ds2 = testdataFactory.createDistributionSet(); - final Set smIds2 = getSoftwareModuleIds(ds2); - - createAndStartRollout(ds1, filterQuery, 12); - createAndStartRollout(ds2, filterQuery, 45); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION, EventTopic.MULTI_ACTION); - createAndStartRollout(ds1, filterQuery, 65); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.MULTI_ACTION); - assertLatestMultiActionMessageContainsInstallMessages(controllerId, Arrays.asList(smIds1, smIds2, smIds1)); - - final List installActions = getLatestMultiActionMessageActions(controllerId).stream() - .filter(entry -> entry.getValue().equals(EventTopic.DOWNLOAD_AND_INSTALL)) - .map(Entry::getKey) - .toList(); - - updateActionViaDmfClient(controllerId, installActions.get(0), DmfActionStatus.FINISHED); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.REQUEST_ATTRIBUTES_UPDATE, EventTopic.MULTI_ACTION); - assertLatestMultiActionMessageContainsInstallMessages(controllerId, Arrays.asList(smIds2, smIds1)); - - updateActionViaDmfClient(controllerId, installActions.get(1), DmfActionStatus.FINISHED); - waitUntilEventMessagesAreDispatchedToTarget(EventTopic.REQUEST_ATTRIBUTES_UPDATE, EventTopic.MULTI_ACTION); - assertLatestMultiActionMessageContainsInstallMessages(controllerId, Collections.singletonList(smIds1)); - } - /** * Verify that a cancel assignment send a cancel message. */ @@ -649,21 +357,6 @@ protected void assertEventMessageNotPresent(final EventTopic eventTopic) { assertThat(replyToListener.getLatestEventMessage(eventTopic)).isNull(); } - /** - * Verify that batch and multi-assignments can't be activated at the same time. - */ - @Test - void assertBatchAndMultiAssignmentsNotCompatible() { - enableBatchAssignments(); - assertThatExceptionOfType(TenantConfigurationValueChangeNotAllowedException.class) - .isThrownBy(() -> enableMultiAssignments()); - disableBatchAssignments(); - - enableMultiAssignments(); - assertThatExceptionOfType(TenantConfigurationValueChangeNotAllowedException.class) - .isThrownBy(() -> enableBatchAssignments()); - } - /** * Verify payload of batch assignments. */ @@ -734,27 +427,6 @@ void sendConfirmStatus() { assertEventMessageNotPresent(EventTopic.DOWNLOAD_AND_INSTALL); } - private static Set getSmIds(final DmfDownloadAndUpdateRequest request) { - return request.getSoftwareModules().stream().map(DmfSoftwareModule::getModuleId).collect(Collectors.toSet()); - } - - private static List getDownloadAndUpdateRequests(final DmfMultiActionRequest request) { - return request.getElements().stream() - .filter(AmqpMessageDispatcherServiceIntegrationTest::isDownloadAndUpdateRequest) - .map(multiAction -> (DmfDownloadAndUpdateRequest) multiAction.getAction()).toList(); - } - - private static boolean isDownloadAndUpdateRequest(final DmfMultiActionElement multiActionElement) { - return multiActionElement.getTopic().equals(EventTopic.DOWNLOAD) - || multiActionElement.getTopic().equals(EventTopic.DOWNLOAD_AND_INSTALL); - } - - private List getLatestMultiActionMessages(final String expectedControllerId) { - final Message multiactionMessage = replyToListener.getLatestEventMessage(EventTopic.MULTI_ACTION); - assertThat(multiactionMessage.getMessageProperties().getHeaders()).containsEntry(MessageHeaderKey.THING_ID, expectedControllerId); - return ((DmfMultiActionRequest) getDmfClient().getMessageConverter().fromMessage(multiactionMessage)).getElements(); - } - private void updateActionViaDmfClient(final String controllerId, final long actionId, final DmfActionStatus status) { createAndSendActionStatusUpdateMessage(controllerId, actionId, status); @@ -773,18 +445,6 @@ private Long assignNewDsToTarget(final String controllerId, final Integer weight return actionId; } - private Set getSoftwareModuleIds(final DistributionSet ds) { - return ds.getModules().stream().map(SoftwareModule::getId).collect(Collectors.toSet()); - } - - private Rollout createAndStartRollout(final DistributionSet ds, final String filterQuery, final Integer weight) { - final Rollout rollout = testdataFactory.createRolloutByVariables(UUID.randomUUID().toString(), "", 1, - filterQuery, ds, "50", "5", ActionType.FORCED, weight, false); - rolloutManagement.start(rollout.getId()); - rolloutHandler.handleAll(); - return rollout; - } - private void waitUntilTargetHasStatus(final String controllerId, final TargetUpdateStatus status) { waitUntil(() -> { final Optional findTargetByControllerID = targetManagement.findByControllerId(controllerId); @@ -795,29 +455,4 @@ private void waitUntilTargetHasStatus(final String controllerId, final TargetUpd private void waitUntil(final Callable callable) { await().until(() -> SecurityContextSwitch.asPrivileged(callable)); } - - private void assertLatestMultiActionMessageContainsInstallMessages(final String controllerId, - final List> smIdsOfActionsExpected) { - final Message multiactionMessage = replyToListener.getLatestEventMessage(EventTopic.MULTI_ACTION); - assertThat(multiactionMessage.getMessageProperties().getHeaders()).containsEntry(MessageHeaderKey.THING_ID, controllerId); - final DmfMultiActionRequest multiActionRequest = - (DmfMultiActionRequest) getDmfClient().getMessageConverter().fromMessage(multiactionMessage); - - final List> smIdsOfActionsFound = getDownloadAndUpdateRequests(multiActionRequest).stream() - .map(AmqpMessageDispatcherServiceIntegrationTest::getSmIds).toList(); - assertThat(smIdsOfActionsFound).containsExactlyInAnyOrderElementsOf(smIdsOfActionsExpected); - } - - private void assertLatestMultiActionMessage(final String controllerId, - final List> actionsExpected) { - final List> actionsFromMessage = getLatestMultiActionMessageActions(controllerId); - assertThat(actionsFromMessage).containsExactlyInAnyOrderElementsOf(actionsExpected); - } - - private List> getLatestMultiActionMessageActions(final String expectedControllerId) { - final List multiActionRequest = getLatestMultiActionMessages(expectedControllerId); - return multiActionRequest.stream() - .map(request -> new SimpleEntry<>(request.getAction().getActionId(), request.getTopic())) - .toList(); - } } diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java index 13bb00b012..6d529b72b3 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtDistributionSetResourceTest.java @@ -1484,52 +1484,30 @@ void identicalAssignmentInRequestAreRemovedIfMultiassignmentsDisabled() throws E .andExpect(jsonPath("total", equalTo(1))); } - /** - * Assigning targets multiple times to a DS in one request works in multi-assignment mode. - */ - @Test - void multiAssignment() throws Exception { - final List targetIds = testdataFactory.createTargets(2).stream().map(Target::getControllerId).toList(); - final Long dsId = testdataFactory.createDistributionSet().getId(); - - final JSONArray body = new JSONArray(); - body.put(getAssignmentObject(targetIds.get(0), MgmtActionType.FORCED, 56)); - body.put(getAssignmentObject(targetIds.get(0), MgmtActionType.FORCED, 78)); - body.put(getAssignmentObject(targetIds.get(1), MgmtActionType.FORCED, 67)); - body.put(getAssignmentObject(targetIds.get(1), MgmtActionType.SOFT, 34)); - - enableMultiAssignments(); - mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(body.toString()) - .contentType(APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("total", equalTo(body.length()))); - } - /** * An assignment request containing a weight is only accepted when weight is valide and multi assignment is on. */ @Test void weightValidation() throws Exception { final String targetId = testdataFactory.createTarget().getControllerId(); - final Long dsId = testdataFactory.createDistributionSet().getId(); + final Long dsId1 = testdataFactory.createDistributionSet().getId(); + final Long dsId2 = testdataFactory.createDistributionSet().getId(); final int weight = 78; final JSONArray bodyValide = new JSONArray().put(getAssignmentObject(targetId, MgmtActionType.FORCED, weight)); final JSONArray bodyInvalide = new JSONArray() .put(getAssignmentObject(targetId, MgmtActionType.FORCED, Action.WEIGHT_MIN - 1)); - mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(bodyValide.toString()) + mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId1).content(bodyValide.toString()) .contentType(APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); - enableMultiAssignments(); - mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(bodyInvalide.toString()) + mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId2).content(bodyInvalide.toString()) .contentType(APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.repo.constraintViolation"))); - mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId).content(bodyValide.toString()) + mvc.perform(post("/rest/v1/distributionsets/{ds}/assignedTargets", dsId2).content(bodyValide.toString()) .contentType(APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()); diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java index a6f1253635..7795bed24b 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtRolloutResourceTest.java @@ -105,7 +105,6 @@ class MgmtRolloutResourceTest extends AbstractManagementApiIntegrationTest { */ @Test void getRollout() throws Exception { - enableMultiAssignments(); approvalStrategy.setApprovalNeeded(true); try { approvalStrategy.setApprovalDecidedBy("exampleUsername"); @@ -1678,26 +1677,20 @@ void weightValidation() throws Exception { null, null); final String valideWeightRequest = JsonBuilder.rollout("withWeight", "d", 2, dsId, "id==rollout*", new RolloutGroupConditionBuilder().withDefaults().build(), null, null, weight, null, null, null); - final String valideWeightRequestMultiAssignment = JsonBuilder.rollout("withWeightMultiAssignment", "d", 2, dsId, "id==rollout*", - new RolloutGroupConditionBuilder().withDefaults().build(), null, null, weight, null, null, null); mvc.perform(post("/rest/v1/rollouts").content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isCreated()); - enableMultiAssignments(); + mvc.perform(post("/rest/v1/rollouts").content(invalideWeightRequest).contentType(MediaType.APPLICATION_JSON) .accept(MediaType.APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.errorCode", equalTo("hawkbit.server.error.repo.constraintViolation"))); - mvc.perform(post("/rest/v1/rollouts").content(valideWeightRequestMultiAssignment).contentType(MediaType.APPLICATION_JSON) - .accept(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isCreated()); final List rollouts = rolloutManagement.findAll(false, PAGE).getContent(); - assertThat(rollouts).hasSize(2); + assertThat(rollouts).hasSize(1); assertThat(rollouts.get(0).getWeight()).get().isEqualTo(weight); } diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResourceTest.java index 4fceef6a55..9db00fff6d 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetFilterQueryResourceTest.java @@ -560,7 +560,6 @@ void getAssignDS() throws Exception { */ @Test void createAutoAssignDS() throws Exception { - enableMultiAssignments(); enableConfirmationFlow(); final String filterName = "filter_01"; @@ -643,7 +642,7 @@ void weightValidation() throws Exception { filterId).content(valideWeightRequest).contentType(MediaType.APPLICATION_JSON)) .andDo(print()) .andExpect(status().isOk()); - enableMultiAssignments(); + mvc.perform(post(MgmtTargetFilterQueryRestApi.TARGETFILTERS_V1 + "/{targetFilterQueryId}/autoAssignDS", filterId).content(invalideWeightRequest).contentType(MediaType.APPLICATION_JSON)) .andDo(print()) diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java index 28528706f7..5eab93669a 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTargetResourceTest.java @@ -2213,24 +2213,6 @@ void identicalAssignmentInRequestAreRemovedIfMultiassignmentsDisabled() throws E .andExpect(jsonPath("total", equalTo(1))); } - /** - * Assign multiple DSs to a target in one request with multiassignments enabled. - */ - @Test - void multiAssignment() throws Exception { - final String targetId = testdataFactory.createTarget().getControllerId(); - final List dsIds = testdataFactory.createDistributionSets(2).stream().map(DistributionSet::getId).toList(); - - final JSONArray body = new JSONArray(); - dsIds.forEach(id -> body.put(getAssignmentObject(id, MgmtActionType.FORCED, 76))); - - enableMultiAssignments(); - mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(body.toString()).contentType(APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()) - .andExpect(jsonPath("total", equalTo(2))); - } - /** * An assignment request containing a weight is only accepted when weight is valid and multi assignment is on. */ @@ -2243,7 +2225,6 @@ void weightValidation() throws Exception { final JSONObject bodyValid = getAssignmentObject(dsId, MgmtActionType.FORCED, weight); final JSONObject bodyInvalid = getAssignmentObject(dsId, MgmtActionType.FORCED, Action.WEIGHT_MIN - 1); - enableMultiAssignments(); mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(bodyInvalid.toString()).contentType(APPLICATION_JSON)) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isBadRequest()) @@ -2272,48 +2253,24 @@ void weightWithSingleAssignment() throws Exception { .andExpect(status().isOk()); } - /** - * An assignment request containing a valid weight when multi assignment is on. - */ - @Test - void weightWithMultiAssignment() throws Exception { - final String targetId = testdataFactory.createTarget().getControllerId(); - final Long dsId = testdataFactory.createDistributionSet().getId(); - final int weight = 98; - - final JSONObject bodyValid = getAssignmentObject(dsId, MgmtActionType.FORCED, weight); - - enableMultiAssignments(); - mvc.perform(post("/rest/v1/targets/{targetId}/assignedDS", targetId).content(bodyValid.toString()).contentType(APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isOk()); - - final List actions = deploymentManagement.findActionsAll(PAGE).get().toList(); - assertThat(actions).size().isEqualTo(1); - assertThat(actions.get(0).getWeight()).get().isEqualTo(weight); - } - /** * Get weight of action */ @Test void getActionWeight() throws Exception { final String targetId = testdataFactory.createTarget().getControllerId(); - final Long dsId = testdataFactory.createDistributionSet().getId(); - final int customWeightHigh = 800; - final int customWeightLow = 300; - assignDistributionSet(dsId, targetId); // default weight 1000 - enableMultiAssignments(); - assignDistributionSet(dsId, targetId, customWeightHigh); - assignDistributionSet(dsId, targetId, customWeightLow); + final Long dsId1 = testdataFactory.createDistributionSet().getId(); + final Long dsId2 = testdataFactory.createDistributionSet().getId(); + final int customWeight = 800; + assignDistributionSet(dsId1, targetId); // default weight 1000 + assignDistributionSet(dsId2, targetId, customWeight); mvc.perform(get("/rest/v1/targets/{targetId}/actions", targetId) .param(MgmtRestConstants.REQUEST_PARAMETER_SORTING, "WEIGHT:ASC")) .andDo(MockMvcResultPrinter.print()) .andExpect(status().isOk()) - .andExpect(jsonPath("content.[0].weight", equalTo(customWeightLow))) - .andExpect(jsonPath("content.[1].weight", equalTo(customWeightHigh))) - .andExpect(jsonPath("content.[2].weight", equalTo(1000))); + .andExpect(jsonPath("content.[0].weight", equalTo(customWeight))) + .andExpect(jsonPath("content.[1].weight", equalTo(1000))); } /** diff --git a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java index f91d40ed91..24b9051b16 100644 --- a/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java +++ b/hawkbit-mgmt/hawkbit-mgmt-resource/src/test/java/org/eclipse/hawkbit/mgmt/rest/resource/MgmtTenantManagementResourceTest.java @@ -15,7 +15,6 @@ import static org.eclipse.hawkbit.repository.test.util.SecurityContextSwitch.withUser; import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_ENABLED; import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY; -import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED; import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED; import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.ROLLOUT_APPROVAL_ENABLED; import static org.hamcrest.CoreMatchers.equalTo; @@ -141,27 +140,6 @@ void putTenantMetadataFails() throws Exception { assertDefaultDsTypeUpdateBadRequestFails(newDefaultDsType, oldDefaultDsType, status().isNotFound()); } - /** - * The 'multi.assignments.enabled' property must not be changed to false. - */ - @Test - void deactivateMultiAssignment() throws Exception { - final String bodyActivate = new JSONObject().put("value", true).toString(); - final String bodyDeactivate = new JSONObject().put("value", false).toString(); - - mvc.perform(put(SYSTEM_V1 + "/configs/{keyName}", MULTI_ASSIGNMENTS_ENABLED) - .content(bodyActivate) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isNoContent()); - - mvc.perform(put(SYSTEM_V1 + "/configs/{keyName}", MULTI_ASSIGNMENTS_ENABLED) - .content(bodyDeactivate) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isForbidden()); - } - /** * The Batch configuration should not be applied, because of invalid TenantConfiguration props */ @@ -249,36 +227,6 @@ void changeBatchConfiguration() throws Exception { "Change BatchConfiguration was successful but TenantConfiguration property was not actually changed."); } - /** - * The 'repository.actions.autoclose.enabled' property must not be modified if Multi-Assignments is enabled. - */ - @Test - void autoCloseCannotBeModifiedIfMultiAssignmentIsEnabled() throws Exception { - final String bodyActivate = new JSONObject().put("value", true).toString(); - final String bodyDeactivate = new JSONObject().put("value", false).toString(); - - // enable Multi-Assignments - mvc.perform(put(SYSTEM_V1 + "/configs/{keyName}", MULTI_ASSIGNMENTS_ENABLED) - .content(bodyActivate) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isNoContent()); - - // try to enable Auto-Close - mvc.perform(put(SYSTEM_V1 + "/configs/{keyName}", REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED) - .content(bodyActivate) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isForbidden()); - - // try to disable Auto-Close - mvc.perform(put(SYSTEM_V1 + "/configs/{keyName}", REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED) - .content(bodyDeactivate) - .contentType(MediaType.APPLICATION_JSON)) - .andDo(MockMvcResultPrinter.print()) - .andExpect(status().isForbidden()); - } - /** * Handles DELETE request deleting a tenant specific configuration. */ 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 d7e256bc22..bbb99599ca 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 @@ -32,7 +32,7 @@ import org.eclipse.hawkbit.repository.exception.CancelActionNotAllowedException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException; -import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException; +import org.eclipse.hawkbit.repository.exception.MultiAssignmentException; import org.eclipse.hawkbit.repository.exception.RSQLParameterSyntaxException; import org.eclipse.hawkbit.repository.exception.RSQLParameterUnsupportedFieldException; import org.eclipse.hawkbit.repository.model.Action; @@ -76,8 +76,8 @@ default String permissionGroup() { * @throws EntityNotFoundException if either provided {@link DistributionSet} or {@link Target}s do not exist * @throws AssignmentQuotaExceededException if the maximum number of targets the distribution set can be * assigned to at once is exceeded - * @throws MultiAssignmentIsNotEnabledException if the request results in multiple assignments to the same - * target and multi-assignment is disabled + * @throws MultiAssignmentException if the request results in multiple assignments to the same + * target */ @PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET) List assignDistributionSets( @@ -102,8 +102,8 @@ List assignDistributionSets( * defined by the {@link DistributionSetType}. * @throws EntityNotFoundException if either provided {@link DistributionSet} or {@link Target}s do not exist * @throws AssignmentQuotaExceededException if the maximum number of targets the distribution set can be assigned to at once is exceeded - * @throws MultiAssignmentIsNotEnabledException if the request results in multiple assignments to the same - * target and multi-assignment is disabled + * @throws MultiAssignmentException if the request results in multiple assignments to the same + * target */ @PreAuthorize(HAS_UPDATE_TARGET_AND_READ_DISTRIBUTION_SET) List offlineAssignedDistributionSets(Collection> assignments); diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/MultiActionAssignEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/MultiActionAssignEvent.java deleted file mode 100644 index fd8e43e70a..0000000000 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/MultiActionAssignEvent.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.repository.event.remote; - -import java.io.Serial; -import java.util.List; - -import lombok.NoArgsConstructor; -import org.eclipse.hawkbit.repository.model.Action; - -/** - * Generic deployment event for the Multi-Assignments feature. The event extends - * the {@link MultiActionEvent} and holds a list of controller IDs to identify - * the targets which are affected by a deployment action and a list of - * actionIds containing the identifiers of the affected actions - * as payload. This event is only published in case of an assignment. - */ -@NoArgsConstructor -public class MultiActionAssignEvent extends MultiActionEvent { - - @Serial - private static final long serialVersionUID = 1L; - - /** - * Constructor. - * - * @param tenant tenant the event is scoped to - * @param actions the actions of the deployment action - */ - public MultiActionAssignEvent(String tenant, List actions) { - super(tenant, actions); - } -} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/MultiActionCancelEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/MultiActionCancelEvent.java deleted file mode 100644 index 68bb2abedf..0000000000 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/MultiActionCancelEvent.java +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Copyright (c) 2020 Bosch.IO GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.repository.event.remote; - -import java.io.Serial; -import java.util.List; - -import lombok.NoArgsConstructor; -import org.eclipse.hawkbit.repository.model.Action; - -/** - * Generic deployment event for the Multi-Assignments feature. The event extends the {@link MultiActionEvent} and holds a list of controller IDs - * to identify the targets which are affected by a deployment action and a list of actionIds containing the identifiers of the affected actions - * as payload. This event is only published in case of a cancellation. - */ -@NoArgsConstructor // for serialization libs like jackson -public class MultiActionCancelEvent extends MultiActionEvent { - - @Serial - private static final long serialVersionUID = 1L; - - public MultiActionCancelEvent(String tenant, List actions) { - super(tenant, actions); - } -} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/MultiActionEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/MultiActionEvent.java deleted file mode 100644 index b6171724b6..0000000000 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/MultiActionEvent.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright (c) 2019 Bosch Software Innovations GmbH and others - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.repository.event.remote; - -import java.io.Serial; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; - -import lombok.AccessLevel; -import lombok.Data; -import lombok.EqualsAndHashCode; -import lombok.NoArgsConstructor; -import lombok.NonNull; -import lombok.ToString; -import org.eclipse.hawkbit.repository.Identifiable; -import org.eclipse.hawkbit.repository.model.Action; -import org.eclipse.hawkbit.repository.model.Target; - -/** - * Generic deployment event for the Multi-Assignments feature. The event payload holds a list of controller IDs identifying the targets which - * are affected by a deployment action (e.g. a software assignment (update) or a cancellation of an update). - */ -@NoArgsConstructor(access = AccessLevel.PROTECTED) // for serialization libs like jackson -@Data -@EqualsAndHashCode(callSuper = true) -@ToString(callSuper = true) -public abstract class MultiActionEvent extends RemoteTenantAwareEvent implements Iterable { - - @Serial - private static final long serialVersionUID = 1L; - - private final List controllerIds = new ArrayList<>(); - private final List actionIds = new ArrayList<>(); - - protected MultiActionEvent(final String tenant, final List actions) { - super(tenant, null); - this.controllerIds.addAll(getControllerIdsFromActions(actions)); - this.actionIds.addAll(getIdsFromActions(actions)); - } - - @Override - @NonNull - public Iterator iterator() { - return controllerIds.iterator(); - } - - private static List getControllerIdsFromActions(final List actions) { - return actions.stream().map(Action::getTarget).map(Target::getControllerId).distinct().toList(); - } - - private static List getIdsFromActions(final List actions) { - return actions.stream().map(Identifiable::getId).toList(); - } -} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/service/MultiActionAssignServiceEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/service/MultiActionAssignServiceEvent.java deleted file mode 100644 index 11275a6c83..0000000000 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/service/MultiActionAssignServiceEvent.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2025 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.repository.event.remote.service; - -import java.io.Serial; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent; - -/** - * Service event for {@link MultiActionAssignEvent}. Event that needs single replica processing - */ -public class MultiActionAssignServiceEvent extends AbstractServiceRemoteEvent { - - @Serial - private static final long serialVersionUID = 1L; - - - @JsonCreator - public MultiActionAssignServiceEvent(@JsonProperty("payload") final MultiActionAssignEvent remoteEvent) { - super(remoteEvent); - } -} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/service/MultiActionCancelServiceEvent.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/service/MultiActionCancelServiceEvent.java deleted file mode 100644 index c8c88e9132..0000000000 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/event/remote/service/MultiActionCancelServiceEvent.java +++ /dev/null @@ -1,31 +0,0 @@ -/** - * Copyright (c) 2025 Contributors to the Eclipse Foundation - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - */ -package org.eclipse.hawkbit.repository.event.remote.service; - -import java.io.Serial; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent; - -/** - * Service event for {@link MultiActionCancelEvent}. Event that needs single replica processing - */ -public class MultiActionCancelServiceEvent extends AbstractServiceRemoteEvent { - - @Serial - private static final long serialVersionUID = 1L; - - - @JsonCreator - public MultiActionCancelServiceEvent(@JsonProperty("payload") final MultiActionCancelEvent remoteEvent) { - super(remoteEvent); - } -} \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiAssignmentIsNotEnabledException.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiAssignmentException.java similarity index 83% rename from hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiAssignmentIsNotEnabledException.java rename to hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiAssignmentException.java index 5cd7fba447..084ada6400 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiAssignmentIsNotEnabledException.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/exception/MultiAssignmentException.java @@ -21,14 +21,14 @@ */ @EqualsAndHashCode(callSuper = true) @ToString(callSuper = true) -public class MultiAssignmentIsNotEnabledException extends AbstractServerRtException { +public class MultiAssignmentException extends AbstractServerRtException { @Serial private static final long serialVersionUID = 1L; - private static final SpServerError THIS_ERROR = SpServerError.SP_MULTIASSIGNMENT_NOT_ENABLED; + private static final SpServerError THIS_ERROR = SpServerError.SP_MULTIASSIGNMENT; - public MultiAssignmentIsNotEnabledException() { + public MultiAssignmentException() { super(THIS_ERROR); } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/helper/TenantConfigHelper.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/helper/TenantConfigHelper.java index c5d3a7e61d..d9a2cf0310 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/helper/TenantConfigHelper.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/repository/helper/TenantConfigHelper.java @@ -10,7 +10,6 @@ package org.eclipse.hawkbit.repository.helper; import static org.eclipse.hawkbit.context.AccessContext.asSystem; -import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED; import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.USER_CONFIRMATION_FLOW_ENABLED; import java.io.Serializable; @@ -45,10 +44,6 @@ public static T getAsSystem(final String key, final Cla return asSystem(() -> getTenantConfigurationManagement().getConfigurationValue(key, valueType).getValue()); } - public static boolean isMultiAssignmentsEnabled() { - return getAsSystem(MULTI_ASSIGNMENTS_ENABLED, Boolean.class); - } - public static boolean isUserConfirmationFlowEnabled() { return getAsSystem(USER_CONFIRMATION_FLOW_ENABLED, Boolean.class); } diff --git a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationProperties.java b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationProperties.java index 57a20baaca..db96979209 100644 --- a/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationProperties.java +++ b/hawkbit-repository/hawkbit-repository-api/src/main/java/org/eclipse/hawkbit/tenancy/configuration/TenantConfigurationProperties.java @@ -116,10 +116,6 @@ public static class TenantConfigurationKey { * Configuration value for percentage of oldest actions to be cleaned if @maxActionsPerTarget quota is hit */ public static final String ACTION_CLEANUP_ON_QUOTA_HIT_PERCENTAGE = "action.cleanup.onQuotaHit.percent"; - /** - * Switch to enable/disable the multi-assignment feature. - */ - public static final String MULTI_ASSIGNMENTS_ENABLED = "multi.assignments.enabled"; /** * Switch to enable/disable the batch-assignment feature. */ diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/EventType.java b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/EventType.java index ac33051613..2ecb995f45 100644 --- a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/EventType.java +++ b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/event/EventType.java @@ -24,8 +24,6 @@ import org.eclipse.hawkbit.repository.event.remote.DistributionSetTagDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.DistributionSetTypeDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.DownloadProgressEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent; import org.eclipse.hawkbit.repository.event.remote.RolloutDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.RolloutGroupDeletedEvent; import org.eclipse.hawkbit.repository.event.remote.RolloutStoppedEvent; @@ -68,8 +66,6 @@ import org.eclipse.hawkbit.repository.event.remote.service.ActionCreatedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.ActionUpdatedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.CancelTargetAssignmentServiceEvent; -import org.eclipse.hawkbit.repository.event.remote.service.MultiActionAssignServiceEvent; -import org.eclipse.hawkbit.repository.event.remote.service.MultiActionCancelServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistributionSetServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetAttributesRequestedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetCreatedServiceEvent; @@ -162,9 +158,6 @@ public class EventType { // target attributes requested flag TYPES.put(37, TargetAttributesRequestedEvent.class); - // deployment event for assignments and /or cancellations - TYPES.put(38, MultiActionAssignEvent.class); - TYPES.put(39, MultiActionCancelEvent.class); // tenant configuration TYPES.put(40, TenantConfigurationCreatedEvent.class); @@ -186,8 +179,6 @@ public class EventType { TYPES.put(1003, TargetAssignDistributionSetServiceEvent.class); TYPES.put(1004, TargetAttributesRequestedServiceEvent.class); TYPES.put(1005, CancelTargetAssignmentServiceEvent.class); - TYPES.put(1006, MultiActionAssignServiceEvent.class); - TYPES.put(1007, MultiActionCancelServiceEvent.class); TYPES.put(1008, ActionCreatedServiceEvent.class); TYPES.put(1009, ActionUpdatedServiceEvent.class); } diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/event/EventPublisherHolder.java b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/event/EventPublisherHolder.java index b800469896..aed15cca5d 100644 --- a/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/event/EventPublisherHolder.java +++ b/hawkbit-repository/hawkbit-repository-core/src/main/java/org/eclipse/hawkbit/repository/event/EventPublisherHolder.java @@ -17,8 +17,6 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.hawkbit.repository.event.remote.AbstractRemoteEvent; import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAttributesRequestedEvent; import org.eclipse.hawkbit.repository.event.remote.TargetDeletedEvent; @@ -29,8 +27,6 @@ import org.eclipse.hawkbit.repository.event.remote.service.ActionCreatedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.ActionUpdatedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.CancelTargetAssignmentServiceEvent; -import org.eclipse.hawkbit.repository.event.remote.service.MultiActionAssignServiceEvent; -import org.eclipse.hawkbit.repository.event.remote.service.MultiActionCancelServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistributionSetServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetAttributesRequestedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetCreatedServiceEvent; @@ -77,8 +73,6 @@ private void validateRemoteEventConfig() { TargetAssignDistributionSetEvent.class, CancelTargetAssignmentEvent.class, TargetAttributesRequestedEvent.class, - MultiActionAssignEvent.class, - MultiActionCancelEvent.class, ActionCreatedEvent.class, ActionUpdatedEvent.class ); @@ -183,10 +177,6 @@ private AbstractRemoteEvent toServiceEvent(final AbstractRemoteEvent event) { return new CancelTargetAssignmentServiceEvent(cancelTargetAssignmentEvent); } else if (event instanceof TargetAttributesRequestedEvent targetAttributesRequestedEvent) { return new TargetAttributesRequestedServiceEvent(targetAttributesRequestedEvent); - } else if (event instanceof MultiActionAssignEvent multiActionAssignEvent) { - return new MultiActionAssignServiceEvent(multiActionAssignEvent); - } else if (event instanceof MultiActionCancelEvent multiActionCancelEvent) { - return new MultiActionCancelServiceEvent(multiActionCancelEvent); } else if (event instanceof ActionCreatedEvent actionCreatedEvent) { return new ActionCreatedServiceEvent(actionCreatedEvent); } else if (event instanceof ActionUpdatedEvent actionUpdatedEvent) { diff --git a/hawkbit-repository/hawkbit-repository-core/src/main/resources/hawkbit-repository-defaults.properties b/hawkbit-repository/hawkbit-repository-core/src/main/resources/hawkbit-repository-defaults.properties index 64ccb3672a..f4c926b9df 100644 --- a/hawkbit-repository/hawkbit-repository-core/src/main/resources/hawkbit-repository-defaults.properties +++ b/hawkbit-repository/hawkbit-repository-core/src/main/resources/hawkbit-repository-defaults.properties @@ -85,10 +85,6 @@ hawkbit.server.tenant.configuration.action-cleanup-on-quota-hit-percent.keyName= hawkbit.server.tenant.configuration.action-cleanup-on-quota-hit-percent.defaultValue=0 hawkbit.server.tenant.configuration.action-cleanup-on-quota-hit-percent.dataType=java.lang.Integer -hawkbit.server.tenant.configuration.multi-assignments-enabled.keyName=multi.assignments.enabled -hawkbit.server.tenant.configuration.multi-assignments-enabled.defaultValue=false -hawkbit.server.tenant.configuration.multi-assignments-enabled.dataType=java.lang.Boolean - hawkbit.server.tenant.configuration.batch-assignments-enabled.keyName=batch.assignments.enabled hawkbit.server.tenant.configuration.batch-assignments-enabled.defaultValue=false hawkbit.server.tenant.configuration.batch-assignments-enabled.dataType=java.lang.Boolean diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractDsAssignmentStrategy.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractDsAssignmentStrategy.java index 08fd91c78b..9c94937967 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractDsAssignmentStrategy.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/AbstractDsAssignmentStrategy.java @@ -65,7 +65,6 @@ public abstract class AbstractDsAssignmentStrategy { private final ActionStatusRepository actionStatusRepository; private final QuotaManagement quotaManagement; - private final BooleanSupplier multiAssignmentsConfig; private final BooleanSupplier confirmationFlowConfig; private final RepositoryProperties repositoryProperties; private final Consumer maxAssignmentExceededHandler; @@ -74,14 +73,13 @@ public abstract class AbstractDsAssignmentStrategy { AbstractDsAssignmentStrategy( final TargetRepository targetRepository, final ActionRepository actionRepository, final ActionStatusRepository actionStatusRepository, - final QuotaManagement quotaManagement, final BooleanSupplier multiAssignmentsConfig, - final BooleanSupplier confirmationFlowConfig, final RepositoryProperties repositoryProperties, + final QuotaManagement quotaManagement, final BooleanSupplier confirmationFlowConfig, + final RepositoryProperties repositoryProperties, final Consumer maxAssignmentExceededHandler) { this.targetRepository = targetRepository; this.actionRepository = actionRepository; this.actionStatusRepository = actionStatusRepository; this.quotaManagement = quotaManagement; - this.multiAssignmentsConfig = multiAssignmentsConfig; this.confirmationFlowConfig = confirmationFlowConfig; this.repositoryProperties = repositoryProperties; this.maxAssignmentExceededHandler = maxAssignmentExceededHandler; @@ -211,10 +209,6 @@ protected void cancelAssignDistributionSetEvent(final Action action) { afterCommit(() -> EventPublisherHolder.getInstance().getEventPublisher().publishEvent(new CancelTargetAssignmentEvent(action))); } - protected boolean isMultiAssignmentsEnabled() { - return multiAssignmentsConfig.getAsBoolean(); - } - protected boolean isConfirmationFlowEnabled() { return confirmationFlowConfig.getAsBoolean(); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java index 65d66c0015..4732fef1be 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaDeploymentManagement.java @@ -52,7 +52,7 @@ import org.eclipse.hawkbit.repository.exception.IncompatibleTargetTypeException; import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException; import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException; -import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException; +import org.eclipse.hawkbit.repository.exception.MultiAssignmentException; import org.eclipse.hawkbit.repository.helper.TenantConfigHelper; import org.eclipse.hawkbit.repository.jpa.Jpa; import org.eclipse.hawkbit.repository.jpa.JpaManagementHelper; @@ -159,10 +159,10 @@ protected JpaDeploymentManagement( maxAssignmentsExceededInfo.requested, maxAssignmentsExceededInfo.quotaExceededException); onlineDsAssignmentStrategy = new OnlineDsAssignmentStrategy(targetRepository, actionRepository, actionStatusRepository, - quotaManagement, this::isMultiAssignmentsEnabled, this::isConfirmationFlowEnabled, repositoryProperties, + quotaManagement, this::isConfirmationFlowEnabled, repositoryProperties, maxAssignmentsExceededHandler); offlineDsAssignmentStrategy = new OfflineDsAssignmentStrategy(targetRepository, actionRepository, actionStatusRepository, - quotaManagement, this::isMultiAssignmentsEnabled, this::isConfirmationFlowEnabled, repositoryProperties, + quotaManagement, this::isConfirmationFlowEnabled, repositoryProperties, maxAssignmentsExceededHandler); } @@ -423,16 +423,12 @@ public void deleteOldestTargetActions(final String controllerId, final int keepL @Retryable(retryFor = { ConcurrencyFailureException.class }, maxAttempts = Constants.TX_RT_MAX, backoff = @Backoff(delay = Constants.TX_RT_DELAY)) public void cancelInactiveScheduledActionsForTargets(final List targetIds) { - if (!isMultiAssignmentsEnabled()) { - targetRepository.getAccessController().ifPresent(v -> { - if (targetRepository.count(AccessController.Operation.UPDATE, TargetSpecifications.hasIdIn(targetIds)) != targetIds.size()) { - throw new EntityNotFoundException(Target.class, targetIds); - } - }); - actionRepository.switchStatus(Status.CANCELED, targetIds, false, Status.SCHEDULED); - } else { - log.debug("The Multi Assignments feature is enabled: No need to cancel inactive scheduled actions."); - } + targetRepository.getAccessController().ifPresent(v -> { + if (targetRepository.count(AccessController.Operation.UPDATE, TargetSpecifications.hasIdIn(targetIds)) != targetIds.size()) { + throw new EntityNotFoundException(Target.class, targetIds); + } + }); + actionRepository.switchStatus(Status.CANCELED, targetIds, false, Status.SCHEDULED); } @Override @@ -668,12 +664,10 @@ private List validateAndFilterRequestForAssignments(List deploymentRequests) { - if (!isMultiAssignmentsEnabled()) { - final long distinctTargetsInRequest = deploymentRequests.stream() - .map(request -> request.getTargetWithActionType().getControllerId()).distinct().count(); - if (distinctTargetsInRequest < deploymentRequests.size()) { - throw new MultiAssignmentIsNotEnabledException(); - } + final long distinctTargetsInRequest = deploymentRequests.stream() + .map(request -> request.getTargetWithActionType().getControllerId()).distinct().count(); + if (distinctTargetsInRequest < deploymentRequests.size()) { + throw new MultiAssignmentException(); } } @@ -819,9 +813,7 @@ private List doAssignDistributionSetToTargets( final List targetEntities) { final List> targetEntitiesIdsChunks = getTargetEntitiesAsChunks(targetEntities); - if (!isMultiAssignmentsEnabled()) { - closeOrCancelActiveActions(assignmentStrategy, targetEntitiesIdsChunks); - } + closeOrCancelActiveActions(assignmentStrategy, targetEntitiesIdsChunks); // cancel all scheduled actions which are in-active, these actions were // not active before and the manual assignment which has been done cancels them targetEntitiesIdsChunks.forEach(this::cancelInactiveScheduledActionsForTargets); @@ -944,10 +936,6 @@ private void detachEntitiesAndSendTargetUpdatedEvents(final JpaDistributionSet s } private JpaAction closeActionIfSetWasAlreadyAssigned(final JpaAction action) { - if (isMultiAssignmentsEnabled()) { - return action; - } - final JpaTarget target = action.getTarget(); if (target.getAssignedDistributionSet() != null && action.getDistributionSet().getId() .equals(target.getAssignedDistributionSet().getId())) { @@ -965,9 +953,7 @@ private JpaAction closeActionIfSetWasAlreadyAssigned(final JpaAction action) { } private List startScheduledActionsAndHandleOpenCancellationFirst(final List actions) { - if (!isMultiAssignmentsEnabled()) { - closeOrCancelOpenDeviceActions(actions); - } + closeOrCancelOpenDeviceActions(actions); final List savedActions = activateActionsOfRolloutGroup(actions); setInitialActionStatusOfRolloutGroup(savedActions); setAssignmentOnTargets(savedActions); @@ -1017,10 +1003,6 @@ private void setSkipActionStatus(final JpaAction action) { actionStatusRepository.save(actionStatus); } - private boolean isMultiAssignmentsEnabled() { - return TenantConfigHelper.isMultiAssignmentsEnabled(); - } - private boolean isConfirmationFlowEnabled() { return TenantConfigHelper.isUserConfirmationFlowEnabled(); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java index 5f286ed793..c4ea020a0f 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaRolloutManagement.java @@ -167,7 +167,7 @@ protected JpaRolloutManagement( this.repositoryProperties = repositoryProperties; onlineDsAssignmentStrategy = new OnlineDsAssignmentStrategy(targetRepository, actionRepository, actionStatusRepository, - quotaManagement, this::isMultiAssignmentsEnabled, this::isConfirmationFlowEnabled, repositoryProperties, null); + quotaManagement, this::isConfirmationFlowEnabled, repositoryProperties, null); } @Autowired @@ -554,7 +554,7 @@ private void softCancelActionsOfRollout(final Rollout rollout) { storeActionsAndStatuses(actions, Action.Status.CANCELING); // send cancellation messages to event publisher - onlineDsAssignmentStrategy.sendCancellationMessages(actions, AccessContext.tenant()); + onlineDsAssignmentStrategy.sendCancellationMessages(actions); } private void forceQuitActionsOfRollout(final Rollout rollout) { @@ -1033,10 +1033,6 @@ private TargetCount calculateTargets(final String targetFilter, final Long creat return new TargetCount(totalTargets, baseFilter); } - private boolean isMultiAssignmentsEnabled() { - return TenantConfigHelper.isMultiAssignmentsEnabled(); - } - private boolean isConfirmationFlowEnabled() { return TenantConfigHelper.isUserConfirmationFlowEnabled(); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java index a0511d0f32..5bc8dcbdff 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/JpaTenantConfigurationManagement.java @@ -11,8 +11,6 @@ import static org.eclipse.hawkbit.auth.SpPermission.READ_GATEWAY_SECURITY_TOKEN; import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.AUTHENTICATION_GATEWAY_SECURITY_TOKEN_KEY; -import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.BATCH_ASSIGNMENTS_ENABLED; -import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.MULTI_ASSIGNMENTS_ENABLED; import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.POLLING_TIME; import static org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationProperties.TenantConfigurationKey.REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED; @@ -207,7 +205,6 @@ private void addOrUpdateConfiguration0(final Map configurations) tenantConfiguration.setValue(valueToString); } - assertValueChangeIsAllowed(e.getKey(), tenantConfiguration); return tenantConfiguration; }).toList()); } @@ -273,58 +270,6 @@ private T getGlobalConfigurationValue0(final String keyName, final Class return CONVERSION_SERVICE.convert(key.getDefaultValue(), propertyType); } - /** - * Asserts that the requested configuration value change is allowed. Throws a {@link TenantConfigurationValueChangeNotAllowedException} - * otherwise. - * - * @param key The configuration key. - * @param valueChange The configuration to be validated. - * @throws TenantConfigurationValueChangeNotAllowedException if the requested configuration change is not allowed. - */ - private void assertValueChangeIsAllowed(final String key, final JpaTenantConfiguration valueChange) { - assertMultiAssignmentsValueChange(key, valueChange); - assertAutoCloseValueChange(key); - assertBatchAssignmentValueChange(key, valueChange); - } - - private void assertMultiAssignmentsValueChange(final String key, final JpaTenantConfiguration valueChange) { - if (MULTI_ASSIGNMENTS_ENABLED.equals(key) && !Boolean.parseBoolean(valueChange.getValue())) { - log.debug("The Multi-Assignments '{}' feature cannot be disabled.", key); - throw new TenantConfigurationValueChangeNotAllowedException(); - } - if (MULTI_ASSIGNMENTS_ENABLED.equals(key) && Boolean.parseBoolean(valueChange.getValue())) { - JpaTenantConfiguration batchConfig = tenantConfigurationRepository.findByKey(BATCH_ASSIGNMENTS_ENABLED); - if (batchConfig != null && Boolean.parseBoolean(batchConfig.getValue())) { - log.debug( - "The Multi-Assignments '{}' feature cannot be enabled as it contradicts with the Batch-Assignments feature, which is already enabled .", - key); - throw new TenantConfigurationValueChangeNotAllowedException(); - } - } - } - - private void assertAutoCloseValueChange(final String key) { - if (REPOSITORY_ACTIONS_AUTOCLOSE_ENABLED.equals(key) - && Boolean.TRUE.equals(Optional.ofNullable(getConfigurationValue0(MULTI_ASSIGNMENTS_ENABLED, Boolean.class)) - .map(TenantConfigurationValue::getValue) - .orElse(null))) { - log.debug("The property '{}' must not be changed because the Multi-Assignments feature is currently enabled.", key); - throw new TenantConfigurationValueChangeNotAllowedException(); - } - } - - private void assertBatchAssignmentValueChange(final String key, final JpaTenantConfiguration valueChange) { - if (BATCH_ASSIGNMENTS_ENABLED.equals(key) && Boolean.parseBoolean(valueChange.getValue())) { - final JpaTenantConfiguration multiConfig = tenantConfigurationRepository.findByKey(MULTI_ASSIGNMENTS_ENABLED); - if (multiConfig != null && Boolean.parseBoolean(multiConfig.getValue())) { - log.debug( - "The Batch-Assignments '{}' feature cannot be enabled as it contradicts with the Multi-Assignments feature, which is already enabled .", - key); - throw new TenantConfigurationValueChangeNotAllowedException(); - } - } - } - private static PollStatus pollStatus(final long lastTargetQuery, final PollingInterval pollingInterval, final Duration pollingOverdueTime) { final LocalDateTime currentDate = LocalDateTime.now(); final LocalDateTime lastPollDate = LocalDateTime.ofInstant(Instant.ofEpochMilli(lastTargetQuery), ZoneId.systemDefault()); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/OfflineDsAssignmentStrategy.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/OfflineDsAssignmentStrategy.java index 420242179f..fd44d08b92 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/OfflineDsAssignmentStrategy.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/OfflineDsAssignmentStrategy.java @@ -46,11 +46,11 @@ class OfflineDsAssignmentStrategy extends AbstractDsAssignmentStrategy { OfflineDsAssignmentStrategy( final TargetRepository targetRepository, final ActionRepository actionRepository, final ActionStatusRepository actionStatusRepository, - final QuotaManagement quotaManagement, final BooleanSupplier multiAssignmentsConfig, + final QuotaManagement quotaManagement, final BooleanSupplier confirmationFlowConfig, final RepositoryProperties repositoryProperties, final Consumer maxAssignmentExceededHandler) { super(targetRepository, actionRepository, actionStatusRepository, - quotaManagement, multiAssignmentsConfig, confirmationFlowConfig, repositoryProperties, maxAssignmentExceededHandler); + quotaManagement, confirmationFlowConfig, repositoryProperties, maxAssignmentExceededHandler); } @Override @@ -74,14 +74,11 @@ public JpaActionStatus createActionStatus(final JpaAction action, final String a @Override public List findTargetsForAssignment(final List controllerIDs, final long setId) { - final Function, List> mapper; - if (isMultiAssignmentsEnabled()) { - mapper = ids -> targetRepository.findAll(TargetSpecifications.hasControllerIdIn(ids)); - } else { - mapper = ids -> targetRepository.findAll(JpaManagementHelper.combineWithAnd(List.of( - TargetSpecifications.hasControllerIdAndAssignedDistributionSetIdNot(ids, setId), - TargetSpecifications.notEqualToTargetUpdateStatus(TargetUpdateStatus.PENDING)))); - } + final Function, List> mapper = + ids -> targetRepository.findAll(JpaManagementHelper.combineWithAnd(List.of( + TargetSpecifications.hasControllerIdAndAssignedDistributionSetIdNot(ids, setId), + TargetSpecifications.notEqualToTargetUpdateStatus(TargetUpdateStatus.PENDING)))); + return ListUtils.partition(controllerIDs, Constants.MAX_ENTRIES_IN_STATEMENT).stream().map(mapper).flatMap(List::stream).toList(); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/OnlineDsAssignmentStrategy.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/OnlineDsAssignmentStrategy.java index f753f1d987..ce18d04a89 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/OnlineDsAssignmentStrategy.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/management/OnlineDsAssignmentStrategy.java @@ -23,8 +23,6 @@ import org.eclipse.hawkbit.repository.QuotaManagement; import org.eclipse.hawkbit.repository.RepositoryProperties; import org.eclipse.hawkbit.repository.event.EventPublisherHolder; -import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.exception.InsufficientPermissionException; import org.eclipse.hawkbit.repository.jpa.acm.AccessController; @@ -54,19 +52,14 @@ class OnlineDsAssignmentStrategy extends AbstractDsAssignmentStrategy { OnlineDsAssignmentStrategy( final TargetRepository targetRepository, final ActionRepository actionRepository, final ActionStatusRepository actionStatusRepository, - final QuotaManagement quotaManagement, final BooleanSupplier multiAssignmentsConfig, + final QuotaManagement quotaManagement, final BooleanSupplier confirmationFlowConfig, final RepositoryProperties repositoryProperties, final Consumer maxAssignmentExceededHandler) { super(targetRepository, actionRepository, actionStatusRepository, - quotaManagement, multiAssignmentsConfig, confirmationFlowConfig, repositoryProperties, maxAssignmentExceededHandler); + quotaManagement, confirmationFlowConfig, repositoryProperties, maxAssignmentExceededHandler); } public void sendDeploymentEvents(final long distributionSetId, final List actions) { - if (isMultiAssignmentsEnabled()) { - sendDeploymentEvent(actions); - return; - } - final List filteredActions = getActionsWithoutCancellations(actions); if (filteredActions.isEmpty()) { return; @@ -106,13 +99,9 @@ public JpaActionStatus createActionStatus(final JpaAction action, final String a @Override public List findTargetsForAssignment(final List controllerIDs, final long setId) { - final Function, List> mapper; - if (isMultiAssignmentsEnabled()) { - mapper = ids -> targetRepository.findAll(TargetSpecifications.hasControllerIdIn(ids)); - } else { - mapper = ids -> targetRepository - .findAll(TargetSpecifications.hasControllerIdAndAssignedDistributionSetIdNot(ids, setId)); - } + final Function, List> mapper = + ids -> targetRepository.findAll( + TargetSpecifications.hasControllerIdAndAssignedDistributionSetIdNot(ids, setId)); return ListUtils.partition(controllerIDs, Constants.MAX_ENTRIES_IN_STATEMENT).stream().map(mapper) .flatMap(List::stream).toList(); } @@ -163,27 +152,15 @@ public void closeActiveActions(final List> targetIds) { @Override public void sendDeploymentEvents(final List assignmentResults) { - if (isMultiAssignmentsEnabled()) { - sendDeploymentEvent(assignmentResults.stream().flatMap(result -> result.getAssignedEntity().stream()).toList()); - } else { - assignmentResults.forEach(this::sendDistributionSetAssignedEvent); - } + assignmentResults.forEach(this::sendDistributionSetAssignedEvent); } void sendCancellationMessage(final JpaAction action) { - if (isMultiAssignmentsEnabled()) { - sendMultiActionCancelEvent(action); - } else { - cancelAssignDistributionSetEvent(action); - } + cancelAssignDistributionSetEvent(action); } - void sendCancellationMessages(final List actions, final String tenant) { - if (isMultiAssignmentsEnabled()) { - sendMultiActionCancelEvent(tenant, Collections.unmodifiableList(actions)); - } else { - actions.forEach(this::cancelAssignDistributionSetEvent); - } + void sendCancellationMessages(final List actions) { + actions.forEach(this::cancelAssignDistributionSetEvent); } private static Stream filterCancellations(final List actions) { @@ -200,19 +177,6 @@ private static List getActionsWithoutCancellations(final List ac return filterCancellations(actions).toList(); } - private void sendMultiActionCancelEvent(final Action action) { - sendMultiActionCancelEvent(action.getTenant(), Collections.singletonList(action)); - } - - private void sendDeploymentEvent(final List actions) { - final List filteredActions = getActionsWithoutCancellations(actions); - if (filteredActions.isEmpty()) { - return; - } - final String tenant = filteredActions.get(0).getTenant(); - sendMultiActionAssignEvent(tenant, filteredActions); - } - private void sendDistributionSetAssignedEvent(final DistributionSetAssignmentResult assignmentResult) { final List filteredActions = filterCancellations(assignmentResult.getAssignedEntity()).toList(); final DistributionSet set = assignmentResult.getDistributionSet(); @@ -228,25 +192,4 @@ private void sendTargetAssignDistributionSetEvent(final String tenant, final lon afterCommit(() -> EventPublisherHolder.getInstance().getEventPublisher().publishEvent( new TargetAssignDistributionSetEvent(tenant, distributionSetId, actions, actions.get(0).isMaintenanceWindowAvailable()))); } - - /** - * Helper to fire a {@link MultiActionCancelEvent}. This method may only be - * called if the Multi-Assignments feature is enabled. - * - * @param tenant the event is scoped to - * @param actions assigned to the targets - */ - private void sendMultiActionCancelEvent(final String tenant, final List actions) { - afterCommit(() -> EventPublisherHolder.getInstance().getEventPublisher().publishEvent(new MultiActionCancelEvent(tenant, actions))); - } - - /** - * Helper to fire a {@link MultiActionAssignEvent}. This method may only be called if the Multi-Assignments feature is enabled. - * - * @param tenant the event is scoped to - * @param actions assigned to the targets - */ - private void sendMultiActionAssignEvent(final String tenant, final List actions) { - afterCommit(() -> EventPublisherHolder.getInstance().getEventPublisher().publishEvent(new MultiActionAssignEvent(tenant, actions))); - } } \ No newline at end of file diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/utils/WeightValidationHelper.java b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/utils/WeightValidationHelper.java index baca08f65f..c516c081be 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/utils/WeightValidationHelper.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/main/java/org/eclipse/hawkbit/repository/jpa/utils/WeightValidationHelper.java @@ -84,8 +84,7 @@ public static void validateWeight(final Integer weight) { public static void validateWeight(final boolean hasWeight, final boolean hasNoWeight) { // remove bypassing the weight enforcement as soon as weight can be set via UI final boolean bypassWeightEnforcement = true; - final boolean multiAssignmentsEnabled = TenantConfigHelper.isMultiAssignmentsEnabled(); - if (!bypassWeightEnforcement && multiAssignmentsEnabled && hasNoWeight) { + if (!bypassWeightEnforcement && hasNoWeight) { throw new NoWeightProvidedInMultiAssignmentModeException(); } } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantEventTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantEventTest.java index 07c7a25a6a..ba88beeb6e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantEventTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/RemoteTenantEventTest.java @@ -30,44 +30,6 @@ class RemoteTenantEventTest extends AbstractRemoteEventTest { private static final String TENANT_DEFAULT = "DEFAULT"; - /** - * Verifies that a testMultiActionAssignEvent can be properly serialized and deserialized - */ - @Test - void testMultiActionAssignEvent() { - final List controllerIds = List.of("id0", "id1", "id2", "id3", "id4loooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnng"); - final List actions = controllerIds.stream().map(this::createAction).toList(); - - final MultiActionAssignEvent assignEvent = new MultiActionAssignEvent(TENANT_DEFAULT, actions); - - final MultiActionAssignEvent remoteAssignEventProtoStuff = createProtoStuffEvent(assignEvent); - assertThat(assignEvent).isEqualTo(remoteAssignEventProtoStuff); - assertThat(remoteAssignEventProtoStuff.getControllerIds()).containsExactlyElementsOf(controllerIds); - - final MultiActionAssignEvent remoteAssignEventJackson = createJacksonEvent(assignEvent); - assertThat(assignEvent).isEqualTo(remoteAssignEventJackson); - assertThat(remoteAssignEventJackson.getControllerIds()).containsExactlyElementsOf(controllerIds); - } - - /** - * Verifies that a MultiActionCancelEvent can be properly serialized and deserialized - */ - @Test - void testMultiActionCancelEvent() { - final List controllerIds = List.of("id0", "id1", "id2", "id3", "id4loooooooooooooooooooooooooooooooooooonnnnnnnnnnnnnnnnnng"); - final List actions = controllerIds.stream().map(this::createAction).toList(); - - final MultiActionCancelEvent cancelEvent = new MultiActionCancelEvent(TENANT_DEFAULT, actions); - - final MultiActionCancelEvent remoteCancelEventProtoStuff = createProtoStuffEvent(cancelEvent); - assertThat(cancelEvent).isEqualTo(remoteCancelEventProtoStuff); - assertThat(remoteCancelEventProtoStuff.getControllerIds()).containsExactlyElementsOf(controllerIds); - - final MultiActionCancelEvent remoteCancelEventJackson = createJacksonEvent(cancelEvent); - assertThat(cancelEvent).isEqualTo(remoteCancelEventJackson); - assertThat(remoteCancelEventJackson.getControllerIds()).containsExactlyElementsOf(controllerIds); - } - /** * Verifies that a DownloadProgressEvent can be properly serialized and deserialized */ @@ -135,15 +97,6 @@ void testCancelTargetAssignmentEvent() { assertCancelTargetAssignmentEvent(action, remoteEventJackson); } - private Action createAction(final String controllerId) { - final JpaAction generateAction = new JpaAction(); - generateAction.setId(1L); - generateAction.setActionType(ActionType.FORCED); - generateAction.setTarget(testdataFactory.createTarget(controllerId)); - generateAction.setStatus(Status.RUNNING); - return generateAction; - } - private void assertTargetAssignDistributionSetEvent(final Action action, final TargetAssignDistributionSetEvent underTest) { assertThat(underTest.getActions()).hasSize(1); final ActionProperties actionProperties = underTest.getActions().get(action.getTarget().getControllerId()); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/ServiceEventsTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/ServiceEventsTest.java index ff2ed73af2..a228c08b11 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/ServiceEventsTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/event/remote/ServiceEventsTest.java @@ -16,7 +16,6 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import java.util.List; import java.util.Set; import org.eclipse.hawkbit.repository.event.EventPublisherHolder; @@ -25,7 +24,6 @@ import org.eclipse.hawkbit.repository.event.remote.entity.TargetCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.service.CancelTargetAssignmentServiceEvent; -import org.eclipse.hawkbit.repository.event.remote.service.MultiActionAssignServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistributionSetServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetAttributesRequestedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetCreatedServiceEvent; @@ -79,8 +77,6 @@ void testExpectedServiceEvents(){ TargetAssignDistributionSetEvent.class, CancelTargetAssignmentEvent.class, TargetAttributesRequestedEvent.class, - MultiActionAssignEvent.class, - MultiActionCancelEvent.class, ActionCreatedEvent.class, ActionUpdatedEvent.class ); @@ -124,16 +120,6 @@ void testProcessingTargetAttributesRequestedEventIsSent() { verify(streamBridge).send(eq("group"), any(TargetAttributesRequestedServiceEvent.class)); } - @Test - void testProcessingMultiActionAssignmentEventIsSent() { - MultiActionAssignEvent event = new MultiActionAssignEvent("testtenant", List.of(mockAction())); - - publisher.publishEvent(event); - - verify(streamBridge).send("fanout", event); - verify(streamBridge).send(eq("group"), any(MultiActionAssignServiceEvent.class)); - } - @Test void testCancelTargetAssignmentEventIsSent() { CancelTargetAssignmentEvent event = new CancelTargetAssignmentEvent(mockAction()); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ConfirmationManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ConfirmationManagementTest.java index 0254367e97..a4b6ecc7e4 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ConfirmationManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ConfirmationManagementTest.java @@ -64,37 +64,6 @@ void retrieveActionsWithConfirmationState() { .allMatch(action -> action.getStatus() == Status.WAIT_FOR_CONFIRMATION); } - /** - * Verify 'findActiveActionsWaitingConfirmation' method is filtering like expected with multi assignment active - */ - @Test - void retrieveActionsWithConfirmationStateInMultiAssignment() { - enableMultiAssignments(); - enableConfirmationFlow(); - - final String controllerId = testdataFactory.createTarget().getControllerId(); - final Long dsId = testdataFactory.createDistributionSet().getId(); - - final List actions = assignDistributionSet(dsId, controllerId).getAssignedEntity(); - assertThat(actions).hasSize(1); - - assertThat(confirmationManagement.findActiveActionsWaitingConfirmation(controllerId)).hasSize(1) - .allMatch(action -> action.getStatus() == Status.WAIT_FOR_CONFIRMATION); - - final Long dsId2 = testdataFactory.createDistributionSet().getId(); - assignDistributionSet(dsId2, controllerId); - - assertThat(confirmationManagement.findActiveActionsWaitingConfirmation(controllerId)).hasSize(2) - .allMatch(action -> action.getStatus() == Status.WAIT_FOR_CONFIRMATION); - - confirmationManagement.confirmAction(actions.get(0).getId(), null, null); - - assertThat(confirmationManagement.findActiveActionsWaitingConfirmation(controllerId)).hasSize(1) - .allMatch(action -> action.getStatus() == Status.WAIT_FOR_CONFIRMATION - && Objects.equals(action.getDistributionSet().getId(), dsId2)); - - } - /** * Verify confirming an action will put it to the running state */ @@ -191,34 +160,6 @@ void deniedActionWillStayInWfcState() { .noneMatch(status -> status.getStatus() == Status.RUNNING); } - /** - * Verify multiple actions in WFC state will be transferred in RUNNING state in case auto-confirmation is activated. - */ - @Test - void activateAutoConfirmationInMultiAssignment() { - enableMultiAssignments(); - enableConfirmationFlow(); - - final String controllerId = testdataFactory.createTarget().getControllerId(); - final Long dsId = testdataFactory.createDistributionSet().getId(); - final Long dsId2 = testdataFactory.createDistributionSet().getId(); - - final List actions = assignDistributionSets( - Arrays.asList(toDeploymentRequest(controllerId, dsId), toDeploymentRequest(controllerId, dsId2))) - .stream().flatMap(s -> s.getAssignedEntity().stream()).toList(); - assertThat(actions).hasSize(2); - - assertThat(confirmationManagement.findActiveActionsWaitingConfirmation(controllerId)).hasSize(2) - .allMatch(action -> action.getStatus() == Status.WAIT_FOR_CONFIRMATION); - - confirmationManagement.activateAutoConfirmation(controllerId, null, null); - - assertThat(confirmationManagement.findActiveActionsWaitingConfirmation(controllerId)).isEmpty(); - - assertThat(deploymentManagement.findActionsByTarget(controllerId, PAGE).getContent()).hasSize(2) - .allMatch(action -> action.getStatus() == Status.RUNNING); - } - /** * Verify action in WFC state will be transferred in RUNNING state in case auto-confirmation is activated. */ @@ -324,10 +265,6 @@ private static Stream getAutoConfirmationArguments() { Arguments.of(null, null)); } - private static DeploymentRequest toDeploymentRequest(final String controllerId, final Long distributionSetId) { - return DeploymentRequest.builder(controllerId, distributionSetId).confirmationRequired(true).build(); - } - private void verifyAutoConfirmationIsDisabled(final String controllerId) { assertThat(targetManagement.getWithAutoConfigurationStatus(controllerId).getAutoConfirmationStatus()).isNull(); } diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java index d3466a5928..a20efc93ac 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/ControllerManagementTest.java @@ -1582,41 +1582,6 @@ void controllerReportsFinishedForOldDownloadOnlyActionAfterSuccessfulForcedAssig assertNoActiveActionsExistsForControllerId(DEFAULT_CONTROLLER_ID); } - /** - * Actions are exposed according to thier weight in multi assignment mode. - */ - @Test - void actionsAreExposedAccordingToTheirWeight() { - final String targetId = testdataFactory.createTarget().getControllerId(); - final DistributionSet ds = testdataFactory.createDistributionSet(); - final Long actionWeightNull = assignDistributionSet(ds.getId(), targetId).getAssignedEntity().get(0).getId(); - enableMultiAssignments(); - final Long actionWeight500old = assignDistributionSet(ds.getId(), targetId, 500).getAssignedEntity().get(0) - .getId(); - final Long actionWeight500new = assignDistributionSet(ds.getId(), targetId, 500).getAssignedEntity().get(0) - .getId(); - final Long actionWeight1000 = assignDistributionSet(ds.getId(), targetId, 1000).getAssignedEntity().get(0) - .getId(); - - assertThat(controllerManagement.findActiveActionWithHighestWeight(targetId).get().getId()) - .isEqualTo(actionWeightNull); - controllerManagement - .addUpdateActionStatus(ActionStatusCreate.builder().actionId(actionWeightNull).status(Status.FINISHED).build()); - assertThat(controllerManagement.findActiveActionWithHighestWeight(targetId).get().getId()) - .isEqualTo(actionWeight1000); - controllerManagement - .addUpdateActionStatus(ActionStatusCreate.builder().actionId(actionWeight1000).status(Status.FINISHED).build()); - assertThat(controllerManagement.findActiveActionWithHighestWeight(targetId).get().getId()) - .isEqualTo(actionWeight500old); - controllerManagement - .addUpdateActionStatus(ActionStatusCreate.builder().actionId(actionWeight500old).status(Status.FINISHED).build()); - assertThat(controllerManagement.findActiveActionWithHighestWeight(targetId).get().getId()) - .isEqualTo(actionWeight500new); - controllerManagement - .addUpdateActionStatus(ActionStatusCreate.builder().actionId(actionWeight500new).status(Status.FINISHED).build()); - assertThat(controllerManagement.findActiveActionWithHighestWeight(targetId)).isEmpty(); - } - /** * Delete a target on requested target deletion from client side */ diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java index 13de6403e9..c4c8b8d29e 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/DeploymentManagementTest.java @@ -37,8 +37,6 @@ import org.eclipse.hawkbit.repository.DistributionSetTagManagement; import org.eclipse.hawkbit.repository.Identifiable; import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; import org.eclipse.hawkbit.repository.event.remote.entity.ActionCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.ActionUpdatedEvent; @@ -50,13 +48,18 @@ import org.eclipse.hawkbit.repository.event.remote.entity.TargetUpdatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationCreatedEvent; import org.eclipse.hawkbit.repository.event.remote.entity.TenantConfigurationUpdatedEvent; +import org.eclipse.hawkbit.repository.event.remote.service.ActionCreatedServiceEvent; +import org.eclipse.hawkbit.repository.event.remote.service.ActionUpdatedServiceEvent; +import org.eclipse.hawkbit.repository.event.remote.service.CancelTargetAssignmentServiceEvent; +import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistributionSetServiceEvent; +import org.eclipse.hawkbit.repository.event.remote.service.TargetUpdatedServiceEvent; import org.eclipse.hawkbit.repository.exception.AssignmentQuotaExceededException; import org.eclipse.hawkbit.repository.exception.EntityNotFoundException; import org.eclipse.hawkbit.repository.exception.ForceQuitActionNotAllowedException; import org.eclipse.hawkbit.repository.exception.IncompatibleTargetTypeException; import org.eclipse.hawkbit.repository.exception.IncompleteDistributionSetException; import org.eclipse.hawkbit.repository.exception.InvalidDistributionSetException; -import org.eclipse.hawkbit.repository.exception.MultiAssignmentIsNotEnabledException; +import org.eclipse.hawkbit.repository.exception.MultiAssignmentException; import org.eclipse.hawkbit.repository.jpa.AbstractJpaIntegrationTest; import org.eclipse.hawkbit.repository.jpa.model.JpaAction; import org.eclipse.hawkbit.repository.jpa.model.JpaActionStatus; @@ -208,19 +211,22 @@ void findActionByTargetId() { */ @Test void assertMaxActionsPerTargetQuotaIsEnforced() { - enableMultiAssignments(); final int maxActions = quotaManagement.getMaxActionsPerTarget(); final Target testTarget = testdataFactory.createTarget(); - final Long ds1Id = testdataFactory.createDistributionSet("ds1").getId(); + final List dsIds = new ArrayList<>(); + for (int i = 0; i < maxActions; i++) { + dsIds.add(testdataFactory.createDistributionSet("ds" + i).getId()); + } final String controllerId = testTarget.getControllerId(); for (int i = 0; i < maxActions; i++) { - deploymentManagement.offlineAssignedDistributionSets(List.of(new SimpleEntry<>(controllerId, ds1Id))); + deploymentManagement.offlineAssignedDistributionSets(List.of(new SimpleEntry<>(controllerId, dsIds.get(i)))); } + final long dsIdThatShouldNotBeAssigned = testdataFactory.createDistributionSet("shouldNotBeAssigned").getId(); assertThatExceptionOfType(AssignmentQuotaExceededException.class) - .isThrownBy(() -> assignDistributionSet(ds1Id, controllerId, 77)); + .isThrownBy(() -> assignDistributionSet(dsIdThatShouldNotBeAssigned, controllerId, 77)); } /** @@ -539,44 +545,6 @@ void assignedDistributionSet() { .allMatch(target -> target.getLastModifiedAt() == target.getInstallationDate()); } - /** - * Offline assign multiple DSs to a single Target in multiassignment mode. - */ - @Test - @ExpectEvents({ - @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = TargetUpdatedEvent.class, count = 4), - @Expect(type = ActionCreatedEvent.class, count = 4), - @Expect(type = DistributionSetCreatedEvent.class, count = 4), - @Expect(type = SoftwareModuleCreatedEvent.class, count = 12), - @Expect(type = DistributionSetUpdatedEvent.class, count = 4), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 12), // implicit lock - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) - void multiOfflineAssignment() { - final List targetIds = testdataFactory.createTargets(1).stream().map(Target::getControllerId).toList(); - final List dsIds = testdataFactory.createDistributionSets(4).stream().map(DistributionSet::getId).toList(); - - enableMultiAssignments(); - final List> offlineAssignments = new ArrayList<>(); - targetIds.forEach(targetId -> dsIds.forEach(dsId -> offlineAssignments.add(new SimpleEntry<>(targetId, dsId)))); - final List assignmentResults = deploymentManagement - .offlineAssignedDistributionSets(offlineAssignments); - - assertThat(getResultingActionCount(assignmentResults)).isEqualTo(4); - targetIds.forEach(controllerId -> { - final List assignedDsIds = deploymentManagement.findActionsByTarget(controllerId, PAGE).stream() - .map(a -> { - // don't use peek since it is by documentation mainly for debugging and could be skipped in some cases - assertThat(a.getInitiatedBy()) - .as("Actions should be initiated by current user") - .isEqualTo(AccessContext.actor()); - return a; - }) - .map(action -> action.getDistributionSet().getId()).toList(); - assertThat(assignedDsIds).containsExactlyInAnyOrderElementsOf(dsIds); - }); - } - /** * Verifies that if an account is set to action autoclose running actions in case of a new assigned set get closed and set to CANCELED. */ @@ -620,118 +588,11 @@ void assignDistributionSetAndAutoCloseActiveActions() { } } - /** - * If multi-assignment is enabled, verify that the previous Distribution Set assignment is not canceled when a new one is assigned. - */ - @Test - @ExpectEvents({ - @Expect(type = TargetCreatedEvent.class, count = 10), - @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 = DistributionSetUpdatedEvent.class, count = 2), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock - @Expect(type = MultiActionAssignEvent.class, count = 2), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) - void previousAssignmentsAreNotCanceledInMultiAssignMode() { - enableMultiAssignments(); - final List targets = testdataFactory.createTargets(10); - final List targetIds = targets.stream().map(Target::getControllerId).toList(); - - // First assignment - final DistributionSet ds1 = testdataFactory.createDistributionSet("Multi-assign-1"); - assignDistributionSet(ds1.getId(), targetIds, 77); - - assertDsExclusivelyAssignedToTargets(targets, ds1.getId(), STATE_ACTIVE, RUNNING); - - // Second assignment - final DistributionSet ds2 = testdataFactory.createDistributionSet("Multi-assign-2"); - assignDistributionSet(ds2.getId(), targetIds, 45); - - assertDsExclusivelyAssignedToTargets(targets, ds2.getId(), STATE_ACTIVE, RUNNING); - assertDsExclusivelyAssignedToTargets(targets, ds1.getId(), STATE_ACTIVE, RUNNING); - } - - /** - * Assign multiple DSs to a single Target in one request in multiassignment mode. - */ - @Test - @ExpectEvents({ - @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = TargetUpdatedEvent.class, count = 4), - @Expect(type = ActionCreatedEvent.class, count = 4), - @Expect(type = DistributionSetCreatedEvent.class, count = 4), - @Expect(type = SoftwareModuleCreatedEvent.class, count = 12), - @Expect(type = DistributionSetUpdatedEvent.class, count = 4), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 12), // implicit lock - @Expect(type = MultiActionAssignEvent.class, count = 1), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) - void multiAssignmentInOneRequest() { - final List targets = testdataFactory.createTargets(1); - final List distributionSets = testdataFactory.createDistributionSets(4); - final List deploymentRequests = createAssignmentRequests(distributionSets, targets, 34); - - enableMultiAssignments(); - final List results = deploymentManagement.assignDistributionSets(deploymentRequests, null); - - assertThat(getResultingActionCount(results)).isEqualTo(deploymentRequests.size()); - final List dsIds = distributionSets.stream().map(DistributionSet::getId).toList(); - targets.forEach(target -> { - final List assignedDsIds = deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE) - .stream() - .map(a -> { - // don't use peek since it is by documentation mainly for debugging and could be skipped in some cases - assertThat(a.getInitiatedBy()).as("Initiated by current user") - .isEqualTo(AccessContext.actor()); - return a; - }) - .map(action -> action.getDistributionSet().getId()).toList(); - assertThat(assignedDsIds).containsExactlyInAnyOrderElementsOf(dsIds); - }); - } - - /** - * Assign multiple DSs to single Target in one request in multiAssignment mode and cancel each created action afterwards. - */ - @Test - @ExpectEvents({ - @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = TargetUpdatedEvent.class, count = 4), - @Expect(type = ActionCreatedEvent.class, count = 4), - @Expect(type = DistributionSetCreatedEvent.class, count = 4), - @Expect(type = SoftwareModuleCreatedEvent.class, count = 12), - @Expect(type = DistributionSetUpdatedEvent.class, count = 4), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 12), // implicit lock - @Expect(type = MultiActionAssignEvent.class, count = 1), - @Expect(type = MultiActionCancelEvent.class, count = 4), - @Expect(type = ActionUpdatedEvent.class, count = 4), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) - void cancelMultiAssignmentActions() { - final List targets = testdataFactory.createTargets(1); - final List distributionSets = testdataFactory.createDistributionSets(4); - final List deploymentRequests = createAssignmentRequests(distributionSets, targets, 34, false); - - enableMultiAssignments(); - final List results = deploymentManagement.assignDistributionSets(deploymentRequests, null); - - assertThat(getResultingActionCount(results)).isEqualTo(deploymentRequests.size()); - - final List dsIds = distributionSets.stream().map(DistributionSet::getId).toList(); - targets.forEach(target -> - deploymentManagement.findActionsByTarget(target.getControllerId(), PAGE).forEach(action -> { - assertThat(action.getDistributionSet().getId()).isIn(dsIds); - assertThat(action.getInitiatedBy()) - .as("Should be Initiated by current user").isEqualTo(AccessContext.actor()); - deploymentManagement.cancelAction(action.getId()); - })); - } - /** * A Request resulting in multiple assignments to a single target is only allowed when multiassignment is enabled. */ @Test - void multipleAssignmentsToTargetOnlyAllowedInMultiAssignMode() { + void multipleAssignmentsToTargetNotAllowed() { final Target target = testdataFactory.createTarget(); final List distributionSets = testdataFactory.createDistributionSets(2); @@ -742,11 +603,9 @@ void multipleAssignmentsToTargetOnlyAllowedInMultiAssignMode() { .builder(target.getControllerId(), distributionSets.get(1).getId()).weight(565).build(); final List deploymentRequests = List.of(targetToDS0, targetToDS1); - Assertions.assertThatExceptionOfType(MultiAssignmentIsNotEnabledException.class) + Assertions.assertThatExceptionOfType(MultiAssignmentException.class) .isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests, null)); - enableMultiAssignments(); - assertThat(getResultingActionCount(deploymentManagement.assignDistributionSets(List.of(targetToDS0, targetToDS1), null))).isEqualTo(2); } /** @@ -912,77 +771,46 @@ void verifyConfirmationRequiredFlagHaveNoInfluenceIfFlowIsDeactivated() { })); } - /** - * Duplicate Assignments are removed from a request when multi-assignment is disabled, otherwise not - */ - @Test - @ExpectEvents({ - @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = DistributionSetCreatedEvent.class, count = 1), - @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), - @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock - @Expect(type = TargetAssignDistributionSetEvent.class, count = 1), - @Expect(type = ActionCreatedEvent.class, count = 2), - @Expect(type = TargetUpdatedEvent.class, count = 2), - @Expect(type = MultiActionAssignEvent.class, count = 1), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) - void duplicateAssignmentsInRequestAreRemovedIfMultiassignmentEnabled() { - final String targetId = testdataFactory.createTarget().getControllerId(); - final Long dsId = testdataFactory.createDistributionSet().getId(); - final List twoEqualAssignments = Collections.nCopies(2, DeploymentRequest.builder(targetId, dsId).build()); - assertThat(getResultingActionCount(deploymentManagement.assignDistributionSets(twoEqualAssignments, null))).isEqualTo(1); - - enableMultiAssignments(); - final List twoEqualAssignmentsWithWeight = Collections.nCopies( - 2, DeploymentRequest.builder(targetId, dsId).weight(555).build()); - - assertThat(getResultingActionCount(deploymentManagement.assignDistributionSets(twoEqualAssignmentsWithWeight, null))).isEqualTo(1); - } - /** * An assignment request is not accepted if it would lead to a target exceeding the max actions per target quota. */ @Test @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1), + @Expect(type = TargetUpdatedEvent.class, count = 20), + @Expect(type = TargetUpdatedServiceEvent.class, count = 20), + @Expect(type = TargetAssignDistributionSetEvent.class, count = 20), + @Expect(type = CancelTargetAssignmentEvent.class, count = 19), + @Expect(type = CancelTargetAssignmentServiceEvent.class, count = 19), @Expect(type = DistributionSetCreatedEvent.class, count = 21), // max actions per target are 20 for test + @Expect(type = DistributionSetUpdatedEvent.class, count = 20), @Expect(type = SoftwareModuleCreatedEvent.class, count = 3 * 21), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) + @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3 * 20), + @Expect(type = ActionUpdatedEvent.class, count = 19), + @Expect(type = ActionCreatedEvent.class, count = 20), + @Expect(type = ActionCreatedServiceEvent.class, count = 20), + @Expect(type = TargetAssignDistributionSetEvent.class, count = 20), + }) void maxActionsPerTargetIsCheckedBeforeAssignmentExecution() { final int maxActions = quotaManagement.getMaxActionsPerTarget(); assertThat(maxActions) .as("Expect 20 as maxActionPerTarget. If not the case change @Expect counts for " + "DistributionSetCreatedEvent and SoftwareModuleCreatedEvent accordingly!") .isEqualTo(20); - final int size = maxActions + 1; + final String controllerId = testdataFactory.createTarget().getControllerId(); - final List deploymentRequests = new ArrayList<>(); - for (int i = 0; i < size; i++) { + for (int i = 0; i < maxActions; i++) { final Long dsId = testdataFactory.createDistributionSet().getId(); - deploymentRequests.add(DeploymentRequest.builder(controllerId, dsId).weight(24).build()); + deploymentManagement.assignDistributionSets( + List.of(DeploymentRequest.builder(controllerId, dsId).weight(24).build()), null); } - enableMultiAssignments(); + final Long dsId = testdataFactory.createDistributionSet().getId(); + final List deploymentRequests = List.of(DeploymentRequest.builder(controllerId, dsId).weight(24).build()); Assertions.assertThatExceptionOfType(AssignmentQuotaExceededException.class) .isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequests, null)); - assertThat(actionRepository.countByTargetControllerId(controllerId)).isZero(); - } - - /** - * An assignment request without a weight is ok when multi assignment in enabled. - */ - @Test - void weightNotRequiredInMultiAssignmentMode() { - final String targetId = testdataFactory.createTarget().getControllerId(); - final Long dsId = testdataFactory.createDistributionSet().getId(); - - final DeploymentRequest assignWithoutWeight = DeploymentRequest.builder(targetId, dsId).build(); - final DeploymentRequest assignWithWeight = DeploymentRequest.builder(targetId, dsId).weight(567).build(); - - enableMultiAssignments(); - assertThat(deploymentManagement.assignDistributionSets(List.of(assignWithoutWeight, assignWithWeight), null)).isNotNull(); + assertThat(actionRepository.countByTargetControllerId(controllerId)).isEqualTo(20L); } /** @@ -1003,22 +831,28 @@ void weightAllowedWhenMultiAssignmentModeNotEnabled() { @Test @ExpectEvents({ @Expect(type = TargetCreatedEvent.class, count = 1), - @Expect(type = DistributionSetCreatedEvent.class, count = 1), - @Expect(type = SoftwareModuleCreatedEvent.class, count = 3), - @Expect(type = DistributionSetUpdatedEvent.class, count = 1), // implicit lock - @Expect(type = SoftwareModuleUpdatedEvent.class, count = 3), // implicit lock + @Expect(type = DistributionSetCreatedEvent.class, count = 2), + @Expect(type = SoftwareModuleCreatedEvent.class, count = 6), + @Expect(type = DistributionSetUpdatedEvent.class, count = 2), // implicit lock + @Expect(type = SoftwareModuleUpdatedEvent.class, count = 6), // implicit lock @Expect(type = ActionCreatedEvent.class, count = 2), + @Expect(type = ActionUpdatedEvent.class, count = 1), + @Expect(type = ActionUpdatedServiceEvent.class, count = 1), @Expect(type = TargetUpdatedEvent.class, count = 2), - @Expect(type = MultiActionAssignEvent.class, count = 2), - @Expect(type = TenantConfigurationCreatedEvent.class, count = 1) }) + @Expect(type = TargetAssignDistributionSetEvent.class, count = 2), + @Expect(type = TargetAssignDistributionSetServiceEvent.class, count = 2), + @Expect(type = CancelTargetAssignmentEvent.class, count = 1), + @Expect(type = CancelTargetAssignmentServiceEvent.class, count = 1) + }) void weightValidatedAndSaved() { final String targetId = testdataFactory.createTarget().getControllerId(); - final Long dsId = testdataFactory.createDistributionSet().getId(); - final DeploymentRequest validRequest1 = DeploymentRequest.builder(targetId, dsId).weight(Action.WEIGHT_MAX).build(); - final DeploymentRequest validRequest2 = DeploymentRequest.builder(targetId, dsId).weight(Action.WEIGHT_MIN).build(); - final DeploymentRequest weightTooLow = DeploymentRequest.builder(targetId, dsId).weight(Action.WEIGHT_MIN - 1).build(); - final DeploymentRequest weightTooHigh = DeploymentRequest.builder(targetId, dsId).weight(Action.WEIGHT_MAX + 1).build(); - enableMultiAssignments(); + final Long dsId1 = testdataFactory.createDistributionSet().getId(); + final Long dsId2 = testdataFactory.createDistributionSet().getId(); + final DeploymentRequest validRequest1 = DeploymentRequest.builder(targetId, dsId1).weight(Action.WEIGHT_MAX).build(); + final DeploymentRequest validRequest2 = DeploymentRequest.builder(targetId, dsId2).weight(Action.WEIGHT_MIN).build(); + final DeploymentRequest weightTooLow = DeploymentRequest.builder(targetId, dsId1).weight(Action.WEIGHT_MIN - 1).build(); + final DeploymentRequest weightTooHigh = DeploymentRequest.builder(targetId, dsId1).weight(Action.WEIGHT_MAX + 1).build(); + final List deploymentRequestsTooLow = Collections.singletonList(weightTooLow); Assertions.assertThatExceptionOfType(ConstraintViolationException.class) .isThrownBy(() -> deploymentManagement.assignDistributionSets(deploymentRequestsTooLow, null)); @@ -1027,9 +861,11 @@ void weightValidatedAndSaved() { () -> deploymentManagement.assignDistributionSets(deploymentRequestsTooHigh, null)); final Long validActionId1 = getFirstAssignedAction( deploymentManagement.assignDistributionSets(Collections.singletonList(validRequest1), null).get(0)).getId(); - final Long validActionId2 = getFirstAssignedAction( - deploymentManagement.assignDistributionSets(Collections.singletonList(validRequest2), null).get(0)).getId(); assertThat(actionRepository.findById(validActionId1).get().getWeight()).get().isEqualTo(Action.WEIGHT_MAX); + DistributionSetAssignmentResult assignmentResult = deploymentManagement.assignDistributionSets(Collections.singletonList(validRequest2), null).get(0); + System.out.println(assignmentResult.getAssignedEntity().toString()); + + final Long validActionId2 = getFirstAssignedAction(assignmentResult).getId(); assertThat(actionRepository.findById(validActionId2).get().getWeight()).get().isEqualTo(Action.WEIGHT_MIN); } @@ -1720,20 +1556,6 @@ void testThatOnlyNeededNumberOfActionsIsPurged() { } - private List createAssignmentRequests( - final Collection distributionSets, final Collection targets, final int weight) { - return createAssignmentRequests(distributionSets, targets, weight, false); - } - - private List createAssignmentRequests(final Collection distributionSets, - final Collection targets, final int weight, final boolean confirmationRequired) { - final List deploymentRequests = new ArrayList<>(); - distributionSets.forEach(ds -> targets.forEach(target -> deploymentRequests.add( - DeploymentRequest.builder(target.getControllerId(), ds.getId()) - .weight(weight).confirmationRequired(confirmationRequired).build()))); - return deploymentRequests; - } - private JpaAction assignSet(final Target target, final DistributionSet ds) { assignDistributionSet(ds.getId(), target.getControllerId()); implicitLock(ds); diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java index 4acf7b2d84..d4cb6c8405 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/RolloutManagementTest.java @@ -25,6 +25,7 @@ import jakarta.validation.ConstraintViolationException; import jakarta.validation.ValidationException; +import lombok.extern.slf4j.Slf4j; import org.assertj.core.api.Assertions; import org.assertj.core.api.Condition; import org.eclipse.hawkbit.auth.SpPermission; @@ -1994,18 +1995,6 @@ void findAllRolloutsConsidersSorting() { assertThat(rolloutsOrderedByName).containsSubsequence(List.of(rolloutRunning, rolloutReady)); } - /** - * Creating a rollout without weight value when multi assignment in enabled. - */ - @Test - void weightNotRequiredInMultiAssignmentMode() { - enableMultiAssignments(); - final Rollout rollout = testdataFactory.createSimpleTestRolloutWithTargetsAndDistributionSet(10, 10, 2, "50", - "80", - ActionType.FORCED, null); - assertThat(rollout).isNotNull(); - } - /** * Creating a rollout with a weight causes an error when multi assignment in disabled. */ @@ -2024,7 +2013,6 @@ void weightAllowedWhenMultiAssignmentModeNotEnabled() { void weightValidatedAndSaved() { final String targetPrefix = UUID.randomUUID().toString(); testdataFactory.createTargets(4, targetPrefix); - enableMultiAssignments(); final String rolloutName = UUID.randomUUID().toString(); final String targetPrefixName = UUID.randomUUID().toString(); @@ -2054,7 +2042,6 @@ void weightValidatedAndSaved() { void actionsWithWeightAreCreated() { final int amountOfTargets = 5; final int weight = 99; - enableMultiAssignments(); final Long rolloutId = testdataFactory .createSimpleTestRolloutWithTargetsAndDistributionSet(amountOfTargets, 2, amountOfTargets, "80", "50", null, weight).getId(); @@ -2066,24 +2053,6 @@ void actionsWithWeightAreCreated() { .allMatch(action -> action.getWeight().get() == weight); } - /** - * Rollout can be created without weight in single assignment and be started in multi assignment - */ - @Test - void createInSingleStartInMultiassignMode() { - final int amountOfTargets = 5; - final Long rolloutId = testdataFactory.createSimpleTestRolloutWithTargetsAndDistributionSet(amountOfTargets, 2, - amountOfTargets, - "80", "50", null, null).getId(); - - enableMultiAssignments(); - rolloutManagement.start(rolloutId); - rolloutHandler.handleAll(); - final List actions = deploymentManagement.findActionsAll(PAGE).getContent(); - // wight replaced with default - assertThat(actions).hasSize(5).allMatch(action -> action.getWeight().isPresent()); - } - /** * Verifies that an exception is thrown when trying to create a rollout with an invalidated distribution set. */ diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetFilterQueryManagementTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetFilterQueryManagementTest.java index 968035427f..1f7331104d 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetFilterQueryManagementTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/management/TargetFilterQueryManagementTest.java @@ -244,23 +244,6 @@ void findFiltersWithDistributionSet() { verifyFindForAllWithAutoAssignDs(tfq, tfq2); } - /** - * Creating or updating a target filter query with autoassignment and no-value weight when multi assignment in enabled. - */ - @Test - void weightNotRequiredInMultiAssignmentMode() { - enableMultiAssignments(); - final DistributionSet ds = testdataFactory.createDistributionSet(); - final Long filterId = targetFilterQueryManagement.create(Create.builder().name("a").query("name==*").build()).getId(); - - assertThat( - targetFilterQueryManagement.create(Create.builder().name("b").query("name==*").autoAssignDistributionSet(ds).build())) - .isNotNull(); - assertThat( - targetFilterQueryManagement.updateAutoAssignDS(new AutoAssignDistributionSetUpdate(filterId).ds(ds.getId()))) - .isNotNull(); - } - /** * Creating or updating a target filter query with autoassignment with a weight causes an error when multi assignment in disabled. */ @@ -279,23 +262,8 @@ void weightAllowedWhenMultiAssignmentModeNotEnabled() { .isNotNull(); } - /** - * Auto assignment can be removed from filter when multi assignment in enabled. - */ - @Test - void removeDsFromFilterWhenMultiAssignmentModeNotEnabled() { - enableMultiAssignments(); - final DistributionSet ds = testdataFactory.createDistributionSet(); - final Long filterId = targetFilterQueryManagement.create( - Create.builder().name("a").query("name==*").autoAssignDistributionSet(ds).autoAssignWeight(23).build()).getId(); - assertThat(targetFilterQueryManagement.updateAutoAssignDS( - new AutoAssignDistributionSetUpdate(filterId).ds(null).weight(null))) - .isNotNull(); - } - @Test void weightValidatedAndSaved() { - enableMultiAssignments(); final DistributionSet ds = testdataFactory.createDistributionSet(); final Create targetFilterQueryCreate = Create.builder().name("a") diff --git a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/scheduler/AutoAssignHandlerIntTest.java b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/scheduler/AutoAssignHandlerIntTest.java index 9f63ad9641..079087e582 100644 --- a/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/scheduler/AutoAssignHandlerIntTest.java +++ b/hawkbit-repository/hawkbit-repository-jpa/src/test/java/org/eclipse/hawkbit/repository/jpa/scheduler/AutoAssignHandlerIntTest.java @@ -328,7 +328,6 @@ void actionsWithWeightAreCreated() { final int amountOfTargets = 5; final DistributionSet ds = testdataFactory.createDistributionSet(); final int weight = 32; - enableMultiAssignments(); targetFilterQueryManagement.create(Create.builder() .name("a").query("name==*").autoAssignDistributionSet(ds).autoAssignWeight(weight) @@ -342,25 +341,6 @@ void actionsWithWeightAreCreated() { .allMatch(action -> action.getWeight().get() == weight); } - /** - * An auto assignment target filter without weight still works after multi assignment is enabled - */ - @Test - void filterWithoutWeightWorksInMultiAssignmentMode() { - final int amountOfTargets = 5; - final DistributionSet ds = testdataFactory.createDistributionSet(); - targetFilterQueryManagement.create(Create.builder().name("a").query("name==*").autoAssignDistributionSet(ds).build()); - enableMultiAssignments(); - - testdataFactory.createTargets(amountOfTargets); - autoAssignChecker.handleAll(); - - final List actions = deploymentManagement.findActionsAll(PAGE).getContent(); - assertThat(actions) - .hasSize(amountOfTargets) - .allMatch(action -> action.getWeight().isPresent()); - } - /** * Verifies an auto assignment only creates actions for compatible targets */ 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 14f4fe0ee8..677bdb200e 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 @@ -34,8 +34,6 @@ import org.awaitility.core.ConditionTimeoutException; import org.eclipse.hawkbit.repository.event.remote.AbstractRemoteEvent; import org.eclipse.hawkbit.repository.event.remote.CancelTargetAssignmentEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionAssignEvent; -import org.eclipse.hawkbit.repository.event.remote.MultiActionCancelEvent; import org.eclipse.hawkbit.repository.event.remote.RemoteIdEvent; import org.eclipse.hawkbit.repository.event.remote.RemoteTenantAwareEvent; import org.eclipse.hawkbit.repository.event.remote.TargetAssignDistributionSetEvent; @@ -48,8 +46,6 @@ import org.eclipse.hawkbit.repository.event.remote.service.ActionCreatedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.ActionUpdatedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.CancelTargetAssignmentServiceEvent; -import org.eclipse.hawkbit.repository.event.remote.service.MultiActionAssignServiceEvent; -import org.eclipse.hawkbit.repository.event.remote.service.MultiActionCancelServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetAssignDistributionSetServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetAttributesRequestedServiceEvent; import org.eclipse.hawkbit.repository.event.remote.service.TargetCreatedServiceEvent; @@ -177,10 +173,6 @@ private static void addServiceEventIfNeeded(final Expect event, final List