diff options
author | 2024-03-20 16:17:46 +0000 | |
---|---|---|
committer | 2024-08-06 10:33:25 +0000 | |
commit | a2477d552ad3993989a4f8b7a7adac6686719cf3 (patch) | |
tree | a7acc256cd3967e85ea091bd3646272def3d3d3d /runtime-acm | |
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 'runtime-acm')
3 files changed, 142 insertions, 21 deletions
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java index 51b7b714c..867148d8b 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java @@ -306,8 +306,6 @@ public class AutomationCompositionInstantiationProvider { AcmUtils.setCascadedState(acToBeUpdated, DeployState.DEPLOYED, LockState.LOCKED, SubState.MIGRATION_PRECHECKING); acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR); - // excluding removed element in MIGRATION_PRECHECKING - elementsRemoved.forEach(uuid -> acToBeUpdated.getElements().get(uuid).setSubState(SubState.NONE)); return createInstantiationResponse(automationCompositionProvider.updateAutomationComposition(acToBeUpdated)); } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java index 31cc8babe..d746b331f 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java @@ -145,17 +145,26 @@ public class SupervisionScanner { return; } - if (DeployState.UPDATING.equals(automationComposition.getDeployState()) - || DeployState.MIGRATING.equals(automationComposition.getDeployState()) + if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) { + scanStage(automationComposition, serviceTemplate); + } else if (DeployState.UPDATING.equals(automationComposition.getDeployState()) + || SubState.PREPARING.equals(automationComposition.getSubState()) + || SubState.REVIEWING.equals(automationComposition.getSubState()) || SubState.MIGRATION_PRECHECKING.equals(automationComposition.getSubState())) { - - scanMigrate(automationComposition, serviceTemplate); + simpleScan(automationComposition, serviceTemplate); } else { - scanDeploy(automationComposition, serviceTemplate); + scanWithPhase(automationComposition, serviceTemplate); } } - private void scanDeploy(final AutomationComposition automationComposition, ToscaServiceTemplate serviceTemplate) { + /** + * Scan with startPhase: DEPLOY, UNDEPLOY, LOCK and UNLOCK. + * + * @param automationComposition the AutomationComposition + * @param serviceTemplate the ToscaServiceTemplate + */ + private void scanWithPhase(final AutomationComposition automationComposition, + ToscaServiceTemplate serviceTemplate) { var completed = true; var minSpNotCompleted = 1000; // min startPhase not completed var maxSpNotCompleted = 0; // max startPhase not completed @@ -176,9 +185,6 @@ public class SupervisionScanner { } if (completed) { - LOGGER.debug("automation composition scan: transition state {} {} completed", - automationComposition.getDeployState(), automationComposition.getLockState()); - complete(automationComposition, serviceTemplate); } else { LOGGER.debug("automation composition scan: transition state {} {} not completed", @@ -197,7 +203,31 @@ public class SupervisionScanner { } } - private void scanMigrate(final AutomationComposition automationComposition, ToscaServiceTemplate serviceTemplate) { + /** + * Simple scan: UPDATE, PREPARE, REVIEW, MIGRATE_PRECHECKING. + * + * @param automationComposition the AutomationComposition + * @param serviceTemplate the ToscaServiceTemplate + */ + private void simpleScan(final AutomationComposition automationComposition, ToscaServiceTemplate serviceTemplate) { + var completed = automationComposition.getElements().values().stream() + .filter(element -> AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), + element.getSubState())).findFirst().isEmpty(); + + if (completed) { + complete(automationComposition, serviceTemplate); + } else { + handleTimeout(automationComposition); + } + } + + /** + * Scan with stage: MIGRATE. + * + * @param automationComposition the AutomationComposition + * @param serviceTemplate the ToscaServiceTemplate + */ + private void scanStage(final AutomationComposition automationComposition, ToscaServiceTemplate serviceTemplate) { var completed = true; var minStageNotCompleted = 1000; // min stage not completed for (var element : automationComposition.getElements().values()) { @@ -214,16 +244,12 @@ public class SupervisionScanner { } if (completed) { - LOGGER.debug("automation composition scan: transition state {} {} ", automationComposition.getDeployState(), - automationComposition.getLockState()); - complete(automationComposition, serviceTemplate); } else { LOGGER.debug("automation composition scan: transition from state {} to {} not completed", automationComposition.getDeployState(), automationComposition.getLockState()); - if (DeployState.MIGRATING.equals(automationComposition.getDeployState()) - && minStageNotCompleted != automationComposition.getPhase()) { + if (minStageNotCompleted != automationComposition.getPhase()) { savePahese(automationComposition, minStageNotCompleted); LOGGER.debug("retry message AutomationCompositionMigration"); automationCompositionMigrationPublisher.send(automationComposition, minStageNotCompleted); @@ -235,6 +261,10 @@ public class SupervisionScanner { private void complete(final AutomationComposition automationComposition, ToscaServiceTemplate serviceTemplate) { + LOGGER.debug("automation composition scan: transition state {} {} {} completed", + automationComposition.getDeployState(), automationComposition.getLockState(), + automationComposition.getSubState()); + var deployState = automationComposition.getDeployState(); if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) { // migration scenario @@ -274,6 +304,10 @@ public class SupervisionScanner { } private void handleTimeout(AutomationComposition automationComposition) { + LOGGER.debug("automation composition scan: transition from state {} to {} {} not completed", + automationComposition.getDeployState(), automationComposition.getLockState(), + automationComposition.getSubState()); + if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) { LOGGER.debug("The ac instance is in timeout {}", automationComposition.getInstanceId()); return; diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java index f7ccfe61e..1e3c89091 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java @@ -35,6 +35,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.UUID; +import java.util.function.Consumer; import org.junit.jupiter.api.Test; import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils; import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher; @@ -49,6 +50,7 @@ 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.NodeTemplateState; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; +import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; import org.onap.policy.clamp.models.acm.utils.TimestampHelper; @@ -57,6 +59,8 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; class SupervisionScannerTest { private static final String AC_JSON = "src/test/resources/rest/acm/AutomationCompositionSmoke.json"; + private static final String ELEMENT_NAME = + "org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement"; private static final UUID compositionId = UUID.randomUUID(); @@ -295,8 +299,7 @@ class SupervisionScannerTest { automationComposition.setPhase(0); automationComposition.setCompositionId(compositionId); for (var element : automationComposition.getElements().values()) { - if ("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement" - .equals(element.getDefinition().getName())) { + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { element.setDeployState(DeployState.DEPLOYING); element.setLockState(LockState.NONE); } else { @@ -372,6 +375,93 @@ class SupervisionScannerTest { } @Test + void testSendAutomationCompositionUpdate() { + var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); + automationComposition.setLockState(LockState.LOCKED); + automationComposition.setDeployState(DeployState.UPDATING); + for (var element : automationComposition.getElements().values()) { + element.setSubState(SubState.NONE); + element.setLockState(LockState.LOCKED); + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { + element.setDeployState(DeployState.UPDATING); + } else { + element.setDeployState(DeployState.DEPLOYED); + } + } + testSimpleScan(automationComposition, element -> element.setDeployState(DeployState.DEPLOYED)); + } + + @Test + void testSendAutomationCompositionMigratingPrecheck() { + var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); + automationComposition.setLockState(LockState.LOCKED); + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setSubState(SubState.MIGRATION_PRECHECKING); + for (var element : automationComposition.getElements().values()) { + element.setDeployState(DeployState.DEPLOYED); + element.setSubState(SubState.NONE); + element.setLockState(LockState.LOCKED); + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { + element.setSubState(SubState.MIGRATION_PRECHECKING); + } + } + testSimpleScan(automationComposition, element -> element.setSubState(SubState.NONE)); + } + + @Test + void testSendAutomationCompositionPrepare() { + var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); + automationComposition.setLockState(LockState.NONE); + automationComposition.setDeployState(DeployState.UNDEPLOYED); + automationComposition.setSubState(SubState.PREPARING); + for (var element : automationComposition.getElements().values()) { + element.setDeployState(DeployState.UNDEPLOYED); + element.setSubState(SubState.NONE); + element.setLockState(LockState.NONE); + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { + element.setSubState(SubState.PREPARING); + } + } + testSimpleScan(automationComposition, element -> element.setSubState(SubState.NONE)); + } + + @Test + void testSendAutomationCompositionReview() { + var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); + automationComposition.setLockState(LockState.LOCKED); + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setSubState(SubState.REVIEWING); + for (var element : automationComposition.getElements().values()) { + element.setDeployState(DeployState.DEPLOYED); + element.setSubState(SubState.NONE); + element.setLockState(LockState.LOCKED); + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { + element.setSubState(SubState.REVIEWING); + } + } + testSimpleScan(automationComposition, element -> element.setSubState(SubState.NONE)); + } + + private void testSimpleScan(AutomationComposition automationComposition, Consumer<AutomationCompositionElement> c) { + automationComposition.setLockState(LockState.NONE); + automationComposition.setCompositionId(compositionId); + automationComposition.setLastMsg(TimestampHelper.now()); + var automationCompositionProvider = mock(AutomationCompositionProvider.class); + when(automationCompositionProvider.getAcInstancesInTransition()).thenReturn(List.of(automationComposition)); + + var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner"); + var supervisionScanner = new SupervisionScanner(automationCompositionProvider, createAcDefinitionProvider(), + null, null, + mock(ParticipantSyncPublisher.class), null, acRuntimeParameterGroup); + supervisionScanner.run(); + verify(automationCompositionProvider, times(0)).updateAcState(any()); + + automationComposition.getElements().values().forEach(c); + supervisionScanner.run(); + verify(automationCompositionProvider).updateAcState(any()); + } + + @Test void testSendAutomationCompositionMsgUnlocking() { var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud"); automationComposition.setDeployState(DeployState.DEPLOYED); @@ -379,8 +469,7 @@ class SupervisionScannerTest { automationComposition.setCompositionId(compositionId); automationComposition.setPhase(0); for (var element : automationComposition.getElements().values()) { - if ("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement" - .equals(element.getDefinition().getName())) { + if (ELEMENT_NAME.equals(element.getDefinition().getName())) { element.setDeployState(DeployState.DEPLOYED); element.setLockState(LockState.UNLOCKING); } else { |