diff options
author | FrancescoFioraEst <francesco.fiora@est.tech> | 2024-03-20 16:17:46 +0000 |
---|---|---|
committer | Francesco Fiora <francesco.fiora@est.tech> | 2024-08-06 10:33:25 +0000 |
commit | a2477d552ad3993989a4f8b7a7adac6686719cf3 (patch) | |
tree | a7acc256cd3967e85ea091bd3646272def3d3d3d /participant | |
parent | e1589aa82ddfb58b0d4bcabe1c63cdda29939e6a (diff) |
Allow migration to be performed in stages in ACM intermediary
Allow migration to be performed in stages,
and replace newElement and removedElement with an Enum
in CompositionElementDto and InstanceElementDto.
Issue-ID: POLICY-5091
Change-Id: I2d66abc453776fd708fc18fd9019ca248f8d2eee
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
Diffstat (limited to 'participant')
18 files changed, 471 insertions, 194 deletions
diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2.java index a7f72ecb4..82602c1e1 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2.java +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2.java @@ -22,6 +22,7 @@ package org.onap.policy.clamp.acm.participant.sim.main.handler; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.acm.participant.intermediary.api.impl.AcElementListenerV2; @@ -116,11 +117,11 @@ public class AutomationCompositionElementHandlerV2 extends AcElementListenerV2 { + " instanceElementMigrate: {}", compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate); - if (instanceElementMigrate.newElement()) { + if (ElementState.NEW.equals(instanceElementMigrate.state())) { LOGGER.debug("new element scenario"); } - if (instanceElementMigrate.removedElement()) { + if (ElementState.REMOVED.equals(instanceElementMigrate.state())) { simulatorService.undeploy(instanceElement.instanceId(), instanceElement.elementId()); simulatorService.delete(instanceElement.instanceId(), instanceElement.elementId()); } else { diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3.java index 66f4c30b9..3e9db9031 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3.java +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3.java @@ -24,6 +24,7 @@ import lombok.Getter; import lombok.Setter; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.acm.participant.intermediary.api.impl.AcElementListenerV3; @@ -120,10 +121,10 @@ public class AutomationCompositionElementHandlerV3 extends AcElementListenerV3 { + " instanceElementMigrate: {}, stage: {}", compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate, stage); - if (instanceElementMigrate.newElement()) { + if (ElementState.NEW.equals(instanceElementMigrate.state())) { LOGGER.debug("new element scenario"); } - if (instanceElementMigrate.removedElement()) { + if (ElementState.REMOVED.equals(instanceElementMigrate.state())) { simulatorService.undeploy(instanceElement.instanceId(), instanceElement.elementId()); simulatorService.delete(instanceElement.instanceId(), instanceElement.elementId()); } else { diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2Test.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2Test.java index e8e9b766c..f3a1839f0 100644 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2Test.java +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV2Test.java @@ -28,6 +28,7 @@ import java.util.UUID; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.acm.participant.sim.comm.CommonTestData; @@ -229,15 +230,21 @@ class AutomationCompositionElementHandlerV2Test { var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV2(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compoElTargetAdd = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of(), true, false); + + var compositionElement = new CompositionElementDto( + UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of(), ElementState.NOT_PRESENT); + + var instanceElement = new InstanceElementDto( + UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of(), ElementState.NOT_PRESENT); + + var compoElTargetAdd = new CompositionElementDto( + UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of(), ElementState.NEW); var inElMigratedAdd = new InstanceElementDto( - INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), - null, Map.of("key", "value"), Map.of(), true, false); + instanceElement.instanceId(), instanceElement.elementId(), null, Map.of(), Map.of(), ElementState.NEW); acElementHandler - .migrate(COMPOSITION_ELEMENT, compoElTargetAdd, INSTANCE_ELEMENT, inElMigratedAdd); + .migrate(compositionElement, compoElTargetAdd, instanceElement, inElMigratedAdd); verify(intermediaryApi).updateAutomationCompositionElementState( - INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); } @@ -250,10 +257,10 @@ class AutomationCompositionElementHandlerV2Test { simulatorService.setConfig(config); var compoElTargetRemove = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of(), false, true); + Map.of(), Map.of(), ElementState.REMOVED); var inElMigratedRemove = new InstanceElementDto( INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), - null, Map.of("key", "value"), Map.of(), false, true); + null, Map.of("key", "value"), Map.of(), ElementState.REMOVED); acElementHandler .migrate(COMPOSITION_ELEMENT, compoElTargetRemove, INSTANCE_ELEMENT, inElMigratedRemove); verify(intermediaryApi).updateAutomationCompositionElementState( diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3Test.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3Test.java index 3a7af2456..12703c7d4 100644 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3Test.java +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerV3Test.java @@ -29,6 +29,7 @@ import java.util.UUID; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionDto; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi; import org.onap.policy.clamp.acm.participant.sim.comm.CommonTestData; @@ -249,15 +250,20 @@ class AutomationCompositionElementHandlerV3Test { var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandlerV3(intermediaryApi, simulatorService); simulatorService.setConfig(config); - var compoElTargetAdd = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of(), true, false); + var compositionElement = new CompositionElementDto( + UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of(), ElementState.NOT_PRESENT); + + var instanceElement = new InstanceElementDto( + UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of(), ElementState.NOT_PRESENT); + + var compoElTargetAdd = new CompositionElementDto( + UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of(), ElementState.NEW); var inElMigratedAdd = new InstanceElementDto( - INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), - null, Map.of("key", "value"), Map.of(), true, false); + instanceElement.instanceId(), instanceElement.elementId(), null, Map.of(), Map.of(), ElementState.NEW); acElementHandler - .migrate(COMPOSITION_ELEMENT, compoElTargetAdd, INSTANCE_ELEMENT, inElMigratedAdd, 0); + .migrate(compositionElement, compoElTargetAdd, instanceElement, inElMigratedAdd, 0); verify(intermediaryApi).updateAutomationCompositionElementState( - INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), + instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); } @@ -270,10 +276,10 @@ class AutomationCompositionElementHandlerV3Test { simulatorService.setConfig(config); var compoElTargetRemove = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), - Map.of(), Map.of(), false, true); + Map.of(), Map.of(), ElementState.REMOVED); var inElMigratedRemove = new InstanceElementDto( INSTANCE_ELEMENT.instanceId(), INSTANCE_ELEMENT.elementId(), - null, Map.of("key", "value"), Map.of(), false, true); + null, Map.of("key", "value"), Map.of(), ElementState.REMOVED); acElementHandler .migrate(COMPOSITION_ELEMENT, compoElTargetRemove, INSTANCE_ELEMENT, inElMigratedRemove, 0); verify(intermediaryApi).updateAutomationCompositionElementState( diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionElementDto.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionElementDto.java index 51800cef1..50699e22c 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionElementDto.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/CompositionElementDto.java @@ -26,11 +26,11 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; public record CompositionElementDto(UUID compositionId, ToscaConceptIdentifier elementDefinitionId, Map<String, Object> inProperties, Map<String, Object> outProperties, - boolean newElement, boolean removedElement) { + ElementState state) { public CompositionElementDto(UUID compositionId, ToscaConceptIdentifier elementDefinitionId, Map<String, Object> inProperties, Map<String, Object> outProperties) { - this(compositionId, elementDefinitionId, inProperties, outProperties, false, false); + this(compositionId, elementDefinitionId, inProperties, outProperties, ElementState.PRESENT); } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ElementState.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ElementState.java new file mode 100644 index 000000000..afb01d014 --- /dev/null +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ElementState.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2024 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.acm.participant.intermediary.api; + +public enum ElementState { + PRESENT, + NOT_PRESENT, + REMOVED, + NEW +} diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/InstanceElementDto.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/InstanceElementDto.java index 65a83e222..b4fdefbf3 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/InstanceElementDto.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/InstanceElementDto.java @@ -26,10 +26,10 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; public record InstanceElementDto(UUID instanceId, UUID elementId, ToscaServiceTemplate toscaServiceTemplateFragment, Map<String, Object> inProperties, Map<String, Object> outProperties, - boolean newElement, boolean removedElement) { + ElementState state) { public InstanceElementDto(UUID instanceId, UUID elementId, ToscaServiceTemplate toscaServiceTemplateFragment, Map<String, Object> inProperties, Map<String, Object> outProperties) { - this(instanceId, elementId, toscaServiceTemplateFragment, inProperties, outProperties, false, false); + this(instanceId, elementId, toscaServiceTemplateFragment, inProperties, outProperties, ElementState.PRESENT); } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java index e1bd06465..233b55926 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java @@ -59,7 +59,8 @@ public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryAp @Override public void updateAutomationCompositionElementStage(UUID instance, UUID elementId, StateChangeResult stateChangeResult, int stage, String message) { - // + automationCompositionHandler.updateAutomationCompositionElementStage(instance, elementId, stateChangeResult, + stage, message); } @Override diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandler.java index 3044080af..1dbf2c935 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandler.java @@ -21,16 +21,21 @@ package org.onap.policy.clamp.acm.participant.intermediary.handler; import java.util.List; +import java.util.Map; import java.util.UUID; import lombok.RequiredArgsConstructor; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare; import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -77,24 +82,64 @@ public class AcSubStateHandler { var acElementList = automationComposition.getElements(); for (var acElement : acElements) { var element = acElementList.get(acElement.getId()); - element.setSubState(SubState.MIGRATION_PRECHECKING); + if (element != null) { + element.setSubState(SubState.MIGRATION_PRECHECKING); + } } var acCopyMigrateTo = new AutomationComposition(automationComposition); - acElementList = acCopyMigrateTo.getElements(); + var acElementCopyList = acCopyMigrateTo.getElements(); for (var acElement : acElements) { - var element = acElementList.get(acElement.getId()); - AcmUtils.recursiveMerge(element.getProperties(), acElement.getProperties()); - element.setDefinition(acElement.getDefinition()); + var element = acElementCopyList.get(acElement.getId()); + if (element != null) { + AcmUtils.recursiveMerge(element.getProperties(), acElement.getProperties()); + element.setDefinition(acElement.getDefinition()); + } else { + element = CacheProvider.createAutomationCompositionElement(acElement); + element.setSubState(SubState.MIGRATION_PRECHECKING); + acElementCopyList.put(element.getId(), element); + } } + var toDelete = acElementCopyList.values().stream() + .filter(el -> !SubState.MIGRATION_PRECHECKING.equals(el.getSubState())) + .map(AutomationCompositionElement::getId) + .toList(); + toDelete.forEach(acElementCopyList::remove); var compositionElementTargetMap = cacheProvider.getCompositionElementDtoMap(acCopyMigrateTo, compositionTargetId); var instanceElementMigrateMap = cacheProvider.getInstanceElementDtoMap(acCopyMigrateTo); for (var acElement : acElements) { - listener.migratePrecheck(messageId, compositionElementMap.get(acElement.getId()), - compositionElementTargetMap.get(acElement.getId()), - instanceElementMap.get(acElement.getId()), instanceElementMigrateMap.get(acElement.getId())); + var compositionElement = compositionElementMap.get(acElement.getId()); + var compositionElementTarget = compositionElementTargetMap.get(acElement.getId()); + var instanceElement = instanceElementMap.get(acElement.getId()); + var instanceElementMigrate = instanceElementMigrateMap.get(acElement.getId()); + + if (instanceElement == null) { + // new element scenario + compositionElement = new CompositionElementDto(automationComposition.getCompositionId(), + acElement.getDefinition(), Map.of(), Map.of(), ElementState.NOT_PRESENT); + instanceElement = new InstanceElementDto(automationComposition.getInstanceId(), acElement.getId(), + new ToscaServiceTemplate(), Map.of(), Map.of(), ElementState.NOT_PRESENT); + compositionElementTarget = CacheProvider.changeStateToNew(compositionElementTarget); + instanceElementMigrate = CacheProvider.changeStateToNew(instanceElementMigrate); + } + + listener.migratePrecheck(messageId, compositionElement, compositionElementTarget, + instanceElement, instanceElementMigrate); + } + + for (var elementId : toDelete) { + var compositionDtoTarget = + new CompositionElementDto(compositionTargetId, + automationComposition.getElements().get(elementId).getDefinition(), + Map.of(), Map.of(), ElementState.REMOVED); + var instanceDtoTarget = + new InstanceElementDto(automationComposition.getInstanceId(), elementId, + null, Map.of(), Map.of(), ElementState.REMOVED); + + listener.migratePrecheck(messageId, compositionElementMap.get(elementId), compositionDtoTarget, + instanceElementMap.get(elementId), instanceDtoTarget); } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java index 6c560e7fa..6d94efb0f 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java @@ -21,13 +21,13 @@ package org.onap.policy.clamp.acm.participant.intermediary.handler; - -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.stream.Collectors; import lombok.RequiredArgsConstructor; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher; import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; @@ -47,7 +47,6 @@ import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMe import org.onap.policy.clamp.models.acm.messages.kafka.participant.PropertiesUpdate; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; import org.onap.policy.clamp.models.acm.utils.AcmUtils; -import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -124,8 +123,7 @@ public class AutomationCompositionHandler { updateMsg.getAutomationCompositionId()); automationComposition.setDeployState(DeployState.UPDATING); var acCopy = new AutomationComposition(automationComposition); - updateExistingElementsOnThisParticipant(updateMsg.getAutomationCompositionId(), participantDeploy, - DeployState.UPDATING); + updateExistingElementsOnThisParticipant(updateMsg.getAutomationCompositionId(), participantDeploy); callParticipantUpdateProperty(updateMsg.getMessageId(), participantDeploy.getAcElementList(), acCopy); } @@ -188,56 +186,56 @@ public class AutomationCompositionHandler { } } - private void updateExistingElementsOnThisParticipant(UUID instanceId, ParticipantDeploy participantDeploy, - DeployState deployState) { - var acElementList = cacheProvider.getAutomationComposition(instanceId).getElements(); + private void migrateExistingElementsOnThisParticipant(UUID instanceId, UUID compositionTargetId, + ParticipantDeploy participantDeploy, int stage) { + var automationComposition = cacheProvider.getAutomationComposition(instanceId); + var acElementList = automationComposition.getElements(); for (var element : participantDeploy.getAcElementList()) { - var acElement = acElementList.get(element.getId()); - if (acElement == null && deployState.equals(DeployState.MIGRATING)) { - var newElement = new AutomationCompositionElement(); - newElement.setId(element.getId()); - newElement.setParticipantId(participantDeploy.getParticipantId()); - newElement.setDefinition(element.getDefinition()); - newElement.setDeployState(deployState); - newElement.setSubState(SubState.NONE); - newElement.setLockState(LockState.LOCKED); - newElement.setProperties(element.getProperties()); + var compositionInProperties = + cacheProvider.getCommonProperties(compositionTargetId, element.getDefinition()); + var stageSet = ParticipantUtils.findStageSet(compositionInProperties); + if (stageSet.contains(stage)) { + var acElement = acElementList.get(element.getId()); + if (acElement == null) { + var newElement = CacheProvider.createAutomationCompositionElement(element); + newElement.setParticipantId(participantDeploy.getParticipantId()); + newElement.setDeployState(DeployState.MIGRATING); + newElement.setLockState(LockState.LOCKED); + newElement.setStage(stage); - acElementList.put(element.getId(), newElement); - LOGGER.info("New Ac Element with id {} is added in Migration", element.getId()); - } else if (acElement != null) { - AcmUtils.recursiveMerge(acElement.getProperties(), element.getProperties()); - acElement.setDeployState(deployState); - acElement.setSubState(SubState.NONE); - acElement.setDefinition(element.getDefinition()); + acElementList.put(element.getId(), newElement); + LOGGER.info("New Ac Element with id {} is added in Migration", element.getId()); + } else { + AcmUtils.recursiveMerge(acElement.getProperties(), element.getProperties()); + acElement.setDeployState(DeployState.MIGRATING); + acElement.setStage(stage); + acElement.setDefinition(element.getDefinition()); + } } } - if (deployState.equals(DeployState.MIGRATING)) { - // Check for missing elements and remove them from cache - List<UUID> elementsToRemove = findElementsToRemove(participantDeploy.getAcElementList(), acElementList); - for (UUID key : elementsToRemove) { - acElementList.remove(key); - LOGGER.info("Element with id {} is removed in Migration", key); - } + // Check for missing elements and remove them from cache + var elementsToRemove = findElementsToRemove(participantDeploy.getAcElementList(), acElementList); + for (var key : elementsToRemove) { + acElementList.remove(key); + LOGGER.info("Element with id {} is removed in Migration", key); + } + } + + private void updateExistingElementsOnThisParticipant(UUID instanceId, ParticipantDeploy participantDeploy) { + var acElementList = cacheProvider.getAutomationComposition(instanceId).getElements(); + for (var element : participantDeploy.getAcElementList()) { + var acElement = acElementList.get(element.getId()); + AcmUtils.recursiveMerge(acElement.getProperties(), element.getProperties()); + acElement.setDeployState(DeployState.UPDATING); + acElement.setSubState(SubState.NONE); + acElement.setDefinition(element.getDefinition()); } } private List<UUID> findElementsToRemove(List<AcElementDeploy> acElementDeployList, Map<UUID, AutomationCompositionElement> acElementList) { - List<UUID> elementsToRemove = new ArrayList<>(); - for (var elementInCache : acElementList.entrySet()) { - boolean found = false; - for (var element : acElementDeployList) { - if (element.getId().equals(elementInCache.getValue().getId())) { - found = true; - break; - } - } - if (!found) { - elementsToRemove.add(elementInCache.getKey()); - } - } - return elementsToRemove; + var acElementDeploySet = acElementDeployList.stream().map(AcElementDeploy::getId).collect(Collectors.toSet()); + return acElementList.keySet().stream().filter(id -> !acElementDeploySet.contains(id)).toList(); } /** @@ -311,17 +309,17 @@ public class AutomationCompositionHandler { for (var participantDeploy : migrationMsg.getParticipantUpdatesList()) { if (cacheProvider.getParticipantId().equals(participantDeploy.getParticipantId())) { - updateExistingElementsOnThisParticipant(migrationMsg.getAutomationCompositionId(), participantDeploy, - DeployState.MIGRATING); + migrateExistingElementsOnThisParticipant(migrationMsg.getAutomationCompositionId(), + migrationMsg.getCompositionTargetId(), participantDeploy, migrationMsg.getStage()); callParticipantMigrate(migrationMsg.getMessageId(), participantDeploy.getAcElementList(), - acCopy, migrationMsg.getCompositionTargetId()); + acCopy, migrationMsg.getCompositionTargetId(), migrationMsg.getStage()); } } } private void callParticipantMigrate(UUID messageId, List<AcElementDeploy> acElements, - AutomationComposition acCopy, UUID compositionTargetId) { + AutomationComposition acCopy, UUID compositionTargetId, int stage) { var compositionElementMap = cacheProvider.getCompositionElementDtoMap(acCopy); var instanceElementMap = cacheProvider.getInstanceElementDtoMap(acCopy); var automationComposition = cacheProvider.getAutomationComposition(acCopy.getInstanceId()); @@ -331,32 +329,46 @@ public class AutomationCompositionHandler { // Call migrate for newly added and updated elements for (var acElement : acElements) { - if (instanceElementMap.get(acElement.getId()) == null) { - var compositionDto = new CompositionElementDto(acElement.getId(), acElement.getDefinition(), - Map.of(), Map.of(), true, false); - var instanceDto = new InstanceElementDto(acCopy.getInstanceId(), acElement.getId(), - new ToscaServiceTemplate(), Map.of(), Map.of(), true, false); + var compositionInProperties = cacheProvider + .getCommonProperties(compositionTargetId, acElement.getDefinition()); + var stageSet = ParticipantUtils.findStageSet(compositionInProperties); + if (stageSet.contains(stage)) { + if (instanceElementMap.get(acElement.getId()) == null) { + var compositionElementDto = + new CompositionElementDto(acCopy.getCompositionId(), acElement.getDefinition(), + Map.of(), Map.of(), ElementState.NOT_PRESENT); + var instanceElementDto = new InstanceElementDto(acCopy.getInstanceId(), acElement.getId(), + null, Map.of(), Map.of(), ElementState.NOT_PRESENT); + var compositionElementTargetDto = CacheProvider.changeStateToNew( + compositionElementTargetMap.get(acElement.getId())); + var instanceElementMigrateDto = CacheProvider + .changeStateToNew(instanceElementMigrateMap.get(acElement.getId())); - listener.migrate(messageId, compositionDto, - compositionElementTargetMap.get(acElement.getId()), - instanceDto, instanceElementMigrateMap.get(acElement.getId())); - } else { - listener.migrate(messageId, compositionElementMap.get(acElement.getId()), - compositionElementTargetMap.get(acElement.getId()), - instanceElementMap.get(acElement.getId()), instanceElementMigrateMap.get(acElement.getId())); + listener.migrate(messageId, compositionElementDto, compositionElementTargetDto, instanceElementDto, + instanceElementMigrateDto, stage); + } else { + listener.migrate(messageId, compositionElementMap.get(acElement.getId()), + compositionElementTargetMap.get(acElement.getId()), + instanceElementMap.get(acElement.getId()), instanceElementMigrateMap.get(acElement.getId()), + stage); + } } } - // Call migrate for removed elements - List<UUID> removedElements = findElementsToRemove(acElements, acCopy.getElements()); - for (var elementId : removedElements) { - var compositionDtoTarget = new CompositionElementDto(elementId, acCopy.getElements().get(elementId) - .getDefinition(), Map.of(), Map.of(), false, true); - var instanceDtoTarget = new InstanceElementDto(acCopy.getInstanceId(), elementId, - new ToscaServiceTemplate(), Map.of(), Map.of(), false, true); + if (stage == 0) { + // Call migrate for removed elements + List<UUID> removedElements = findElementsToRemove(acElements, acCopy.getElements()); + for (var elementId : removedElements) { + var compositionDtoTarget = + new CompositionElementDto(compositionTargetId, + acCopy.getElements().get(elementId).getDefinition(), + Map.of(), Map.of(), ElementState.REMOVED); + var instanceDtoTarget = + new InstanceElementDto(acCopy.getInstanceId(), elementId, null, Map.of(), + Map.of(), ElementState.REMOVED); - listener.migrate(messageId, compositionElementMap.get(elementId), - compositionDtoTarget, - instanceElementMap.get(elementId), instanceDtoTarget); + listener.migrate(messageId, compositionElementMap.get(elementId), compositionDtoTarget, + instanceElementMap.get(elementId), instanceDtoTarget, 0); + } } } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java index 06b11bbca..77bcb19ef 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java @@ -56,27 +56,77 @@ public class AutomationCompositionOutHandler { private final CacheProvider cacheProvider; /** + * Handle a automation composition element stage change message. + * + * @param instance the automationComposition Id + * @param elementId the automationComposition Element Id + * @param stage the next stage + * @param message the message + * @param stateChangeResult the indicator if error occurs + */ + public void updateAutomationCompositionElementStage(UUID instance, UUID elementId, + StateChangeResult stateChangeResult, int stage, String message) { + + if (instance == null || elementId == null) { + LOGGER.error("Cannot update Automation composition element stage, id is null"); + return; + } + + var automationComposition = cacheProvider.getAutomationComposition(instance); + if (automationComposition == null) { + LOGGER.error("Cannot update Automation composition element stage, Automation composition id {} not present", + instance); + return; + } + + var element = automationComposition.getElements().get(elementId); + if (element == null) { + var msg = "Cannot update Automation composition element stage, AC Element id {} not present"; + LOGGER.error(msg, elementId); + return; + } + + element.setRestarting(null); + + var automationCompositionStateChangeAck = + new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK); + automationCompositionStateChangeAck.setParticipantId(cacheProvider.getParticipantId()); + automationCompositionStateChangeAck.setMessage(message); + automationCompositionStateChangeAck.setResponseTo(cacheProvider.getMsgIdentification().get(element.getId())); + automationCompositionStateChangeAck.setStateChangeResult(stateChangeResult); + automationCompositionStateChangeAck.setStage(stage); + automationCompositionStateChangeAck.setAutomationCompositionId(instance); + automationCompositionStateChangeAck.getAutomationCompositionResultMap().put(element.getId(), + new AcElementDeployAck(element.getDeployState(), element.getLockState(), element.getOperationalState(), + element.getUseState(), element.getOutProperties(), true, message)); + LOGGER.debug("Automation composition element {} stage changed to {}", elementId, stage); + automationCompositionStateChangeAck.setResult(true); + publisher.sendAutomationCompositionAck(automationCompositionStateChangeAck); + cacheProvider.getMsgIdentification().remove(element.getId()); + } + + /** * Handle a automation composition element state change message. * - * @param automationCompositionId the automationComposition Id + * @param instance the automationComposition Id * @param elementId the automationComposition Element Id * @param deployState the DeployState state * @param lockState the LockState state * @param message the message * @param stateChangeResult the indicator if error occurs */ - public void updateAutomationCompositionElementState(UUID automationCompositionId, UUID elementId, + public void updateAutomationCompositionElementState(UUID instance, UUID elementId, DeployState deployState, LockState lockState, StateChangeResult stateChangeResult, String message) { - if (automationCompositionId == null || elementId == null) { + if (instance == null || elementId == null) { LOGGER.error("Cannot update Automation composition element state, id is null"); return; } - var automationComposition = cacheProvider.getAutomationComposition(automationCompositionId); + var automationComposition = cacheProvider.getAutomationComposition(instance); if (automationComposition == null) { LOGGER.error("Cannot update Automation composition element state, Automation composition id {} not present", - automationCompositionId); + instance); return; } @@ -114,7 +164,7 @@ public class AutomationCompositionOutHandler { automationCompositionStateChangeAck.setMessage(message); automationCompositionStateChangeAck.setResponseTo(cacheProvider.getMsgIdentification().get(element.getId())); automationCompositionStateChangeAck.setStateChangeResult(stateChangeResult); - automationCompositionStateChangeAck.setAutomationCompositionId(automationCompositionId); + automationCompositionStateChangeAck.setAutomationCompositionId(instance); automationCompositionStateChangeAck.getAutomationCompositionResultMap().put(element.getId(), new AcElementDeployAck(element.getDeployState(), element.getLockState(), element.getOperationalState(), element.getUseState(), element.getOutProperties(), true, message)); diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java index f56fabf3f..7aa06badb 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java @@ -30,8 +30,10 @@ import lombok.Getter; import lombok.NonNull; import lombok.Setter; import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; +import org.onap.policy.clamp.acm.participant.intermediary.api.ElementState; import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto; import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantParameters; +import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; @@ -181,14 +183,10 @@ public class CacheProvider { var acLast = automationCompositions.get(instanceId); Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>(); for (var element : participantDeploy.getAcElementList()) { - var acElement = new AutomationCompositionElement(); - acElement.setId(element.getId()); + var acElement = createAutomationCompositionElement(element); acElement.setParticipantId(getParticipantId()); - acElement.setDefinition(element.getDefinition()); acElement.setDeployState(deployState); - acElement.setLockState(LockState.NONE); acElement.setSubState(subState); - acElement.setProperties(element.getProperties()); var acElementLast = acLast != null ? acLast.getElements().get(element.getId()) : null; if (acElementLast != null) { acElement.setOutProperties(acElementLast.getOutProperties()); @@ -249,6 +247,22 @@ public class CacheProvider { } /** + * Create AutomationCompositionElement to save in memory. + * + * @param element AcElementDeploy + * @return a new AutomationCompositionElement + */ + public static AutomationCompositionElement createAutomationCompositionElement(AcElementDeploy element) { + var acElement = new AutomationCompositionElement(); + acElement.setId(element.getId()); + acElement.setDefinition(element.getDefinition()); + acElement.setProperties(element.getProperties()); + acElement.setSubState(SubState.NONE); + acElement.setLockState(LockState.LOCKED); + return acElement; + } + + /** * Create CompositionElementDto. * * @param compositionId the composition Id @@ -302,4 +316,27 @@ public class CacheProvider { } return map; } + + /** + * Create a new InstanceElementDto record with state New. + * + * @param instanceElement the InstanceElementDto + * @return a new InstanceElementDto + */ + public static InstanceElementDto changeStateToNew(InstanceElementDto instanceElement) { + return new InstanceElementDto(instanceElement.instanceId(), instanceElement.elementId(), + instanceElement.toscaServiceTemplateFragment(), + instanceElement.inProperties(), instanceElement.outProperties(), ElementState.NEW); + } + + /** + * Create a new CompositionElementDto record with state New. + * + * @param compositionElement the CompositionElementDto + * @return a new CompositionElementDto + */ + public static CompositionElementDto changeStateToNew(CompositionElementDto compositionElement) { + return new CompositionElementDto(compositionElement.compositionId(), compositionElement.elementDefinitionId(), + compositionElement.inProperties(), compositionElement.outProperties(), ElementState.NEW); + } } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java index 24b7f3adc..9a43bf4c3 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java @@ -53,7 +53,7 @@ public class ThreadHandler implements Closeable { private final ParticipantIntermediaryApi intermediaryApi; private final CacheProvider cacheProvider; - private final Map<UUID, Future> executionMap = new ConcurrentHashMap<>(); + private final Map<UUID, Future<?>> executionMap = new ConcurrentHashMap<>(); private final ExecutorService executor = Context.taskWrapping(Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors())); @@ -295,21 +295,24 @@ public class ThreadHandler implements Closeable { * @param compositionElementTarget the information of the Automation Composition Definition Element Target * @param instanceElement the information of the Automation Composition Instance Element * @param instanceElementMigrate the information of the Automation Composition Instance Element updated + * @param stage the stage */ public void migrate(UUID messageId, CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, - InstanceElementDto instanceElementMigrate) { + InstanceElementDto instanceElementMigrate, int stage) { cleanExecution(instanceElement.elementId(), messageId); var result = executor.submit(() -> - this.migrateProcess(compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate)); + this.migrateProcess(compositionElement, compositionElementTarget, + instanceElement, instanceElementMigrate, stage)); executionMap.put(instanceElement.elementId(), result); } private void migrateProcess(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, - InstanceElementDto instanceElementMigrate) { + InstanceElementDto instanceElementMigrate, int stage) { try { - listener.migrate(compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate, 0); + listener.migrate(compositionElement, compositionElementTarget, + instanceElement, instanceElementMigrate, stage); } catch (PfModelException e) { LOGGER.error("Automation composition element migrate failed {} {}", instanceElement.elementId(), e.getMessage()); diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2Test.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2Test.java index be8275ca6..a6cb7b005 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2Test.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/AcElementListenerV2Test.java @@ -134,7 +134,7 @@ class AcElementListenerV2Test { var compositionElement = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), Map.of(), Map.of()); var instanceElement = new InstanceElementDto(UUID.randomUUID(), UUID.randomUUID(), null, Map.of(), Map.of()); - acElementListenerV2.migrate(compositionElement, compositionElement, instanceElement, instanceElement); + acElementListenerV2.migrate(compositionElement, compositionElement, instanceElement, instanceElement, 0); verify(intermediaryApi).updateAutomationCompositionElementState(instanceElement.instanceId(), instanceElement.elementId(), DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandlerTest.java index 293a4415b..8fad1d22b 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandlerTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcSubStateHandlerTest.java @@ -28,11 +28,13 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition; import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionMigration; @@ -64,37 +66,70 @@ class AcSubStateHandlerTest { @Test void handleAcMigrationPrecheckTest() { - var listener = mock(ThreadHandler.class); - var cacheProvider = mock(CacheProvider.class); - var ach = new AcSubStateHandler(cacheProvider, listener); + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setCompositionId(UUID.randomUUID()); + automationComposition.setInstanceId(UUID.randomUUID()); + automationComposition.setCompositionTargetId(UUID.randomUUID()); + var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters()); + var definitions = + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); + cacheProvider.addElementDefinition(automationComposition.getCompositionId(), definitions); + cacheProvider.addElementDefinition(automationComposition.getCompositionTargetId(), definitions); + var participantDeploy = + CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), automationComposition); + cacheProvider.initializeAutomationComposition(automationComposition.getCompositionId(), + automationComposition.getInstanceId(), participantDeploy); var migrationMsg = new AutomationCompositionMigration(); + migrationMsg.setStage(0); + migrationMsg.setCompositionId(automationComposition.getCompositionId()); + migrationMsg.setAutomationCompositionId(automationComposition.getInstanceId()); + migrationMsg.setCompositionTargetId(automationComposition.getCompositionTargetId()); + migrationMsg.setParticipantUpdatesList(List.of(participantDeploy)); migrationMsg.setPrecheck(true); - assertDoesNotThrow(() -> ach.handleAcMigrationPrecheck(migrationMsg)); + var listener = mock(ThreadHandler.class); + var ach = new AcSubStateHandler(cacheProvider, listener); + ach.handleAcMigrationPrecheck(migrationMsg); + verify(listener, times(automationComposition.getElements().size())) + .migratePrecheck(any(), any(), any(), any(), any()); + } + + @Test + void handleAcMigrationPrecheckAddRemoveTest() { var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); - migrationMsg.setCompositionTargetId(UUID.randomUUID()); - migrationMsg.setAutomationCompositionId(automationComposition.getInstanceId()); - assertDoesNotThrow(() -> ach.handleAcMigrationPrecheck(migrationMsg)); - when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) - .thenReturn(automationComposition); - var participantDeploy = new ParticipantDeploy(); - participantDeploy.setParticipantId(CommonTestData.getParticipantId()); - when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); - migrationMsg.getParticipantUpdatesList().add(participantDeploy); - Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>(); - for (var element : automationComposition.getElements().values()) { - var acElementDeploy = new AcElementDeploy(); - acElementDeploy.setProperties(Map.of()); - acElementDeploy.setId(element.getId()); - acElementDeploy.setDefinition(element.getDefinition()); - participantDeploy.getAcElementList().add(acElementDeploy); - map.put(element.getDefinition(), new AutomationCompositionElementDefinition()); - } - when(cacheProvider.getAcElementsDefinitions()) - .thenReturn(Map.of(automationComposition.getCompositionId(), map, - migrationMsg.getCompositionTargetId(), map)); + automationComposition.setCompositionId(UUID.randomUUID()); + automationComposition.setInstanceId(UUID.randomUUID()); + var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters()); + var definitions = + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); + cacheProvider.addElementDefinition(automationComposition.getCompositionId(), definitions); + var participantDeploy = + CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), automationComposition); + cacheProvider.initializeAutomationComposition(automationComposition.getCompositionId(), + automationComposition.getInstanceId(), participantDeploy); + + var acMigrate = new AutomationComposition(automationComposition); + acMigrate.setCompositionTargetId(UUID.randomUUID()); + + // replacing first element with new one + var element = acMigrate.getElements().values().iterator().next(); + element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.0.0")); + element.setId(UUID.randomUUID()); + + var migrateDefinitions = + CommonTestData.createAutomationCompositionElementDefinitionList(acMigrate); + cacheProvider.addElementDefinition(acMigrate.getCompositionTargetId(), migrateDefinitions); + var migrationMsg = new AutomationCompositionMigration(); + migrationMsg.setStage(0); + migrationMsg.setCompositionId(acMigrate.getCompositionId()); + migrationMsg.setAutomationCompositionId(acMigrate.getInstanceId()); + migrationMsg.setCompositionTargetId(acMigrate.getCompositionTargetId()); + var participantMigrate = CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), acMigrate); + migrationMsg.setParticipantUpdatesList(List.of(participantMigrate)); + var listener = mock(ThreadHandler.class); + var ach = new AcSubStateHandler(cacheProvider, listener); ach.handleAcMigrationPrecheck(migrationMsg); - verify(listener, times(automationComposition.getElements().size())) + verify(listener, times(acMigrate.getElements().size() + 1)) .migratePrecheck(any(), any(), any(), any(), any()); } diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java index 5973508a8..7f21264b2 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java @@ -23,12 +23,14 @@ package org.onap.policy.clamp.acm.participant.intermediary.handler; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; import org.junit.jupiter.api.Test; @@ -197,57 +199,82 @@ class AutomationCompositionHandlerTest { } @Test - void handleAutomationCompositionMigrationTest() { - var listener = mock(ThreadHandler.class); - var cacheProvider = mock(CacheProvider.class); - var ach = new AutomationCompositionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); + void handleMigrationNullTest() { + var ach = new AutomationCompositionHandler( + mock(CacheProvider.class), mock(ParticipantMessagePublisher.class), mock(ThreadHandler.class)); var migrationMsg = new AutomationCompositionMigration(); + migrationMsg.setStage(0); assertDoesNotThrow(() -> ach.handleAutomationCompositionMigration(migrationMsg)); - var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); - + migrationMsg.setAutomationCompositionId(UUID.randomUUID()); + migrationMsg.setCompositionTargetId(UUID.randomUUID()); assertDoesNotThrow(() -> ach.handleAutomationCompositionMigration(migrationMsg)); - when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) - .thenReturn(automationComposition); - when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); - - Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>(); - var participantDeploy = new ParticipantDeploy(); - populateMigrationMsg(automationComposition, migrationMsg, map, participantDeploy); - when(cacheProvider.getAcElementsDefinitions()) - .thenReturn(Map.of(automationComposition.getCompositionId(), map, - migrationMsg.getCompositionTargetId(), map)); + } + @Test + void handleAutomationCompositionMigrationTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setCompositionId(UUID.randomUUID()); + automationComposition.setInstanceId(UUID.randomUUID()); + automationComposition.setCompositionTargetId(UUID.randomUUID()); + var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters()); + var definitions = + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); + cacheProvider.addElementDefinition(automationComposition.getCompositionId(), definitions); + cacheProvider.addElementDefinition(automationComposition.getCompositionTargetId(), definitions); + var participantDeploy = + CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), automationComposition); + cacheProvider.initializeAutomationComposition(automationComposition.getCompositionId(), + automationComposition.getInstanceId(), participantDeploy); + var migrationMsg = new AutomationCompositionMigration(); + migrationMsg.setStage(0); + migrationMsg.setCompositionId(automationComposition.getCompositionId()); + migrationMsg.setAutomationCompositionId(automationComposition.getInstanceId()); + migrationMsg.setCompositionTargetId(automationComposition.getCompositionTargetId()); + migrationMsg.setParticipantUpdatesList(List.of(participantDeploy)); + var listener = mock(ThreadHandler.class); + var ach = new AutomationCompositionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); ach.handleAutomationCompositionMigration(migrationMsg); - verify(listener, times(automationComposition.getElements().size() + 1)) - .migrate(any(), any(), any(), any(), any()); + verify(listener, times(automationComposition.getElements().size())) + .migrate(any(), any(), any(), any(), any(), anyInt()); } - private void populateMigrationMsg(AutomationComposition automationComposition, - AutomationCompositionMigration migrationMsg, - Map<ToscaConceptIdentifier, - AutomationCompositionElementDefinition> map, - ParticipantDeploy participantDeploy) { + @Test + void handleMigrationAddRemoveTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + automationComposition.setCompositionId(UUID.randomUUID()); + automationComposition.setInstanceId(UUID.randomUUID()); + var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters()); + var definitions = + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); + cacheProvider.addElementDefinition(automationComposition.getCompositionId(), definitions); + var participantDeploy = + CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), automationComposition); + cacheProvider.initializeAutomationComposition(automationComposition.getCompositionId(), + automationComposition.getInstanceId(), participantDeploy); - participantDeploy.setParticipantId(CommonTestData.getParticipantId()); - migrationMsg.setCompositionTargetId(UUID.randomUUID()); - migrationMsg.setAutomationCompositionId(automationComposition.getInstanceId()); - migrationMsg.getParticipantUpdatesList().add(participantDeploy); - for (var element : automationComposition.getElements().values()) { - var acElementDeploy = new AcElementDeploy(); - acElementDeploy.setProperties(Map.of()); - acElementDeploy.setId(element.getId()); - acElementDeploy.setDefinition(element.getDefinition()); - participantDeploy.getAcElementList().add(acElementDeploy); - map.put(element.getDefinition(), new AutomationCompositionElementDefinition()); - } - // remove an element - participantDeploy.getAcElementList().remove(0); - // Add a new element - var acElementDeploy = new AcElementDeploy(); - acElementDeploy.setProperties(Map.of()); - acElementDeploy.setId(UUID.randomUUID()); - acElementDeploy.setDefinition(new ToscaConceptIdentifier("1.2.3", "policy.clamp.new.element")); - participantDeploy.getAcElementList().add(acElementDeploy); + var acMigrate = new AutomationComposition(automationComposition); + acMigrate.setCompositionTargetId(UUID.randomUUID()); + + // replacing first element with new one + var element = acMigrate.getElements().values().iterator().next(); + element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.0.0")); + element.setId(UUID.randomUUID()); + var migrateDefinitions = + CommonTestData.createAutomationCompositionElementDefinitionList(acMigrate); + cacheProvider.addElementDefinition(acMigrate.getCompositionTargetId(), migrateDefinitions); + + var migrationMsg = new AutomationCompositionMigration(); + migrationMsg.setStage(0); + migrationMsg.setCompositionId(acMigrate.getCompositionId()); + migrationMsg.setAutomationCompositionId(acMigrate.getInstanceId()); + migrationMsg.setCompositionTargetId(acMigrate.getCompositionTargetId()); + var participantMigrate = CommonTestData.createparticipantDeploy(cacheProvider.getParticipantId(), acMigrate); + migrationMsg.setParticipantUpdatesList(List.of(participantMigrate)); + var listener = mock(ThreadHandler.class); + var ach = new AutomationCompositionHandler(cacheProvider, mock(ParticipantMessagePublisher.class), listener); + ach.handleAutomationCompositionMigration(migrationMsg); + verify(listener, times(acMigrate.getElements().size() + 1)) + .migrate(any(), any(), any(), any(), any(), anyInt()); } } diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java index 27813988d..dd8747ff4 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandlerTest.java @@ -65,11 +65,35 @@ class AutomationCompositionOutHandlerTest { when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) .thenReturn(automationComposition); assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState( - automationComposition.getInstanceId(), UUID.randomUUID(), DeployState.DEPLOYED, null, null, null)); + automationComposition.getInstanceId(), UUID.randomUUID(), DeployState.DEPLOYED, + null, null, null)); var elementId = automationComposition.getElements().values().iterator().next().getId(); assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementState( automationComposition.getInstanceId(), elementId, null, null, null, null)); + + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementStage( + elementId, null, null, 0, null)); + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementStage( + null, elementId, null, 0, null)); + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementStage( + UUID.randomUUID(), elementId, null, 0, null)); + assertDoesNotThrow(() -> acOutHandler.updateAutomationCompositionElementStage( + automationComposition.getInstanceId(), UUID.randomUUID(), null, 0, null)); + } + + @Test + void updateAutomationCompositionElementStageTest() { + var publisher = mock(ParticipantMessagePublisher.class); + var cacheProvider = mock(CacheProvider.class); + var acOutHandler = new AutomationCompositionOutHandler(publisher, cacheProvider); + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + when(cacheProvider.getAutomationComposition(automationComposition.getInstanceId())) + .thenReturn(automationComposition); + var elementId = automationComposition.getElements().values().iterator().next().getId(); + acOutHandler.updateAutomationCompositionElementStage( + automationComposition.getInstanceId(), elementId, StateChangeResult.NO_ERROR, 0, "OK"); + verify(publisher).sendAutomationCompositionAck(any(AutomationCompositionDeployAck.class)); } @Test diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java index 90d011fac..d05471901 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java @@ -117,7 +117,7 @@ class ThreadHandlerTest { var compositionElementTarget = new CompositionElementDto(compositionTargetId, new ToscaConceptIdentifier(), properties, properties); threadHandler.migrate(messageId, compositionElement, compositionElementTarget, - instanceElement, instanceElementUpdated); + instanceElement, instanceElementUpdated, 0); verify(listener, timeout(TIMEOUT)).migrate(compositionElement, compositionElementTarget, instanceElement, instanceElementUpdated, 0); @@ -170,7 +170,7 @@ class ThreadHandlerTest { doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener) .migrate(compositionElement, compositionElementTarget, instanceElement, instanceElementUpdated, 0); threadHandler.migrate(messageId, compositionElement, compositionElementTarget, - instanceElement, instanceElementUpdated); + instanceElement, instanceElementUpdated, 0); verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Automation composition element migrate failed"); |