diff options
author | rameshiyer27 <ramesh.murugan.iyer@est.tech> | 2024-07-23 18:08:35 +0100 |
---|---|---|
committer | rameshiyer27 <ramesh.murugan.iyer@est.tech> | 2024-07-26 12:43:25 +0100 |
commit | bcc65d6f4268ff437b162324de13ee53bde47ddd (patch) | |
tree | 3b4fbbb23639d6a006da828d7d9400b1d75d3e56 /participant/participant-intermediary | |
parent | 37195c69c99b5987f037a018859b4421cbcbadf2 (diff) |
Support add/remove elements in Migration
Issue-ID: POLICY-4917
Change-Id: I0014b4858dd7e6ac76bfa1184d0b90b52e8649f5
Signed-off-by: zrrmmua <ramesh.murugan.iyer@est.tech>
Diffstat (limited to 'participant/participant-intermediary')
4 files changed, 124 insertions, 18 deletions
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 d203f90cb..51800cef1 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 @@ -25,5 +25,12 @@ import java.util.UUID; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; public record CompositionElementDto(UUID compositionId, ToscaConceptIdentifier elementDefinitionId, - Map<String, Object> inProperties, Map<String, Object> outProperties) { + Map<String, Object> inProperties, Map<String, Object> outProperties, + boolean newElement, boolean removedElement) { + + public CompositionElementDto(UUID compositionId, ToscaConceptIdentifier elementDefinitionId, + Map<String, Object> inProperties, Map<String, Object> outProperties) { + this(compositionId, elementDefinitionId, inProperties, outProperties, false, false); + + } } 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 297af6c43..65a83e222 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 @@ -25,5 +25,11 @@ import java.util.UUID; 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) { + Map<String, Object> inProperties, Map<String, Object> outProperties, + boolean newElement, boolean removedElement) { + + public InstanceElementDto(UUID instanceId, UUID elementId, ToscaServiceTemplate toscaServiceTemplateFragment, + Map<String, Object> inProperties, Map<String, Object> outProperties) { + this(instanceId, elementId, toscaServiceTemplateFragment, inProperties, outProperties, false, false); + } } 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 0f230c0a4..6c560e7fa 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,14 +21,20 @@ 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 lombok.RequiredArgsConstructor; +import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElementDto; 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; 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.LockState; import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; @@ -41,6 +47,7 @@ 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; @@ -186,11 +193,51 @@ public class AutomationCompositionHandler { 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); - acElement.setSubState(SubState.NONE); - acElement.setDefinition(element.getDefinition()); + 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()); + + 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()); + } + } + 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); + } + } + } + + 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; } /** @@ -282,10 +329,34 @@ public class AutomationCompositionHandler { compositionTargetId); var instanceElementMigrateMap = cacheProvider.getInstanceElementDtoMap(automationComposition); + // Call migrate for newly added and updated elements for (var acElement : acElements) { - listener.migrate(messageId, compositionElementMap.get(acElement.getId()), - compositionElementTargetMap.get(acElement.getId()), - instanceElementMap.get(acElement.getId()), instanceElementMigrateMap.get(acElement.getId())); + 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); + + 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())); + } + } + // 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); + + listener.migrate(messageId, compositionElementMap.get(elementId), + compositionDtoTarget, + instanceElementMap.get(elementId), instanceDtoTarget); } } } 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 40e3b1eec..5973508a8 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 @@ -35,6 +35,7 @@ import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher; 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.DeployState; import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; @@ -203,16 +204,34 @@ class AutomationCompositionHandlerTest { var migrationMsg = new AutomationCompositionMigration(); assertDoesNotThrow(() -> ach.handleAutomationCompositionMigration(migrationMsg)); var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); - migrationMsg.setCompositionTargetId(UUID.randomUUID()); - migrationMsg.setAutomationCompositionId(automationComposition.getInstanceId()); + 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)); + + ach.handleAutomationCompositionMigration(migrationMsg); + verify(listener, times(automationComposition.getElements().size() + 1)) + .migrate(any(), any(), any(), any(), any()); + } + + private void populateMigrationMsg(AutomationComposition automationComposition, + AutomationCompositionMigration migrationMsg, + Map<ToscaConceptIdentifier, + AutomationCompositionElementDefinition> map, + ParticipantDeploy participantDeploy) { + participantDeploy.setParticipantId(CommonTestData.getParticipantId()); - when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId()); + migrationMsg.setCompositionTargetId(UUID.randomUUID()); + migrationMsg.setAutomationCompositionId(automationComposition.getInstanceId()); migrationMsg.getParticipantUpdatesList().add(participantDeploy); - Map<ToscaConceptIdentifier, AutomationCompositionElementDefinition> map = new HashMap<>(); for (var element : automationComposition.getElements().values()) { var acElementDeploy = new AcElementDeploy(); acElementDeploy.setProperties(Map.of()); @@ -221,11 +240,14 @@ class AutomationCompositionHandlerTest { participantDeploy.getAcElementList().add(acElementDeploy); map.put(element.getDefinition(), new AutomationCompositionElementDefinition()); } - when(cacheProvider.getAcElementsDefinitions()) - .thenReturn(Map.of(automationComposition.getCompositionId(), map, - migrationMsg.getCompositionTargetId(), map)); + // 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); - ach.handleAutomationCompositionMigration(migrationMsg); - verify(listener, times(automationComposition.getElements().size())).migrate(any(), any(), any(), any(), any()); } } |