From: FrancescoFioraEst Date: Tue, 28 Oct 2025 13:19:12 +0000 (+0000) Subject: Refactor rollback implementation X-Git-Url: https://gerrit.onap.org/r/gitweb?a=commitdiff_plain;h=14bf4bdf5b77fec9a0105cddac2f28e4fb88cf96;p=policy%2Fclamp.git Refactor rollback implementation Issue-ID: POLICY-5471 Change-Id: I55ff837624617999caeb3776235639f37378be10 Signed-off-by: FrancescoFioraEst --- diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java index 1b209d697..b238c5e50 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java @@ -43,7 +43,7 @@ import org.onap.policy.clamp.models.acm.persistence.concepts.JpaAutomationCompos import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionElementRepository; import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionRepository; import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionRollbackRepository; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.parameters.ValidationStatus; import org.onap.policy.models.base.PfConceptKey; @@ -109,7 +109,7 @@ public class AutomationCompositionProvider { */ public AutomationComposition createAutomationComposition(final AutomationComposition automationComposition) { automationComposition.setInstanceId(UUID.randomUUID()); - AcmUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYED, LockState.NONE); + AcmStateUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYED, LockState.NONE); var result = automationCompositionRepository.save(ProviderUtils.getJpaAndValidate(automationComposition, JpaAutomationComposition::new, "automation composition")); diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmStageUtils.java similarity index 56% rename from models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java rename to models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmStageUtils.java index d7069e2f8..9cfade4c2 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmStageUtils.java @@ -1,6 +1,6 @@ /*- * ============LICENSE_START======================================================= - * Copyright (C) 2021-2025 OpenInfra Foundation Europe. All rights reserved. + * Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,35 +18,23 @@ * ============LICENSE_END========================================================= */ -package org.onap.policy.clamp.models.acm.concepts; +package org.onap.policy.clamp.models.acm.utils; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import java.util.stream.Collectors; import lombok.AccessLevel; import lombok.NoArgsConstructor; +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.models.tosca.authorative.concepts.ToscaServiceTemplate; @NoArgsConstructor(access = AccessLevel.PRIVATE) -public final class ParticipantUtils { +public final class AcmStageUtils { private static final String STAGE_MIGRATE = "migrate"; private static final String STAGE_PREPARE = "prepare"; - public static final String DEFAULT_TIMEOUT = "maxOperationWaitMs"; - public static final String PRIME_TIMEOUT = "primeTimeoutMs"; - public static final String DEPRIME_TIMEOUT = "deprimeTimeoutMs"; - public static final String DEPLOY_TIMEOUT = "deployTimeoutMs"; - public static final String UNDEPLOY_TIMEOUT = "undeployTimeoutMs"; - public static final String UPDATE_TIMEOUT = "updateTimeoutMs"; - public static final String MIGRATE_TIMEOUT = "migrateTimeoutMs"; - public static final String DELETE_TIMEOUT = "deleteTimeoutMs"; - - public static final Map MAP_TIMEOUT = Map.of(DeployState.DEPLOYING, DEPLOY_TIMEOUT, - DeployState.UNDEPLOYING, UNDEPLOY_TIMEOUT, - DeployState.UPDATING, UPDATE_TIMEOUT, - DeployState.MIGRATING, MIGRATE_TIMEOUT, - DeployState.DELETING, DELETE_TIMEOUT); /** * Get the First StartPhase. @@ -59,25 +47,25 @@ public final class ParticipantUtils { * @return the First StartPhase */ public static int getFirstStartPhase( - AutomationComposition automationComposition, ToscaServiceTemplate toscaServiceTemplate) { + AutomationComposition automationComposition, ToscaServiceTemplate toscaServiceTemplate) { var minStartPhase = 1000; var maxStartPhase = 0; for (var element : automationComposition.getElements().values()) { var toscaNodeTemplate = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates() - .get(element.getDefinition().getName()); + .get(element.getDefinition().getName()); int startPhase = toscaNodeTemplate != null && element.getDefinition().getVersion().equals(toscaNodeTemplate.getVersion()) - ? ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties()) : 0; + ? findStartPhase(toscaNodeTemplate.getProperties()) : 0; minStartPhase = Math.min(minStartPhase, startPhase); maxStartPhase = Math.max(maxStartPhase, startPhase); } - return DeployState.DEPLOYING.equals(automationComposition.getDeployState()) - || LockState.UNLOCKING.equals(automationComposition.getLockState()) ? minStartPhase : maxStartPhase; + return AcmStateUtils.isForward(automationComposition.getDeployState(), automationComposition.getLockState()) + ? minStartPhase : maxStartPhase; } /** - * Get the First Stage. + * Get the First Stage from AutomationComposition. * * @param automationComposition the automation composition * @param toscaServiceTemplate the ToscaServiceTemplate @@ -85,19 +73,39 @@ public final class ParticipantUtils { */ public static int getFirstStage(AutomationComposition automationComposition, ToscaServiceTemplate toscaServiceTemplate) { - Set minStage = new HashSet<>(); - for (var element : automationComposition.getElements().values()) { - if (! MigrationState.REMOVED.equals(element.getMigrationState())) { - var toscaNodeTemplate = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates() - .get(element.getDefinition().getName()); - var stage = DeployState.MIGRATING.equals(automationComposition.getDeployState()) - ? ParticipantUtils.findStageSetMigrate(toscaNodeTemplate.getProperties()) - : ParticipantUtils.findStageSetPrepare(toscaNodeTemplate.getProperties()); - minStage.addAll(stage); - } + var stages = automationComposition.getElements().values().stream() + .map(element -> getFirstStage(element, toscaServiceTemplate)); + return stages.min(Integer::compare).orElse(0); + } + /** + * Get the First Stage from AutomationCompositionElement. + * + * @param element the automation composition element + * @param toscaServiceTemplate the ToscaServiceTemplate + * @return the First stage + */ + public static int getFirstStage(AutomationCompositionElement element, ToscaServiceTemplate toscaServiceTemplate) { + var toscaNodeTemplate = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates() + .get(element.getDefinition().getName()); + if (toscaNodeTemplate == null) { + return 0; } - return minStage.stream().min(Integer::compare).orElse(0); + return getFirstStage(element.getDeployState(), toscaNodeTemplate.getProperties()); + } + + /** + * Get the First Stage. + * + * @param deployState the DeployState + * @param properties Map of properties + * @return the First stage + */ + public static int getFirstStage(DeployState deployState, Map properties) { + var stageSet = AcmStateUtils.isMigrating(deployState) + ? findStageSetMigrate(properties) + : findStageSetPrepare(properties); + return stageSet.stream().min(Integer::compare).orElse(0); } /** @@ -129,42 +137,6 @@ public final class ParticipantUtils { return Set.of(0); } - /** - * Get timeout value from properties by name operation, return default value if not present. - * - * @param properties instance properties - * @param name the operation name - * @param defaultValue the default value - * @return the timeout value - */ - public static long getTimeout(Map properties, String name, long defaultValue) { - var objTimeout = properties.get(name); - if (objTimeout != null) { - return Long.parseLong(objTimeout.toString()); - } - return defaultValue; - } - - /** - * Get operation name of a composition definition. - * - * @param state the state of the composition definition - * @return the operation name - */ - public static String getOpName(AcTypeState state) { - return AcTypeState.PRIMING.equals(state) ? PRIME_TIMEOUT : DEPRIME_TIMEOUT; - } - - /** - * Get operation name of a AutomationComposition. - * - * @param deployState the state of the AutomationComposition - * @return the operation name - */ - public static String getOpName(DeployState deployState) { - return MAP_TIMEOUT.getOrDefault(deployState, DEFAULT_TIMEOUT); - } - /** * Finds stage from a map of properties for Migrate. * diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmStateUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmStateUtils.java new file mode 100644 index 000000000..1ac15c50e --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmStateUtils.java @@ -0,0 +1,195 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved. + * ================================================================================ + * 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.models.acm.utils; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.apache.commons.collections4.MapUtils; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +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.SubState; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class AcmStateUtils { + + /** + * Return true if DeployState, LockState and SubState are in a Transitional State. + * + * @param deployState the DeployState + * @param lockState the LockState + * @param subState the SubState + * @return true if there is a state in a Transitional State + */ + public static boolean isInTransitionalState(DeployState deployState, LockState lockState, SubState subState) { + return DeployState.DEPLOYING.equals(deployState) || DeployState.UNDEPLOYING.equals(deployState) + || LockState.LOCKING.equals(lockState) || LockState.UNLOCKING.equals(lockState) + || DeployState.DELETING.equals(deployState) || DeployState.UPDATING.equals(deployState) + || DeployState.MIGRATING.equals(deployState) || DeployState.MIGRATION_REVERTING.equals(deployState) + || !SubState.NONE.equals(subState); + } + + /** + * Return true if AcTypeState is in a Transitional State. + * + * @param compositionState the AcTypeState + * @return true if the state in a Transitional State + */ + public static boolean isInTransitionalState(AcTypeState compositionState) { + return AcTypeState.PRIMING.equals(compositionState) + || AcTypeState.DEPRIMING.equals(compositionState); + } + + /** + * Get DeployOrder from transitional DeployState. + * + * @param deployState the Deploy State + * @return the DeployOrder + */ + public static DeployOrder stateDeployToOrder(DeployState deployState) { + return switch (deployState) { + case DEPLOYING -> DeployOrder.DEPLOY; + case UNDEPLOYING -> DeployOrder.UNDEPLOY; + case DELETING -> DeployOrder.DELETE; + default -> DeployOrder.NONE; + }; + } + + /** + * Get LockOrder from transitional LockState. + * + * @param lockState the Lock State + * @return the LockOrder + */ + public static LockOrder stateLockToOrder(LockState lockState) { + if (LockState.LOCKING.equals(lockState)) { + return LockOrder.LOCK; + } else if (LockState.UNLOCKING.equals(lockState)) { + return LockOrder.UNLOCK; + } + return LockOrder.NONE; + } + + /** + * Get final DeployState from transitional DeployState. + * + * @param deployState the DeployState + * @return the DeployState + */ + public static DeployState deployCompleted(DeployState deployState) { + return switch (deployState) { + case MIGRATING, MIGRATION_REVERTING, UPDATING, DEPLOYING -> DeployState.DEPLOYED; + case UNDEPLOYING -> DeployState.UNDEPLOYED; + case DELETING -> DeployState.DELETED; + default -> deployState; + }; + } + + /** + * Get final LockState from transitional LockState. + * + * @param lockState the LockState + * @return the LockState + */ + public static LockState lockCompleted(DeployState deployState, LockState lockState) { + if (LockState.LOCKING.equals(lockState) || DeployState.DEPLOYING.equals(deployState)) { + return LockState.LOCKED; + } else if (LockState.UNLOCKING.equals(lockState)) { + return LockState.UNLOCKED; + } else if (DeployState.UNDEPLOYING.equals(deployState)) { + return LockState.NONE; + } + return lockState; + } + + /** + * Return true if transition states is Forward. + * + * @param deployState the DeployState + * @param lockState the LockState + * @return true if transition is Forward + */ + public static boolean isForward(DeployState deployState, LockState lockState) { + return DeployState.DEPLOYING.equals(deployState) || LockState.UNLOCKING.equals(lockState); + } + + /** + * Return true if migration states is Forward. + * + * @param deployState the DeployState + * @return true if migration is Forward + */ + public static boolean isMigrationForward(DeployState deployState) { + return DeployState.MIGRATING.equals(deployState); + } + + /** + * Return true if the transition is MIGRATING or MIGRATION_REVERTING. + * + * @param deployState the DeployState + * @return true if the transition is MIGRATING or MIGRATION_REVERTING + */ + public static boolean isMigrating(DeployState deployState) { + return DeployState.MIGRATING.equals(deployState) || DeployState.MIGRATION_REVERTING.equals(deployState); + } + + /** + * Set the states on the automation composition and on all its automation composition elements. + * + * @param deployState the DeployState we want the automation composition to transition to + * @param lockState the LockState we want the automation composition to transition to + */ + public static void setCascadedState(final AutomationComposition automationComposition, + final DeployState deployState, final LockState lockState) { + setCascadedState(automationComposition, deployState, lockState, SubState.NONE); + } + + /** + /** + * Set the states on the automation composition and on all its automation composition elements. + * + * @param deployState the DeployState we want the automation composition to transition to + * @param lockState the LockState we want the automation composition to transition to + * @param subState the SubState we want the automation composition to transition to + */ + public static void setCascadedState(final AutomationComposition automationComposition, + final DeployState deployState, final LockState lockState, final SubState subState) { + automationComposition.setDeployState(deployState); + automationComposition.setLockState(lockState); + automationComposition.setLastMsg(TimestampHelper.now()); + automationComposition.setSubState(subState); + + if (MapUtils.isEmpty(automationComposition.getElements())) { + return; + } + + for (var element : automationComposition.getElements().values()) { + element.setDeployState(deployState); + element.setLockState(lockState); + element.setSubState(subState); + element.setMessage(null); + element.setStage(null); + } + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmTimeoutUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmTimeoutUtils.java new file mode 100644 index 000000000..bd2155382 --- /dev/null +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmTimeoutUtils.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved. + * ================================================================================ + * 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.models.acm.utils; + +import java.util.Map; +import lombok.AccessLevel; +import lombok.NoArgsConstructor; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +import org.onap.policy.clamp.models.acm.concepts.DeployState; + +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public final class AcmTimeoutUtils { + public static final String DEFAULT_TIMEOUT = "maxOperationWaitMs"; + public static final String PRIME_TIMEOUT = "primeTimeoutMs"; + public static final String DEPRIME_TIMEOUT = "deprimeTimeoutMs"; + public static final String DEPLOY_TIMEOUT = "deployTimeoutMs"; + public static final String UNDEPLOY_TIMEOUT = "undeployTimeoutMs"; + public static final String UPDATE_TIMEOUT = "updateTimeoutMs"; + public static final String MIGRATE_TIMEOUT = "migrateTimeoutMs"; + public static final String DELETE_TIMEOUT = "deleteTimeoutMs"; + + public static final Map MAP_TIMEOUT = Map.of(DeployState.DEPLOYING, DEPLOY_TIMEOUT, + DeployState.UNDEPLOYING, UNDEPLOY_TIMEOUT, + DeployState.UPDATING, UPDATE_TIMEOUT, + DeployState.MIGRATING, MIGRATE_TIMEOUT, + DeployState.DELETING, DELETE_TIMEOUT); + + /** + * Get timeout value from properties by name operation, return default value if not present. + * + * @param properties instance properties + * @param name the operation name + * @param defaultValue the default value + * @return the timeout value + */ + public static long getTimeout(Map properties, String name, long defaultValue) { + var objTimeout = properties.get(name); + if (objTimeout != null) { + return Long.parseLong(objTimeout.toString()); + } + return defaultValue; + } + + /** + * Get operation name of a composition definition. + * + * @param state the state of the composition definition + * @return the operation name + */ + public static String getOpName(AcTypeState state) { + return AcTypeState.PRIMING.equals(state) ? PRIME_TIMEOUT : DEPRIME_TIMEOUT; + } + + /** + * Get operation name of a AutomationComposition. + * + * @param deployState the state of the AutomationComposition + * @return the operation name + */ + public static String getOpName(DeployState deployState) { + return MAP_TIMEOUT.getOrDefault(deployState, DEFAULT_TIMEOUT); + } +} diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java index c7bc598f5..1a81fab96 100644 --- a/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java +++ b/models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java @@ -45,16 +45,12 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; 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.LockState; import org.onap.policy.clamp.models.acm.concepts.MigrationState; import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState; import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition; import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc; -import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; -import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; import org.onap.policy.clamp.models.acm.persistence.concepts.StringToMapConverter; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.common.parameters.ObjectValidationResult; @@ -199,7 +195,7 @@ public final class AcmUtils { * @return the result of validation */ public static BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition, - ToscaServiceTemplate serviceTemplate, String toscaCompositionName, boolean migrateOperation) { + ToscaServiceTemplate serviceTemplate, String toscaCompositionName, int removeElement) { var result = new BeanValidationResult(ENTRY + automationComposition.getName(), automationComposition); var map = getMapToscaNodeTemplates(serviceTemplate); @@ -222,8 +218,7 @@ public final class AcmUtils { .collect(Collectors.toMap(ToscaConceptIdentifier::getName, UnaryOperator.identity())); // @formatter:on - if (definitions.size() != automationComposition.getElements().size() - && !migrateOperation) { + if (definitions.size() != (automationComposition.getElements().size() - removeElement)) { result.setResult(ValidationStatus.INVALID, "Elements of the instance not matching with the elements of the composition"); } @@ -238,13 +233,15 @@ public final class AcmUtils { } private static ValidationResult validateDefinition(Map definitions, - ToscaConceptIdentifier definition, - MigrationState migrationState) { + ToscaConceptIdentifier definition, MigrationState migrationState) { + if (MigrationState.REMOVED.equals(migrationState)) { + return null; + } var result = new BeanValidationResult(ENTRY + definition.getName(), definition); var identifier = definitions.get(definition.getName()); - if (identifier == null && MigrationState.DEFAULT.equals(migrationState)) { + if (identifier == null) { result.setResult(ValidationStatus.INVALID, "Not found"); - } else if (! definition.equals(identifier) && MigrationState.DEFAULT.equals(migrationState)) { + } else if (! definition.equals(identifier)) { result.setResult(ValidationStatus.INVALID, "Version not matching"); } return (result.isClean() ? null : result); @@ -285,135 +282,6 @@ public final class AcmUtils { // @formatter:on } - - /** - * Return true if DeployState, LockState and SubState are in a Transitional State. - * - * @param deployState the DeployState - * @param lockState the LockState - * @param subState the SubState - * @return true if there is a state in a Transitional State - */ - public static boolean isInTransitionalState(DeployState deployState, LockState lockState, SubState subState) { - return DeployState.DEPLOYING.equals(deployState) || DeployState.UNDEPLOYING.equals(deployState) - || LockState.LOCKING.equals(lockState) || LockState.UNLOCKING.equals(lockState) - || DeployState.DELETING.equals(deployState) || DeployState.UPDATING.equals(deployState) - || DeployState.MIGRATING.equals(deployState) || DeployState.MIGRATION_REVERTING.equals(deployState) - || !SubState.NONE.equals(subState); - } - - /** - * Get DeployOrder from transitional DeployState. - * - * @param deployState the Deploy State - * @return the DeployOrder - */ - public static DeployOrder stateDeployToOrder(DeployState deployState) { - return switch (deployState) { - case DEPLOYING -> DeployOrder.DEPLOY; - case UNDEPLOYING -> DeployOrder.UNDEPLOY; - case DELETING -> DeployOrder.DELETE; - default -> DeployOrder.NONE; - }; - } - - /** - * Get LockOrder from transitional LockState. - * - * @param lockState the Lock State - * @return the LockOrder - */ - public static LockOrder stateLockToOrder(LockState lockState) { - if (LockState.LOCKING.equals(lockState)) { - return LockOrder.LOCK; - } else if (LockState.UNLOCKING.equals(lockState)) { - return LockOrder.UNLOCK; - } - return LockOrder.NONE; - } - - /** - * Get final DeployState from transitional DeployState. - * - * @param deployState the DeployState - * @return the DeployState - */ - public static DeployState deployCompleted(DeployState deployState) { - return switch (deployState) { - case MIGRATING, MIGRATION_REVERTING, UPDATING, DEPLOYING -> DeployState.DEPLOYED; - case UNDEPLOYING -> DeployState.UNDEPLOYED; - case DELETING -> DeployState.DELETED; - default -> deployState; - }; - } - - /** - * Get final LockState from transitional LockState. - * - * @param lockState the LockState - * @return the LockState - */ - public static LockState lockCompleted(DeployState deployState, LockState lockState) { - if (LockState.LOCKING.equals(lockState) || DeployState.DEPLOYING.equals(deployState)) { - return LockState.LOCKED; - } else if (LockState.UNLOCKING.equals(lockState)) { - return LockState.UNLOCKED; - } else if (DeployState.UNDEPLOYING.equals(deployState)) { - return LockState.NONE; - } - return lockState; - } - - /** - * Return true if transition states is Forward. - * - * @param deployState the DeployState - * @param lockState the LockState - * @return true if transition if Forward - */ - public static boolean isForward(DeployState deployState, LockState lockState) { - return DeployState.DEPLOYING.equals(deployState) || LockState.UNLOCKING.equals(lockState); - } - - /** - * Set the states on the automation composition and on all its automation composition elements. - * - * @param deployState the DeployState we want the automation composition to transition to - * @param lockState the LockState we want the automation composition to transition to - */ - public static void setCascadedState(final AutomationComposition automationComposition, - final DeployState deployState, final LockState lockState) { - setCascadedState(automationComposition, deployState, lockState, SubState.NONE); - } - - /** - /** - * Set the states on the automation composition and on all its automation composition elements. - * - * @param deployState the DeployState we want the automation composition to transition to - * @param lockState the LockState we want the automation composition to transition to - * @param subState the SubState we want the automation composition to transition to - */ - public static void setCascadedState(final AutomationComposition automationComposition, - final DeployState deployState, final LockState lockState, final SubState subState) { - automationComposition.setDeployState(deployState); - automationComposition.setLockState(lockState); - automationComposition.setLastMsg(TimestampHelper.now()); - automationComposition.setSubState(subState); - - if (MapUtils.isEmpty(automationComposition.getElements())) { - return; - } - - for (var element : automationComposition.getElements().values()) { - element.setDeployState(deployState); - element.setLockState(lockState); - element.setSubState(subState); - element.setMessage(null); - element.setStage(null); - } - } - /** * Create a new AcElementDeploy from an AutomationCompositionElement. * diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java deleted file mode 100644 index c460d4deb..000000000 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/concepts/ParticipantUtilsTest.java +++ /dev/null @@ -1,185 +0,0 @@ -/*- - * ============LICENSE_START======================================================= - * Copyright (C) 2021-2023,2025 OpenInfra Foundation Europe. All rights reserved. - * ================================================================================ - * 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.models.acm.concepts; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Map; -import org.junit.jupiter.api.Test; -import org.onap.policy.clamp.models.acm.utils.CommonTestData; -import org.onap.policy.common.utils.coder.Coder; -import org.onap.policy.common.utils.coder.CoderException; -import org.onap.policy.common.utils.coder.StandardCoder; -import org.onap.policy.common.utils.resources.ResourceUtils; - -class ParticipantUtilsTest { - - private static final Coder CODER = new StandardCoder(); - private static final String TOSCA_TEMPLATE_YAML = "examples/acm/test-pm-subscription-handling.yaml"; - private static final String AUTOMATION_COMPOSITION_JSON = - "src/test/resources/providers/TestAutomationCompositions.json"; - - private static final String PROPERTIES = """ - stage: - prepare: [1,2] - migrate: [2,3] - """; - - - @Test - void testFindStartPhase() { - var identifier = 13; - var result = ParticipantUtils.findStartPhase(Map.of("startPhase", identifier)); - assertThat(result).isEqualTo(identifier); - } - - @Test - void testGetFirstStartPhase() throws CoderException { - var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); - var automationComposition = - CODER.decode(ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON), AutomationCompositions.class) - .getAutomationCompositionList().get(0); - automationComposition.setDeployState(DeployState.DEPLOYING); - automationComposition.setLockState(LockState.NONE); - var result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); - assertThat(result).isZero(); - - automationComposition.setDeployState(DeployState.DEPLOYED); - automationComposition.setLockState(LockState.UNLOCKING); - result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); - assertThat(result).isZero(); - - automationComposition.setDeployState(DeployState.UNDEPLOYING); - automationComposition.setLockState(LockState.NONE); - result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); - assertThat(result).isEqualTo(1); - } - - @Test - void testGetFirstStartPhaseWithNull() throws CoderException { - var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); - var automationComposition = - CODER.decode(ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON), AutomationCompositions.class) - .getAutomationCompositionList().get(0); - automationComposition.setDeployState(DeployState.DEPLOYING); - automationComposition.setLockState(LockState.NONE); - - serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().values() - .forEach(node -> node.setVersion("0.0.0")); - var result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); - assertThat(result).isZero(); - - automationComposition.setDeployState(DeployState.DEPLOYED); - automationComposition.setLockState(LockState.UNLOCKING); - result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); - assertThat(result).isZero(); - - automationComposition.setDeployState(DeployState.UNDEPLOYING); - automationComposition.setLockState(LockState.NONE); - result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); - assertThat(result).isZero(); - - serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().clear(); - result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); - assertThat(result).isZero(); - - automationComposition.setDeployState(DeployState.DEPLOYED); - automationComposition.setLockState(LockState.UNLOCKING); - result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); - assertThat(result).isZero(); - - automationComposition.setDeployState(DeployState.UNDEPLOYING); - automationComposition.setLockState(LockState.NONE); - result = ParticipantUtils.getFirstStartPhase(automationComposition, serviceTemplate); - assertThat(result).isZero(); - } - - @Test - void testGetFirstStage() throws CoderException { - var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); - var automationComposition = - CODER.decode(ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON), AutomationCompositions.class) - .getAutomationCompositionList().get(0); - automationComposition.setDeployState(DeployState.MIGRATING); - var result = ParticipantUtils.getFirstStage(automationComposition, serviceTemplate); - assertThat(result).isZero(); - - automationComposition.setDeployState(DeployState.UNDEPLOYED); - automationComposition.setSubState(SubState.PREPARING); - result = ParticipantUtils.getFirstStage(automationComposition, serviceTemplate); - assertThat(result).isZero(); - } - - @Test - void testFindStageSetPrepare() { - var result = ParticipantUtils.findStageSetPrepare(Map.of()); - assertThat(result).hasSize(1).contains(0); - result = ParticipantUtils.findStageSetPrepare(Map.of("stage", 1)); - assertThat(result).hasSize(1).contains(0); - - Map map = CommonTestData.getObject(PROPERTIES, Map.class); - result = ParticipantUtils.findStageSetPrepare(map); - assertThat(result).hasSize(2).contains(1).contains(2); - } - - @Test - void testFindStageSetMigrate() { - var result = ParticipantUtils.findStageSetMigrate(Map.of()); - assertThat(result).hasSize(1).contains(0); - result = ParticipantUtils.findStageSetMigrate(Map.of("stage", 1)); - assertThat(result).hasSize(1).contains(0); - - Map map = CommonTestData.getObject(PROPERTIES, Map.class); - result = ParticipantUtils.findStageSetMigrate(map); - assertThat(result).hasSize(2).contains(2).contains(3); - } - - @Test - void testGetTimeout() { - var result = ParticipantUtils.getTimeout(Map.of(), ParticipantUtils.DEPLOY_TIMEOUT, 1000); - assertEquals(1000, result); - - result = ParticipantUtils.getTimeout(Map.of(ParticipantUtils.DEPLOY_TIMEOUT, 20000), - ParticipantUtils.DEPLOY_TIMEOUT, 1000); - assertEquals(20000, result); - } - - @Test - void testGetOpName() { - var result = ParticipantUtils.getOpName(AcTypeState.PRIMING); - assertEquals(ParticipantUtils.PRIME_TIMEOUT, result); - result = ParticipantUtils.getOpName(AcTypeState.DEPRIMING); - assertEquals(ParticipantUtils.DEPRIME_TIMEOUT, result); - result = ParticipantUtils.getOpName(DeployState.DEPLOYING); - assertEquals(ParticipantUtils.DEPLOY_TIMEOUT, result); - result = ParticipantUtils.getOpName(DeployState.UNDEPLOYING); - assertEquals(ParticipantUtils.UNDEPLOY_TIMEOUT, result); - result = ParticipantUtils.getOpName(DeployState.UPDATING); - assertEquals(ParticipantUtils.UPDATE_TIMEOUT, result); - result = ParticipantUtils.getOpName(DeployState.DELETING); - assertEquals(ParticipantUtils.DELETE_TIMEOUT, result); - result = ParticipantUtils.getOpName(DeployState.MIGRATING); - assertEquals(ParticipantUtils.MIGRATE_TIMEOUT, result); - result = ParticipantUtils.getOpName(DeployState.DEPLOYED); - assertEquals(ParticipantUtils.DEFAULT_TIMEOUT, result); - } -} diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmStageUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmStageUtilsTest.java new file mode 100644 index 000000000..fbcb5686c --- /dev/null +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmStageUtilsTest.java @@ -0,0 +1,157 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved. + * ================================================================================ + * 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.models.acm.utils; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; +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.SubState; +import org.onap.policy.common.utils.resources.ResourceUtils; + +class AcmStageUtilsTest { + + private static final String TOSCA_TEMPLATE_YAML = "examples/acm/test-pm-subscription-handling.yaml"; + private static final String AUTOMATION_COMPOSITION_JSON = + "src/test/resources/providers/TestAutomationCompositions.json"; + + private static final String PROPERTIES = """ + stage: + prepare: [1,2] + migrate: [2,3] + """; + + @Test + void testFindStartPhase() { + var identifier = 13; + var result = AcmStageUtils.findStartPhase(Map.of("startPhase", identifier)); + assertThat(result).isEqualTo(identifier); + } + + @Test + void testGetFirstStartPhase() { + var automationCompositions = CommonTestData.getJson( + ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON), AutomationCompositions.class); + assertThat(automationCompositions).isNotNull(); + var automationComposition = automationCompositions.getAutomationCompositionList().get(0); + automationComposition.setDeployState(DeployState.DEPLOYING); + automationComposition.setLockState(LockState.NONE); + var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); + var result = AcmStageUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.UNLOCKING); + result = AcmStageUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.UNDEPLOYING); + automationComposition.setLockState(LockState.NONE); + result = AcmStageUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isEqualTo(1); + } + + @Test + void testGetFirstStartPhaseWithNull() { + var automationCompositions = CommonTestData.getJson( + ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON), AutomationCompositions.class); + assertThat(automationCompositions).isNotNull(); + var automationComposition = automationCompositions.getAutomationCompositionList().get(0); + automationComposition.setDeployState(DeployState.DEPLOYING); + automationComposition.setLockState(LockState.NONE); + + var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); + assertThat(serviceTemplate).isNotNull(); + serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().values() + .forEach(node -> node.setVersion("0.0.0")); + var result = AcmStageUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.UNLOCKING); + result = AcmStageUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.UNDEPLOYING); + automationComposition.setLockState(LockState.NONE); + result = AcmStageUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().clear(); + result = AcmStageUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.DEPLOYED); + automationComposition.setLockState(LockState.UNLOCKING); + result = AcmStageUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + automationComposition.setDeployState(DeployState.UNDEPLOYING); + automationComposition.setLockState(LockState.NONE); + result = AcmStageUtils.getFirstStartPhase(automationComposition, serviceTemplate); + assertThat(result).isZero(); + } + + @Test + void testGetFirstStage() { + var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); + var automationCompositions = CommonTestData.getJson( + ResourceUtils.getResourceAsString(AUTOMATION_COMPOSITION_JSON), AutomationCompositions.class); + assertThat(automationCompositions).isNotNull(); + var automationComposition = automationCompositions.getAutomationCompositionList().get(0); + AcmStateUtils.setCascadedState(automationComposition, DeployState.MIGRATING, LockState.LOCKED); + var result = AcmStageUtils.getFirstStage(automationComposition, serviceTemplate); + assertThat(result).isZero(); + + AcmStateUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYED, LockState.NONE); + automationComposition.setSubState(SubState.PREPARING); + result = AcmStageUtils.getFirstStage(automationComposition, serviceTemplate); + assertThat(result).isZero(); + } + + @Test + void testFindStageSetPrepare() { + var result = AcmStageUtils.findStageSetPrepare(Map.of()); + assertThat(result).hasSize(1).contains(0); + result = AcmStageUtils.findStageSetPrepare(Map.of("stage", 1)); + assertThat(result).hasSize(1).contains(0); + + Map map = CommonTestData.getObject(PROPERTIES, Map.class); + result = AcmStageUtils.findStageSetPrepare(map); + assertThat(result).hasSize(2).contains(1).contains(2); + } + + @Test + void testFindStageSetMigrate() { + var result = AcmStageUtils.findStageSetMigrate(Map.of()); + assertThat(result).hasSize(1).contains(0); + result = AcmStageUtils.findStageSetMigrate(Map.of("stage", 1)); + assertThat(result).hasSize(1).contains(0); + + Map map = CommonTestData.getObject(PROPERTIES, Map.class); + result = AcmStageUtils.findStageSetMigrate(map); + assertThat(result).hasSize(2).contains(2).contains(3); + } + +} diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmStateUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmStateUtilsTest.java new file mode 100644 index 000000000..3a6af0357 --- /dev/null +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmStateUtilsTest.java @@ -0,0 +1,117 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved. + * ================================================================================ + * 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.models.acm.utils; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +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.SubState; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; +import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; + +class AcmStateUtilsTest { + + @Test + void testIsInTransitionalState() { + assertFalse(AcmStateUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE)); + assertTrue(AcmStateUtils.isInTransitionalState(DeployState.DEPLOYING, LockState.NONE, SubState.NONE)); + assertTrue(AcmStateUtils.isInTransitionalState(DeployState.UNDEPLOYING, LockState.NONE, SubState.NONE)); + assertTrue(AcmStateUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKING, SubState.NONE)); + assertTrue(AcmStateUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.UNLOCKING, SubState.NONE)); + assertTrue(AcmStateUtils.isInTransitionalState(DeployState.DELETING, LockState.NONE, SubState.NONE)); + assertTrue(AcmStateUtils.isInTransitionalState(DeployState.UPDATING, LockState.LOCKED, SubState.NONE)); + assertTrue(AcmStateUtils.isInTransitionalState(DeployState.MIGRATING, LockState.LOCKED, SubState.NONE)); + assertTrue(AcmStateUtils.isInTransitionalState(DeployState.MIGRATION_REVERTING, LockState.LOCKED, + SubState.NONE)); + assertTrue(AcmStateUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKED, + SubState.MIGRATION_PRECHECKING)); + } + + @Test + void testCompositionIsInTransitionalState() { + assertTrue(AcmStateUtils.isInTransitionalState(AcTypeState.PRIMING)); + assertTrue(AcmStateUtils.isInTransitionalState(AcTypeState.DEPRIMING)); + assertFalse(AcmStateUtils.isInTransitionalState(AcTypeState.PRIMED)); + assertFalse(AcmStateUtils.isInTransitionalState(AcTypeState.COMMISSIONED)); + } + + @Test + void testStateDeployToOrder() { + // from transitional state to order state + assertEquals(DeployOrder.DEPLOY, AcmStateUtils.stateDeployToOrder(DeployState.DEPLOYING)); + assertEquals(DeployOrder.UNDEPLOY, AcmStateUtils.stateDeployToOrder(DeployState.UNDEPLOYING)); + assertEquals(DeployOrder.DELETE, AcmStateUtils.stateDeployToOrder(DeployState.DELETING)); + assertEquals(DeployOrder.NONE, AcmStateUtils.stateDeployToOrder(DeployState.DEPLOYED)); + } + + @Test + void testStateLockToOrder() { + // from transitional state to order state + assertEquals(LockOrder.LOCK, AcmStateUtils.stateLockToOrder(LockState.LOCKING)); + assertEquals(LockOrder.UNLOCK, AcmStateUtils.stateLockToOrder(LockState.UNLOCKING)); + assertEquals(LockOrder.NONE, AcmStateUtils.stateLockToOrder(LockState.NONE)); + } + + @Test + void testDeployCompleted() { + // from transitional state to final state + assertEquals(DeployState.DEPLOYED, AcmStateUtils.deployCompleted(DeployState.DEPLOYING)); + assertEquals(DeployState.UNDEPLOYED, AcmStateUtils.deployCompleted(DeployState.UNDEPLOYING)); + assertEquals(DeployState.DEPLOYED, AcmStateUtils.deployCompleted(DeployState.DEPLOYED)); + assertEquals(DeployState.DELETED, AcmStateUtils.deployCompleted(DeployState.DELETING)); + } + + @Test + void testLockCompleted() { + // from transitional state to final state + assertEquals(LockState.LOCKED, AcmStateUtils.lockCompleted(DeployState.DEPLOYING, LockState.NONE)); + assertEquals(LockState.LOCKED, AcmStateUtils.lockCompleted(DeployState.DEPLOYED, LockState.LOCKING)); + assertEquals(LockState.UNLOCKED, AcmStateUtils.lockCompleted(DeployState.DEPLOYED, LockState.UNLOCKING)); + assertEquals(LockState.NONE, AcmStateUtils.lockCompleted(DeployState.UNDEPLOYING, LockState.LOCKED)); + } + + @Test + void testIsForward() { + assertTrue(AcmStateUtils.isForward(DeployState.DEPLOYING, LockState.NONE)); + assertTrue(AcmStateUtils.isForward(DeployState.DEPLOYED, LockState.UNLOCKING)); + assertFalse(AcmStateUtils.isForward(DeployState.DEPLOYED, LockState.LOCKING)); + assertFalse(AcmStateUtils.isForward(DeployState.UNDEPLOYING, LockState.LOCKED)); + } + + @Test + void testIsMigratingForward() { + assertTrue(AcmStateUtils.isMigrationForward(DeployState.MIGRATING)); + assertFalse(AcmStateUtils.isMigrationForward(DeployState.MIGRATION_REVERTING)); + } + + @Test + void testIsMigrating() { + assertTrue(AcmStateUtils.isMigrating(DeployState.MIGRATING)); + assertTrue(AcmStateUtils.isMigrating(DeployState.MIGRATION_REVERTING)); + assertFalse(AcmStateUtils.isMigrating(DeployState.DEPLOYING)); + assertFalse(AcmStateUtils.isMigrating(DeployState.DEPLOYED)); + } +} diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmTimeoutUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmTimeoutUtilsTest.java new file mode 100644 index 000000000..2bb9073ab --- /dev/null +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmTimeoutUtilsTest.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved. + * ================================================================================ + * 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.models.acm.utils; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.models.acm.concepts.AcTypeState; +import org.onap.policy.clamp.models.acm.concepts.DeployState; + +class AcmTimeoutUtilsTest { + + @Test + void testGetTimeout() { + var result = AcmTimeoutUtils.getTimeout(Map.of(), AcmTimeoutUtils.DEPLOY_TIMEOUT, 1000); + assertEquals(1000, result); + + result = AcmTimeoutUtils.getTimeout(Map.of(AcmTimeoutUtils.DEPLOY_TIMEOUT, 20000), + AcmTimeoutUtils.DEPLOY_TIMEOUT, 1000); + assertEquals(20000, result); + } + + @Test + void testGetOpName() { + var result = AcmTimeoutUtils.getOpName(AcTypeState.PRIMING); + assertEquals(AcmTimeoutUtils.PRIME_TIMEOUT, result); + result = AcmTimeoutUtils.getOpName(AcTypeState.DEPRIMING); + assertEquals(AcmTimeoutUtils.DEPRIME_TIMEOUT, result); + result = AcmTimeoutUtils.getOpName(DeployState.DEPLOYING); + assertEquals(AcmTimeoutUtils.DEPLOY_TIMEOUT, result); + result = AcmTimeoutUtils.getOpName(DeployState.UNDEPLOYING); + assertEquals(AcmTimeoutUtils.UNDEPLOY_TIMEOUT, result); + result = AcmTimeoutUtils.getOpName(DeployState.UPDATING); + assertEquals(AcmTimeoutUtils.UPDATE_TIMEOUT, result); + result = AcmTimeoutUtils.getOpName(DeployState.DELETING); + assertEquals(AcmTimeoutUtils.DELETE_TIMEOUT, result); + result = AcmTimeoutUtils.getOpName(DeployState.MIGRATING); + assertEquals(AcmTimeoutUtils.MIGRATE_TIMEOUT, result); + result = AcmTimeoutUtils.getOpName(DeployState.DEPLOYED); + assertEquals(AcmTimeoutUtils.DEFAULT_TIMEOUT, result); + } +} diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java index 0fe5bae3f..da87177c6 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java @@ -39,12 +39,8 @@ import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; 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.SubState; import org.onap.policy.clamp.models.acm.document.concepts.DocToscaServiceTemplate; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; -import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType; import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; @@ -64,22 +60,6 @@ class AcmUtilsTest { "org.onap.policy.clamp.acm.AutomationCompositionElement"; public static final String AUTOMATION_COMPOSITION_NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition"; - @Test - void testIsInTransitionalState() { - assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE)).isFalse(); - assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYING, LockState.NONE, SubState.NONE)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.UNDEPLOYING, LockState.NONE, SubState.NONE)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKING, SubState.NONE)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.UNLOCKING, SubState.NONE)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.DELETING, LockState.NONE, SubState.NONE)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.UPDATING, LockState.LOCKED, SubState.NONE)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.MIGRATING, LockState.LOCKED, SubState.NONE)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.MIGRATION_REVERTING, LockState.LOCKED, - SubState.NONE)).isTrue(); - assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKED, - SubState.MIGRATION_PRECHECKING)).isTrue(); - } - @Test void testCheckIfNodeTemplateIsAutomationCompositionElement() { var serviceTemplate = CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML); @@ -134,13 +114,13 @@ class AcmUtilsTest { var doc = new DocToscaServiceTemplate(CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML)); var automationComposition = CommonTestData.getJsonObject(AC_INSTANTIATION_JSON, AutomationComposition.class); var result = AcmUtils.validateAutomationComposition(automationComposition, doc.toAuthorative(), - AUTOMATION_COMPOSITION_NODE_TYPE, false); + AUTOMATION_COMPOSITION_NODE_TYPE, 0); assertTrue(result.isValid()); var element = automationComposition.getElements().values().iterator().next(); automationComposition.getElements().remove(element.getId()); result = AcmUtils.validateAutomationComposition(automationComposition, doc.toAuthorative(), - AUTOMATION_COMPOSITION_NODE_TYPE, false); + AUTOMATION_COMPOSITION_NODE_TYPE, 0); assertFalse(result.isValid()); assertThat(result.getMessage()).contains("not matching"); } @@ -150,7 +130,7 @@ class AcmUtilsTest { var automationComposition = getDummyAutomationComposition(); var toscaServiceTemplate = getDummyToscaServiceTemplate(); var result = AcmUtils.validateAutomationComposition(automationComposition, - toscaServiceTemplate, AUTOMATION_COMPOSITION_NODE_TYPE, false); + toscaServiceTemplate, AUTOMATION_COMPOSITION_NODE_TYPE, 0); assertNotNull(result); assertFalse(result.isValid()); @@ -160,58 +140,15 @@ class AcmUtilsTest { nodeTemplates.put("org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant", nodeTemplate); toscaServiceTemplate.getToscaTopologyTemplate().setNodeTemplates(nodeTemplates); result = AcmUtils.validateAutomationComposition(automationComposition, toscaServiceTemplate, - AUTOMATION_COMPOSITION_NODE_TYPE, false); + AUTOMATION_COMPOSITION_NODE_TYPE, 0); assertFalse(result.isValid()); var doc = new DocToscaServiceTemplate(CommonTestData.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML)); result = AcmUtils.validateAutomationComposition(automationComposition, doc.toAuthorative(), - AUTOMATION_COMPOSITION_NODE_TYPE, false); + AUTOMATION_COMPOSITION_NODE_TYPE, 0); assertFalse(result.isValid()); } - @Test - void testStateDeployToOrder() { - // from transitional state to order state - assertEquals(DeployOrder.DEPLOY, AcmUtils.stateDeployToOrder(DeployState.DEPLOYING)); - assertEquals(DeployOrder.UNDEPLOY, AcmUtils.stateDeployToOrder(DeployState.UNDEPLOYING)); - assertEquals(DeployOrder.DELETE, AcmUtils.stateDeployToOrder(DeployState.DELETING)); - assertEquals(DeployOrder.NONE, AcmUtils.stateDeployToOrder(DeployState.DEPLOYED)); - } - - @Test - void testStateLockToOrder() { - // from transitional state to order state - assertEquals(LockOrder.LOCK, AcmUtils.stateLockToOrder(LockState.LOCKING)); - assertEquals(LockOrder.UNLOCK, AcmUtils.stateLockToOrder(LockState.UNLOCKING)); - assertEquals(LockOrder.NONE, AcmUtils.stateLockToOrder(LockState.NONE)); - } - - @Test - void testDeployCompleted() { - // from transitional state to final state - assertEquals(DeployState.DEPLOYED, AcmUtils.deployCompleted(DeployState.DEPLOYING)); - assertEquals(DeployState.UNDEPLOYED, AcmUtils.deployCompleted(DeployState.UNDEPLOYING)); - assertEquals(DeployState.DEPLOYED, AcmUtils.deployCompleted(DeployState.DEPLOYED)); - assertEquals(DeployState.DELETED, AcmUtils.deployCompleted(DeployState.DELETING)); - } - - @Test - void testLockCompleted() { - // from transitional state to final state - assertEquals(LockState.LOCKED, AcmUtils.lockCompleted(DeployState.DEPLOYING, LockState.NONE)); - assertEquals(LockState.LOCKED, AcmUtils.lockCompleted(DeployState.DEPLOYED, LockState.LOCKING)); - assertEquals(LockState.UNLOCKED, AcmUtils.lockCompleted(DeployState.DEPLOYED, LockState.UNLOCKING)); - assertEquals(LockState.NONE, AcmUtils.lockCompleted(DeployState.UNDEPLOYING, LockState.LOCKED)); - } - - @Test - void testIsForward() { - assertTrue(AcmUtils.isForward(DeployState.DEPLOYING, LockState.NONE)); - assertTrue(AcmUtils.isForward(DeployState.DEPLOYED, LockState.UNLOCKING)); - assertFalse(AcmUtils.isForward(DeployState.DEPLOYED, LockState.LOCKING)); - assertFalse(AcmUtils.isForward(DeployState.UNDEPLOYING, LockState.LOCKED)); - } - @Test void testCreateAcElementDeploy() { var element = getDummyAutomationComposition().getElements().values().iterator().next(); diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/CommonTestData.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/CommonTestData.java index 990c1c42a..fe749ee1d 100644 --- a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/CommonTestData.java +++ b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/CommonTestData.java @@ -127,6 +127,22 @@ public class CommonTestData { } } + /** + * Get Object from json string. + * + * @param json the json + * @param clazz the Class of the Object + * @return the Object + */ + public static T getJson(final String json, Class clazz) { + try { + return CODER.decode(json, clazz); + } catch (CoderException e) { + fail("Cannot decode " + json); + return null; + } + } + /** * Get new AutomationCompositionElementDefinition. * diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandler.java index 4bcedc1d2..1d8a5a94d 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandler.java +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandler.java @@ -58,7 +58,7 @@ public class AutomationCompositionElementHandler extends AcElementListenerV4 { */ @Override public void deploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { - LOGGER.debug("deploy call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + LOGGER.info("deploy call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); simulatorService.deploy(instanceElement.instanceId(), instanceElement.elementId(), instanceElement.outProperties()); } @@ -71,53 +71,53 @@ public class AutomationCompositionElementHandler extends AcElementListenerV4 { */ @Override public void undeploy(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { - LOGGER.debug("undeploy call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + LOGGER.info("undeploy call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); simulatorService.undeploy(instanceElement.instanceId(), instanceElement.elementId(), instanceElement.outProperties()); } @Override public void lock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { - LOGGER.debug("lock call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + LOGGER.info("lock call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); simulatorService.lock(instanceElement.instanceId(), instanceElement.elementId()); } @Override public void unlock(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { - LOGGER.debug("unlock call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + LOGGER.info("unlock call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); simulatorService.unlock(instanceElement.instanceId(), instanceElement.elementId()); } @Override public void delete(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { - LOGGER.debug("delete call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + LOGGER.info("delete call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); simulatorService.delete(instanceElement.instanceId(), instanceElement.elementId()); } @Override public void update(CompositionElementDto compositionElement, InstanceElementDto instanceElement, InstanceElementDto instanceElementUpdated) { - LOGGER.debug("update call compositionElement: {}, instanceElement: {}, instanceElementUpdated: {}", + LOGGER.info("update call compositionElement: {}, instanceElement: {}, instanceElementUpdated: {}", compositionElement, instanceElement, instanceElementUpdated); simulatorService.update(instanceElement.instanceId(), instanceElement.elementId()); } @Override public void prime(CompositionDto composition) { - LOGGER.debug("prime call composition: {}", composition); + LOGGER.info("prime call composition: {}", composition); simulatorService.prime(composition); } @Override public void deprime(CompositionDto composition) { - LOGGER.debug("deprime call composition: {}", composition); + LOGGER.info("deprime call composition: {}", composition); simulatorService.deprime(composition); } @Override public void migrate(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate, int stage) { - LOGGER.debug("migrate call compositionElement: {}, compositionElementTarget: {}, instanceElement: {}," + LOGGER.info("migrate call compositionElement: {}, compositionElementTarget: {}, instanceElement: {}," + " instanceElementMigrate: {}, stage: {}", compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate, stage); @@ -127,8 +127,9 @@ public class AutomationCompositionElementHandler extends AcElementListenerV4 { if (ElementState.REMOVED.equals(instanceElementMigrate.state())) { simulatorService.deleteInMigration(instanceElement.instanceId(), instanceElement.elementId()); } else { + var nextStage = intermediaryApi.getMigrateNextStage(compositionElementTarget, stage); simulatorService.migrate(instanceElementMigrate.instanceId(), instanceElementMigrate.elementId(), stage, - compositionElementTarget.inProperties(), instanceElementMigrate.outProperties()); + nextStage, instanceElementMigrate.outProperties()); } } @@ -136,7 +137,7 @@ public class AutomationCompositionElementHandler extends AcElementListenerV4 { public void migratePrecheck(CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, InstanceElementDto instanceElementMigrate) { - LOGGER.debug("migrate precheck call compositionElement: {}, compositionElementTarget: {}, instanceElement: {}," + LOGGER.info("migrate precheck call compositionElement: {}, compositionElementTarget: {}, instanceElement: {}," + " instanceElementMigrate: {}", compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate); simulatorService.migratePrecheck(instanceElement.instanceId(), instanceElement.elementId()); @@ -144,14 +145,15 @@ public class AutomationCompositionElementHandler extends AcElementListenerV4 { @Override public void prepare(CompositionElementDto compositionElement, InstanceElementDto instanceElement, int stage) { - LOGGER.debug("prepare call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + LOGGER.info("prepare call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + var nextStage = intermediaryApi.getPrepareNextStage(compositionElement, stage); simulatorService.prepare(instanceElement.instanceId(), instanceElement.elementId(), - stage, compositionElement.inProperties(), instanceElement.outProperties()); + stage, nextStage, instanceElement.outProperties()); } @Override public void review(CompositionElementDto compositionElement, InstanceElementDto instanceElement) { - LOGGER.debug("review call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); + LOGGER.info("review call compositionElement: {}, instanceElement: {}", compositionElement, instanceElement); simulatorService.review(instanceElement.instanceId(), instanceElement.elementId()); } @@ -159,7 +161,7 @@ public class AutomationCompositionElementHandler extends AcElementListenerV4 { public void rollbackMigration(CompositionElementDto compositionElement, CompositionElementDto compositionElementRollback, InstanceElementDto instanceElement, InstanceElementDto instanceElementRollback, int stage) { - LOGGER.debug("rollback call compositionElement: {}, compositionElementRollback: {}, instanceElement: {}," + LOGGER.info("rollback call compositionElement: {}, compositionElementRollback: {}, instanceElement: {}," + " instanceElementRollback: {}, stage: {}", compositionElement, compositionElementRollback, instanceElement, instanceElementRollback, stage); @@ -169,8 +171,9 @@ public class AutomationCompositionElementHandler extends AcElementListenerV4 { if (ElementState.REMOVED.equals(instanceElementRollback.state())) { simulatorService.deleteInRollback(instanceElement.instanceId(), instanceElement.elementId()); } else { + var nextStage = intermediaryApi.getRollbackNextStage(compositionElementRollback, stage); simulatorService.rollback(instanceElementRollback.instanceId(), instanceElementRollback.elementId(), stage, - compositionElementRollback.inProperties(), instanceElementRollback.outProperties()); + nextStage, instanceElementRollback.outProperties()); } } } diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorService.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorService.java index 69ab0dbd9..ec0927b08 100644 --- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorService.java +++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorService.java @@ -38,7 +38,6 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; 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.ParticipantUtils; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.slf4j.Logger; @@ -395,10 +394,10 @@ public class SimulatorService { * @param instanceId the instanceId * @param elementId the elementId * @param stage the stage - * @param compositionInProperties in Properties from composition definition element + * @param nextStage the next stage * @param instanceOutProperties in Properties from instance element */ - public void migrate(UUID instanceId, UUID elementId, int stage, Map compositionInProperties, + public void migrate(UUID instanceId, UUID elementId, int stage, int nextStage, Map instanceOutProperties) { if (isInterrupted(getConfig().getMigrateTimerMs(), "Current Thread migrate is Interrupted during execution {}", elementId)) { @@ -406,19 +405,12 @@ public class SimulatorService { } if (config.isMigrateSuccess()) { - var stageSet = ParticipantUtils.findStageSetMigrate(compositionInProperties); - var nextStage = 1000; - for (var s : stageSet) { - if (s > stage) { - nextStage = Math.min(s, nextStage); - } - } instanceOutProperties.putIfAbsent(MIGRATION_PROPERTY, new ArrayList<>()); @SuppressWarnings("unchecked") var stageList = (List) instanceOutProperties.get(MIGRATION_PROPERTY); stageList.add(stage); intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, instanceOutProperties); - if (nextStage == 1000) { + if (nextStage == stage) { intermediaryApi.updateAutomationCompositionElementState( instanceId, elementId, DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migrated"); @@ -461,10 +453,10 @@ public class SimulatorService { * @param instanceId the instanceId * @param elementId the elementId * @param stage the stage - * @param compositionInProperties in Properties from composition definition element + * @param nextStage the next stage * @param instanceOutProperties in Properties from instance element */ - public void prepare(UUID instanceId, UUID elementId, int stage, Map compositionInProperties, + public void prepare(UUID instanceId, UUID elementId, int stage, int nextStage, Map instanceOutProperties) { if (isInterrupted(config.getPrepareTimerMs(), "Current Thread prepare is Interrupted during execution {}", elementId)) { @@ -472,19 +464,12 @@ public class SimulatorService { } if (config.isPrepare()) { - var stageSet = ParticipantUtils.findStageSetPrepare(compositionInProperties); - var nextStage = 1000; - for (var s : stageSet) { - if (s > stage) { - nextStage = Math.min(s, nextStage); - } - } instanceOutProperties.putIfAbsent(PREPARE_PROPERTY, new ArrayList<>()); @SuppressWarnings("unchecked") var stageList = (List) instanceOutProperties.get(PREPARE_PROPERTY); stageList.add(stage); intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, instanceOutProperties); - if (nextStage == 1000) { + if (nextStage == stage) { intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId, DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Prepare completed"); } else { @@ -525,10 +510,10 @@ public class SimulatorService { * @param instanceId the instanceId * @param elementId the elementId * @param stage the stage - * @param compositionInProperties in Properties from composition definition element + * @param nextStage the next stage * @param instanceOutProperties in Properties from instance element */ - public void rollback(UUID instanceId, UUID elementId, int stage, Map compositionInProperties, + public void rollback(UUID instanceId, UUID elementId, int stage, int nextStage, Map instanceOutProperties) { if (isInterrupted(getConfig().getRollbackTimerMs(), "Current Thread for rollback was Interrupted during execution {}", instanceId)) { @@ -537,19 +522,12 @@ public class SimulatorService { } if (config.isRollback()) { - var stageSet = ParticipantUtils.findStageSetMigrate(compositionInProperties); - var nextStage = 1000; - for (var s : stageSet) { - if (s > stage) { - nextStage = Math.min(s, nextStage); - } - } instanceOutProperties.putIfAbsent(ROLLBACK_PROPERTY, new ArrayList<>()); @SuppressWarnings("unchecked") var stageList = (List) instanceOutProperties.get(ROLLBACK_PROPERTY); stageList.add(stage); intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, instanceOutProperties); - if (nextStage == 1000) { + if (nextStage == stage) { intermediaryApi.updateAutomationCompositionElementState( instanceId, elementId, DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Migration rollback done"); diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerTest.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerTest.java index 314d05ec3..d52f5841c 100644 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerTest.java +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerTest.java @@ -21,6 +21,7 @@ package org.onap.policy.clamp.acm.participant.sim.main.handler; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import java.util.HashMap; @@ -33,6 +34,7 @@ import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElement 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.ParticipantIntermediaryApiImpl; import org.onap.policy.clamp.acm.participant.sim.comm.CommonTestData; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.DeployState; @@ -230,7 +232,7 @@ class AutomationCompositionElementHandlerTest { @Test void testMigrateStage() { var config = CommonTestData.createSimConfig(); - var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var intermediaryApi = spy(new ParticipantIntermediaryApiImpl(mock(), mock())); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService); simulatorService.setConfig(config); @@ -248,7 +250,7 @@ class AutomationCompositionElementHandlerTest { @Test void testMigrateAdd() { var config = CommonTestData.createSimConfig(); - var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var intermediaryApi = spy(new ParticipantIntermediaryApiImpl(mock(), mock())); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService); simulatorService.setConfig(config); @@ -381,11 +383,10 @@ class AutomationCompositionElementHandlerTest { null, StateChangeResult.FAILED, "Migration rollback failed"); } - @Test void testRollbackStage() { var config = CommonTestData.createSimConfig(); - var intermediaryApi = mock(ParticipantIntermediaryApi.class); + var intermediaryApi = spy(new ParticipantIntermediaryApiImpl(mock(), mock())); var simulatorService = new SimulatorService(intermediaryApi); var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi, simulatorService); simulatorService.setConfig(config); diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorServiceTest.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorServiceTest.java index 49b01956e..6b32e5d6a 100644 --- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorServiceTest.java +++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorServiceTest.java @@ -149,9 +149,9 @@ class SimulatorServiceTest { simulatorService.update(UUID.randomUUID(), UUID.randomUUID()); simulatorService.prime(mock(CompositionDto.class)); simulatorService.deprime(mock(CompositionDto.class)); - simulatorService.migrate(UUID.randomUUID(), UUID.randomUUID(), 0, new HashMap<>(), new HashMap<>()); + simulatorService.migrate(UUID.randomUUID(), UUID.randomUUID(), 0, 1, new HashMap<>()); simulatorService.review(UUID.randomUUID(), UUID.randomUUID()); - simulatorService.prepare(UUID.randomUUID(), UUID.randomUUID(), 0, new HashMap<>(), new HashMap<>()); + simulatorService.prepare(UUID.randomUUID(), UUID.randomUUID(), 0, 1, new HashMap<>()); simulatorService.migratePrecheck(UUID.randomUUID(), UUID.randomUUID()); verify(intermediaryApi, times(0)).sendAcDefinitionInfo(any(), any(), any()); } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java index a2857bd51..4f7eca5b1 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java @@ -158,4 +158,31 @@ public interface ParticipantIntermediaryApi { */ void updateCompositionState(UUID compositionId, AcTypeState state, StateChangeResult stateChangeResult, String message); + + /** + * Get next stage in Migration. + * + * @param compositionElementTarget the CompositionElementDto target + * @param lastStage the last stage completed + * @return the next stage or lastStage if migration completed + */ + int getMigrateNextStage(CompositionElementDto compositionElementTarget, int lastStage); + + /** + * Get next stage in Rollback. + * + * @param compositionElementRollback the CompositionElementDto rollback target + * @param lastStage the last stage completed + * @return the next stage or lastStage if rollback completed + */ + int getRollbackNextStage(CompositionElementDto compositionElementRollback, int lastStage); + + /** + * Get next stage in Prepare. + * + * @param compositionElement the CompositionElementDto + * @param lastStage the last stage completed + * @return the next stage or lastStage if prepare completed + */ + int getPrepareNextStage(CompositionElementDto compositionElement, int lastStage); } 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 2c6023b7a..f4e35114e 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 @@ -37,7 +37,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDef 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.StateChangeResult; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStageUtils; import org.onap.policy.models.base.PfUtils; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.springframework.stereotype.Component; @@ -49,6 +49,8 @@ import org.springframework.stereotype.Component; @RequiredArgsConstructor public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryApi { + private static final int MAX_STAGES = 1000; + // The handler for the automationComposition intermediary private final AutomationCompositionOutHandler automationCompositionHandler; private final CacheProvider cacheProvider; @@ -85,6 +87,35 @@ public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryAp automationCompositionHandler.updateCompositionState(compositionId, state, stateChangeResult, message); } + @Override + public int getMigrateNextStage(CompositionElementDto compositionElementTarget, int lastStage) { + var stageSet = AcmStageUtils.findStageSetMigrate(compositionElementTarget.inProperties()); + var nextStage = MAX_STAGES; + for (var s : stageSet) { + if (s > lastStage) { + nextStage = Math.min(s, nextStage); + } + } + return nextStage == MAX_STAGES ? lastStage : nextStage; + } + + @Override + public int getRollbackNextStage(CompositionElementDto compositionElementRollback, int lastStage) { + return getMigrateNextStage(compositionElementRollback, lastStage); + } + + @Override + public int getPrepareNextStage(CompositionElementDto compositionElement, int lastStage) { + var stageSet = AcmStageUtils.findStageSetPrepare(compositionElement.inProperties()); + var nextStage = MAX_STAGES; + for (var s : stageSet) { + if (s > lastStage) { + nextStage = Math.min(s, nextStage); + } + } + return nextStage == MAX_STAGES ? lastStage : nextStage; + } + @Override public AutomationCompositionElement getAutomationCompositionElement(UUID instanceId, UUID elementId) { var automationComposition = cacheProvider.getAutomationCompositions().get(instanceId); diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java index 079b9008e..ae683e008 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AcLockHandler.java @@ -27,9 +27,9 @@ import org.onap.policy.clamp.acm.participant.intermediary.api.InstanceElementDto import org.onap.policy.clamp.acm.participant.intermediary.handler.cache.CacheProvider; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.LockState; -import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionStateChange; +import org.onap.policy.clamp.models.acm.utils.AcmStageUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -76,7 +76,7 @@ public class AcLockHandler { for (var element : automationComposition.getElements().values()) { var compositionInProperties = cacheProvider .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); - int startPhase = ParticipantUtils.findStartPhase(compositionInProperties); + int startPhase = AcmStageUtils.findStartPhase(compositionInProperties); if (startPhaseMsg.equals(startPhase)) { element.setLockState(LockState.LOCKING); element.setSubState(SubState.NONE); @@ -95,7 +95,7 @@ public class AcLockHandler { for (var element : automationComposition.getElements().values()) { var compositionInProperties = cacheProvider .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); - int startPhase = ParticipantUtils.findStartPhase(compositionInProperties); + int startPhase = AcmStageUtils.findStartPhase(compositionInProperties); if (startPhaseMsg.equals(startPhase)) { element.setLockState(LockState.UNLOCKING); element.setSubState(SubState.NONE); 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 20b2a2438..1c8fcd82f 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 @@ -32,10 +32,10 @@ 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.ParticipantUtils; 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.AcmStageUtils; import org.onap.policy.clamp.models.acm.utils.AcmUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -188,7 +188,7 @@ public class AcSubStateHandler { .getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); var compositionElement = cacheProvider.createCompositionElementDto(automationComposition.getCompositionId(), element); - var stageSet = ParticipantUtils.findStageSetPrepare(compositionInProperties); + var stageSet = AcmStageUtils.findStageSetPrepare(compositionInProperties); if (stageSet.contains(stageMsg)) { var instanceElement = new InstanceElementDto(instanceId, elementDeploy.getId(), elementDeploy.getProperties(), 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 5b2f74fce..84a7738e5 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,7 +21,6 @@ package org.onap.policy.clamp.acm.participant.intermediary.handler; -import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -31,7 +30,6 @@ import org.onap.policy.clamp.acm.participant.intermediary.api.CompositionElement 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.acm.participant.intermediary.handler.cache.AcDefinition; import org.onap.policy.clamp.acm.participant.intermediary.handler.cache.CacheProvider; import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; @@ -39,7 +37,6 @@ 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.MigrationState; 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; import org.onap.policy.clamp.models.acm.concepts.SubState; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeploy; @@ -49,6 +46,7 @@ import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCom import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageType; 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.AcmStageUtils; import org.onap.policy.clamp.models.acm.utils.AcmUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -162,7 +160,7 @@ public class AutomationCompositionHandler { var element = automationComposition.getElements().get(elementDeploy.getId()); var compositionInProperties = cacheProvider.getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); - int startPhase = ParticipantUtils.findStartPhase(compositionInProperties); + int startPhase = AcmStageUtils.findStartPhase(compositionInProperties); if (startPhaseMsg.equals(startPhase)) { var compositionElement = cacheProvider.createCompositionElementDto(automationComposition.getCompositionId(), element); @@ -186,40 +184,34 @@ public class AutomationCompositionHandler { } } - private void migrateExistingElementsOnThisParticipant(AutomationComposition automationComposition, - UUID compositionTargetId, ParticipantDeploy participantDeploy, - int stage, boolean newParticipant) { + private void migrateAutomationComposition(AutomationComposition automationComposition, + ParticipantDeploy participantDeploy, int stage) { for (var element : participantDeploy.getAcElementList()) { - UUID compIdForCommonProperties = null; - if (MigrationState.REMOVED.equals(element.getMigrationState())) { - compIdForCommonProperties = automationComposition.getCompositionId(); - } else { - compIdForCommonProperties = compositionTargetId; - } - var compositionInProperties = - cacheProvider.getCommonProperties(compIdForCommonProperties, element.getDefinition()); - var stageSet = ParticipantUtils.findStageSetMigrate(compositionInProperties); - if (MigrationState.REMOVED.equals(element.getMigrationState())) { - stageSet = Set.of(0); + var stageSet = getMigrationStageSet(element, automationComposition.getCompositionTargetId()); + if (stageSet.contains(stage)) { + migrateElement(element, automationComposition, stage, participantDeploy); } + } + } + + private void rollbackAutomationComposition(AutomationComposition automationComposition, + ParticipantDeploy participantDeploy, int stage) { + for (var element : participantDeploy.getAcElementList()) { + var stageSet = getRollbackStageSet(element, automationComposition.getCompositionId()); if (stageSet.contains(stage)) { - migrateElement(element, automationComposition, compositionTargetId, stage, newParticipant, - participantDeploy); + migrateElement(element, automationComposition, stage, participantDeploy); } } } private void migrateElement(AcElementDeploy element, AutomationComposition automationComposition, - UUID compositionTargetId, int stage, boolean newParticipant, - ParticipantDeploy participantDeploy) { + int stage, ParticipantDeploy participantDeploy) { var acElementList = automationComposition.getElements(); - automationComposition.setCompositionTargetId(compositionTargetId); - automationComposition.setDeployState(DeployState.MIGRATING); var acElement = acElementList.get(element.getId()); if (acElement == null) { // NEW element with existing participant var newElement = CacheProvider.createAutomationCompositionElement(element); newElement.setParticipantId(participantDeploy.getParticipantId()); - newElement.setDeployState(DeployState.MIGRATING); + newElement.setDeployState(automationComposition.getDeployState()); newElement.setLockState(LockState.LOCKED); newElement.setStage(stage); newElement.setMigrationState(MigrationState.NEW); @@ -229,14 +221,13 @@ public class AutomationCompositionHandler { } else { acElement.setStage(stage); acElement.setMigrationState(element.getMigrationState()); - if (! newParticipant) { //DEFAULT element + acElement.setDeployState(automationComposition.getDeployState()); + acElement.setDefinition(element.getDefinition()); + if (MigrationState.DEFAULT.equals(element.getMigrationState())) { //DEFAULT element AcmUtils.recursiveMerge(acElement.getProperties(), element.getProperties()); - acElement.setDeployState(DeployState.MIGRATING); - acElement.setDefinition(element.getDefinition()); } LOGGER.info("Cache updated for the migration of element with id {}", element.getId()); } - } private void updateExistingElementsOnThisParticipant(UUID instanceId, ParticipantDeploy participantDeploy) { @@ -261,14 +252,10 @@ public class AutomationCompositionHandler { Integer startPhaseMsg) { automationComposition.setDeployState(DeployState.UNDEPLOYING); for (var element : automationComposition.getElements().values()) { - UUID compositionId = null; - if (MigrationState.NEW.equals(element.getMigrationState())) { - compositionId = automationComposition.getCompositionTargetId(); - } else { - compositionId = automationComposition.getCompositionId(); - } + var compositionId = MigrationState.NEW.equals(element.getMigrationState()) + ? automationComposition.getCompositionTargetId() : automationComposition.getCompositionId(); var compositionInProperties = cacheProvider.getCommonProperties(compositionId, element.getDefinition()); - int startPhase = ParticipantUtils.findStartPhase(compositionInProperties); + var startPhase = AcmStageUtils.findStartPhase(compositionInProperties); if (MigrationState.NEW.equals(element.getMigrationState())) { // Undeploy newly added element on a Failed Migration startPhase = 0; @@ -290,7 +277,7 @@ public class AutomationCompositionHandler { for (var element : automationComposition.getElements().values()) { var compositionInProperties = cacheProvider.getCommonProperties(automationComposition.getCompositionId(), element.getDefinition()); - int startPhase = ParticipantUtils.findStartPhase(compositionInProperties); + int startPhase = AcmStageUtils.findStartPhase(compositionInProperties); if (startPhaseMsg.equals(startPhase)) { element.setDeployState(DeployState.DELETING); element.setSubState(SubState.NONE); @@ -310,9 +297,8 @@ public class AutomationCompositionHandler { */ public void handleAutomationCompositionMigration(AutomationCompositionMigration migrationMsg) { var automationComposition = cacheProvider.getAutomationComposition(migrationMsg.getAutomationCompositionId()); - var acTargetDefinition = cacheProvider.getAcElementsDefinitions().get(migrationMsg.getCompositionTargetId()); if (Boolean.FALSE.equals(migrationMsg.getRollback())) { - handleMigration(automationComposition, acTargetDefinition, migrationMsg); + handleMigration(automationComposition, migrationMsg); } else { handleRollback(automationComposition, migrationMsg); } @@ -320,95 +306,49 @@ public class AutomationCompositionHandler { private void handleRollback(AutomationComposition automationComposition, AutomationCompositionMigration migrationMsg) { - AutomationComposition acCopy = null; - if (automationComposition == null) { - LOGGER.warn(AC_NOT_USED, migrationMsg.getAutomationCompositionId()); - return; - } else { - LOGGER.info("Rollback operation invoked for the instance {}", migrationMsg.getAutomationCompositionId()); - acCopy = new AutomationComposition(automationComposition); - automationComposition.setCompositionTargetId(migrationMsg.getCompositionTargetId()); - automationComposition.setDeployState(DeployState.MIGRATION_REVERTING); - } + LOGGER.info("Rollback operation invoked for the instance {}", migrationMsg.getAutomationCompositionId()); + automationComposition.setCompositionTargetId(migrationMsg.getCompositionTargetId()); + automationComposition.setDeployState(DeployState.MIGRATION_REVERTING); + var automationCompositionCopy = new AutomationComposition(automationComposition); for (var participantDeploy : migrationMsg.getParticipantUpdatesList()) { if (cacheProvider.getParticipantId().equals(participantDeploy.getParticipantId())) { - migrateExistingElementsOnThisParticipant(automationComposition, migrationMsg.getCompositionTargetId(), - participantDeploy, migrationMsg.getStage(), false); - - callParticipantMigrate(migrationMsg, participantDeploy.getAcElementList(), acCopy); + rollbackAutomationComposition(automationComposition, participantDeploy, migrationMsg.getStage()); + callParticipantRollback(migrationMsg, participantDeploy.getAcElementList(), automationCompositionCopy); } } } - private void handleMigration(AutomationComposition automationComposition, AcDefinition acTargetDefinition, - AutomationCompositionMigration migrationMsg) { - AutomationComposition acCopy = null; - if (automationComposition == null) { - if (acTargetDefinition == null) { - LOGGER.warn(AC_NOT_USED, migrationMsg.getAutomationCompositionId()); - return; - } - } else { - LOGGER.info("Migration invoked on an existing participant for the instance {}", - migrationMsg.getAutomationCompositionId()); - acCopy = new AutomationComposition(automationComposition); - } - var newParticipant = false; + private void handleMigration(AutomationComposition automationComposition, + AutomationCompositionMigration migrationMsg) { + LOGGER.info("Migration invoked for the instance {}", migrationMsg.getAutomationCompositionId()); + automationComposition.setCompositionTargetId(migrationMsg.getCompositionTargetId()); + automationComposition.setDeployState(DeployState.MIGRATING); + var automationCompositionCopy = new AutomationComposition(automationComposition); for (var participantDeploy : migrationMsg.getParticipantUpdatesList()) { if (cacheProvider.getParticipantId().equals(participantDeploy.getParticipantId())) { - if (automationComposition == null) { - // New element with new participant added in Migration - LOGGER.info("Participant newly added in Migration for the instance {}", - migrationMsg.getAutomationCompositionId()); - newParticipant = true; - cacheProvider.initializeAutomationComposition(migrationMsg.getCompositionId(), - migrationMsg.getCompositionTargetId(), migrationMsg.getAutomationCompositionId(), - participantDeploy, DeployState.MIGRATING, SubState.NONE, - migrationMsg.getRevisionIdInstance()); - automationComposition = cacheProvider - .getAutomationComposition(migrationMsg.getAutomationCompositionId()); - } - migrateExistingElementsOnThisParticipant(automationComposition, migrationMsg.getCompositionTargetId(), - participantDeploy, migrationMsg.getStage(), newParticipant); - - callParticipantMigrate(migrationMsg, participantDeploy.getAcElementList(), acCopy); + migrateAutomationComposition(automationComposition, participantDeploy, migrationMsg.getStage()); + callParticipantMigrate(migrationMsg, participantDeploy.getAcElementList(), automationCompositionCopy); } } } private void callParticipantMigrate(AutomationCompositionMigration migrationMsg, List acElements, - AutomationComposition formerAcInstance) { - var latestAcFromCache = cacheProvider.getAutomationComposition(migrationMsg.getAutomationCompositionId()); - var instanceElementTargetMap = cacheProvider.getInstanceElementDtoMap(latestAcFromCache); - var compositionElementTargetMap = cacheProvider.getCompositionElementDtoMap(latestAcFromCache, - migrationMsg.getCompositionTargetId()); - Map compositionElementMap = new HashMap<>(); - Map instanceElementMap = new HashMap<>(); - if (formerAcInstance != null) { //Existing participant - compositionElementMap = cacheProvider.getCompositionElementDtoMap(formerAcInstance); - instanceElementMap = cacheProvider.getInstanceElementDtoMap(formerAcInstance); - } - // Call migrate for new and existing elements + AutomationComposition automationCompositionCopy) { + var automationComposition = cacheProvider.getAutomationComposition(automationCompositionCopy.getInstanceId()); + var instanceElementTargetMap = cacheProvider.getInstanceElementDtoMap(automationComposition); + var compositionElementTargetMap = cacheProvider.getCompositionElementDtoMap(automationComposition, + automationCompositionCopy.getCompositionTargetId()); + var compositionElementMap = cacheProvider.getCompositionElementDtoMap(automationCompositionCopy); + var instanceElementMap = cacheProvider.getInstanceElementDtoMap(automationCompositionCopy); for (var acElement : acElements) { - UUID compIdForCommonProperties = null; - if (MigrationState.REMOVED.equals(acElement.getMigrationState())) { - compIdForCommonProperties = latestAcFromCache.getCompositionId(); - } else { - compIdForCommonProperties = migrationMsg.getCompositionTargetId(); - } - var compositionInProperties = - cacheProvider.getCommonProperties(compIdForCommonProperties, acElement.getDefinition()); - var stageSet = ParticipantUtils.findStageSetMigrate(compositionInProperties); - if (MigrationState.REMOVED.equals(acElement.getMigrationState())) { - stageSet = Set.of(0); - } - var rollback = Boolean.TRUE.equals(migrationMsg.getRollback()); + var stageSet = getMigrationStageSet(acElement, automationComposition.getCompositionTargetId()); + var newElement = MigrationState.NEW.equals(acElement.getMigrationState()); if (stageSet.contains(migrationMsg.getStage())) { - if (MigrationState.NEW.equals(acElement.getMigrationState())) { - var compositionElementDto = new CompositionElementDto(migrationMsg.getCompositionId(), + if (newElement) { + var compositionElementDto = new CompositionElementDto(automationCompositionCopy.getCompositionId(), acElement.getDefinition(), Map.of(), Map.of(), ElementState.NOT_PRESENT); - var instanceElementDto = new InstanceElementDto(migrationMsg.getAutomationCompositionId(), + var instanceElementDto = new InstanceElementDto(automationCompositionCopy.getInstanceId(), acElement.getId(), Map.of(), Map.of(), ElementState.NOT_PRESENT); var compositionElementTargetDto = CacheProvider.changeStateToNew(compositionElementTargetMap.get(acElement.getId())); @@ -416,7 +356,7 @@ public class AutomationCompositionHandler { CacheProvider.changeStateToNew(instanceElementTargetMap.get(acElement.getId())); listenerMigrate(migrationMsg.getMessageId(), compositionElementDto, compositionElementTargetDto, - instanceElementDto, instanceElementTargetDto, migrationMsg.getStage(), rollback); + instanceElementDto, instanceElementTargetDto, migrationMsg.getStage()); } else if (MigrationState.REMOVED.equals(acElement.getMigrationState())) { var compositionDtoTarget = new CompositionElementDto(migrationMsg.getCompositionTargetId(), @@ -425,28 +365,101 @@ public class AutomationCompositionHandler { acElement.getId(), Map.of(), Map.of(), ElementState.REMOVED); listenerMigrate(migrationMsg.getMessageId(), compositionElementMap.get(acElement.getId()), compositionDtoTarget, instanceElementMap.get(acElement.getId()), instanceElementDtoTarget, - migrationMsg.getStage(), rollback); + migrationMsg.getStage()); } else { // DEFAULT case listenerMigrate(migrationMsg.getMessageId(), compositionElementMap.get(acElement.getId()), compositionElementTargetMap.get(acElement.getId()), instanceElementMap.get(acElement.getId()), instanceElementTargetMap.get(acElement.getId()), - migrationMsg.getStage(), rollback); + migrationMsg.getStage()); } } } } + private Set getMigrationStageSet(AcElementDeploy acElement, UUID compositionTargetId) { + if (MigrationState.REMOVED.equals(acElement.getMigrationState())) { + return Set.of(0); + } else { + var commonProperties = cacheProvider.getCommonProperties(compositionTargetId, acElement.getDefinition()); + return AcmStageUtils.findStageSetMigrate(commonProperties); + } + } + + private void callParticipantRollback(AutomationCompositionMigration migrationMsg, List acElements, + AutomationComposition automationCompositionCopy) { + var automationComposition = cacheProvider.getAutomationComposition(automationCompositionCopy.getInstanceId()); + var instanceElementTargetMap = cacheProvider.getInstanceElementDtoMap(automationComposition); + var compositionElementTargetMap = cacheProvider.getCompositionElementDtoMap(automationComposition); + var compositionElementMap = cacheProvider.getCompositionElementDtoMap(automationCompositionCopy, + automationCompositionCopy.getCompositionTargetId()); + var instanceElementMap = cacheProvider.getInstanceElementDtoMap(automationCompositionCopy); + for (var acElement : acElements) { + var stageSet = getRollbackStageSet(acElement, automationComposition.getCompositionId()); + var removed = MigrationState.NEW.equals(acElement.getMigrationState()); + if (!removed) { + var commonProperties = cacheProvider + .getCommonProperties(automationComposition.getCompositionId(), acElement.getDefinition()); + stageSet = AcmStageUtils.findStageSetMigrate(commonProperties); + } + var newElement = MigrationState.REMOVED.equals(acElement.getMigrationState()); + if (stageSet.contains(migrationMsg.getStage())) { + if (newElement) { + var compositionElementDto = + new CompositionElementDto(automationCompositionCopy.getCompositionTargetId(), + acElement.getDefinition(), Map.of(), Map.of(), ElementState.NOT_PRESENT); + var instanceElementDto = new InstanceElementDto(automationCompositionCopy.getInstanceId(), + acElement.getId(), Map.of(), Map.of(), ElementState.NOT_PRESENT); + var compositionElementTargetDto = + CacheProvider.changeStateToNew(compositionElementTargetMap.get(acElement.getId())); + var instanceElementTargetDto = + CacheProvider.changeStateToNew(instanceElementTargetMap.get(acElement.getId())); + + listenerRollback(migrationMsg.getMessageId(), compositionElementDto, compositionElementTargetDto, + instanceElementDto, instanceElementTargetDto, migrationMsg.getStage()); + + } else if (removed) { + var compositionDtoTarget = new CompositionElementDto( + automationCompositionCopy.getCompositionId(), acElement.getDefinition(), + Map.of(), Map.of(), ElementState.REMOVED); + var instanceElementDtoTarget = new InstanceElementDto(automationCompositionCopy.getInstanceId(), + acElement.getId(), Map.of(), Map.of(), ElementState.REMOVED); + listenerRollback(migrationMsg.getMessageId(), compositionElementMap.get(acElement.getId()), + compositionDtoTarget, instanceElementMap.get(acElement.getId()), instanceElementDtoTarget, + migrationMsg.getStage()); + + } else { // DEFAULT case + listenerRollback(migrationMsg.getMessageId(), compositionElementMap.get(acElement.getId()), + compositionElementTargetMap.get(acElement.getId()), + instanceElementMap.get(acElement.getId()), instanceElementTargetMap.get(acElement.getId()), + migrationMsg.getStage()); + } + } + } + } + + private Set getRollbackStageSet(AcElementDeploy acElement, UUID compositionId) { + if (MigrationState.NEW.equals(acElement.getMigrationState())) { + return Set.of(0); + } else { + var commonProperties = cacheProvider.getCommonProperties(compositionId, acElement.getDefinition()); + return AcmStageUtils.findStageSetMigrate(commonProperties); + } + } + private void listenerMigrate(UUID messageId, CompositionElementDto compositionElement, CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, - InstanceElementDto instanceElementMigrate, int stage, boolean rollback) { - if (rollback) { - listener.rollback(messageId, compositionElement, compositionElementTarget, instanceElement, - instanceElementMigrate, stage); - } else { - LOGGER.info("Invoking migration of element on the participant for {}", instanceElement.elementId()); - listener.migrate(messageId, compositionElement, compositionElementTarget, instanceElement, + InstanceElementDto instanceElementMigrate, int stage) { + LOGGER.info("Invoking migration of element on the participant for {}", instanceElement.elementId()); + listener.migrate(messageId, compositionElement, compositionElementTarget, instanceElement, instanceElementMigrate, stage); - } + } + + private void listenerRollback(UUID messageId, CompositionElementDto compositionElement, + CompositionElementDto compositionElementTarget, InstanceElementDto instanceElement, + InstanceElementDto instanceElementMigrate, int stage) { + LOGGER.info("Invoking rollback of element on the participant for {}", instanceElement.elementId()); + listener.rollback(messageId, compositionElement, compositionElementTarget, instanceElement, + instanceElementMigrate, stage); } } 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 30b52bd0f..039f6b960 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 @@ -44,6 +44,7 @@ import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCom import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantMessageType; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantPrimeAck; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantStatus; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; import org.onap.policy.clamp.models.acm.utils.AcmUtils; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; import org.slf4j.Logger; @@ -142,7 +143,7 @@ public class AutomationCompositionOutHandler { } if ((deployState != null && lockState != null) || (deployState == null && lockState == null) - || AcmUtils.isInTransitionalState(deployState, lockState, SubState.NONE)) { + || AcmStateUtils.isInTransitionalState(deployState, lockState, SubState.NONE)) { LOGGER.error("state error {} and {} cannot be handled", deployState, lockState); return; } diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/cache/CacheProvider.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/cache/CacheProvider.java index 240cbe891..b5cb46104 100644 --- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/cache/CacheProvider.java +++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/cache/CacheProvider.java @@ -164,12 +164,32 @@ public class CacheProvider { */ public Map getCommonProperties(@NonNull UUID compositionId, @NonNull ToscaConceptIdentifier definition) { - var acDefinition = acElementsDefinitions.get(compositionId); + var map = getAcElementDefinition(acElementsDefinitions.get(compositionId), definition); + return map != null ? map.getAutomationCompositionElementToscaNodeTemplate().getProperties() : new HashMap<>(); + } + + /** + * Get AutomationCompositionElementDefinition from AcDefinition and ToscaConceptIdentifier. + * + * @param acDefinition the AcDefinition + * @param definition the ToscaConceptIdentifier + * @return the AutomationCompositionElementDefinition + */ + public AutomationCompositionElementDefinition getAcElementDefinition(AcDefinition acDefinition, + ToscaConceptIdentifier definition) { if (acDefinition == null) { - return new HashMap<>(); + return null; } - var map = acDefinition.getElements().get(definition); - return map != null ? map.getAutomationCompositionElementToscaNodeTemplate().getProperties() : new HashMap<>(); + var acDefinitionElement = acDefinition.getElements().get(definition); + if (acDefinitionElement == null) { + var val = acDefinition.getElements().entrySet().stream() + .filter(entry -> definition.getName().equals(entry.getKey().getName())) + .findFirst(); + if (val.isPresent()) { + acDefinitionElement = val.get().getValue(); + } + } + return acDefinitionElement; } /** @@ -323,9 +343,10 @@ public class CacheProvider { */ public CompositionElementDto createCompositionElementDto(UUID compositionId, AutomationCompositionElement element) { var acDefinition = acElementsDefinitions.get(compositionId); - var acDefinitionElement = acDefinition != null ? acDefinition.getElements().get(element.getDefinition()) : null; + var acDefinitionElement = getAcElementDefinition(acDefinition, element.getDefinition()); - return (acDefinitionElement != null) ? new CompositionElementDto(compositionId, element.getDefinition(), + return (acDefinitionElement != null) ? new CompositionElementDto(compositionId, + acDefinitionElement.getAcElementDefinitionId(), acDefinitionElement.getAutomationCompositionElementToscaNodeTemplate().getProperties(), acDefinitionElement.getOutProperties()) : new CompositionElementDto(compositionId, element.getDefinition(), @@ -344,10 +365,9 @@ public class CacheProvider { var acDefinition = acElementsDefinitions.get(compositionId); Map map = new HashMap<>(); for (var element : automationComposition.getElements().values()) { - var acDefinitionElement = (acDefinition != null) ? acDefinition.getElements().get(element.getDefinition()) : - null; + var acDefinitionElement = getAcElementDefinition(acDefinition, element.getDefinition()); var compositionElement = (acDefinitionElement != null) - ? new CompositionElementDto(compositionId, element.getDefinition(), + ? new CompositionElementDto(compositionId, acDefinitionElement.getAcElementDefinitionId(), acDefinitionElement.getAutomationCompositionElementToscaNodeTemplate().getProperties(), acDefinitionElement.getOutProperties()) : new CompositionElementDto(compositionId, element.getDefinition(), diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java index d1919d80d..752b6706c 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java @@ -26,9 +26,11 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +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.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.handler.AutomationCompositionOutHandler; @@ -245,4 +247,34 @@ class ParticipantIntermediaryApiImplTest { assertEquals(acElementDefinition.getOutProperties(), element.outProperties()); assertEquals(ElementState.PRESENT, element.state()); } + + @Test + void testGetMigrateNextStage() { + var cacheProvider = mock(CacheProvider.class); + var automationCompositionHandler = mock(AutomationCompositionOutHandler.class); + var apiImpl = new ParticipantIntermediaryApiImpl(automationCompositionHandler, cacheProvider); + var migrate = Map.of("migrate", List.of(0, 2)); + Map stageSet = Map.of("stage", migrate); + var compositionElementTarget = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + stageSet, Map.of()); + var result = apiImpl.getMigrateNextStage(compositionElementTarget, 0); + assertEquals(2, result); + result = apiImpl.getMigrateNextStage(compositionElementTarget, 2); + assertEquals(2, result); + } + + @Test + void testGetRollbackNextStage() { + var cacheProvider = mock(CacheProvider.class); + var automationCompositionHandler = mock(AutomationCompositionOutHandler.class); + var apiImpl = new ParticipantIntermediaryApiImpl(automationCompositionHandler, cacheProvider); + var migrate = Map.of("migrate", List.of(0, 2)); + Map stageSet = Map.of("stage", migrate); + var compositionElementTarget = new CompositionElementDto(UUID.randomUUID(), new ToscaConceptIdentifier(), + stageSet, Map.of()); + var result = apiImpl.getRollbackNextStage(compositionElementTarget, 0); + assertEquals(2, result); + result = apiImpl.getRollbackNextStage(compositionElementTarget, 2); + assertEquals(2, result); + } } 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 1553d3075..46002cb61 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 @@ -43,6 +43,7 @@ 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; 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.MigrationState; import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionDeploy; @@ -52,6 +53,7 @@ import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCom 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.messages.rest.instantiation.LockOrder; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; class AutomationCompositionHandlerTest { @@ -249,33 +251,11 @@ class AutomationCompositionHandlerTest { verify(listener, times(0)).deploy(any(), any(), any()); } - @Test - void handleMigrationNullTest() { - var ach = new AutomationCompositionHandler( - mock(CacheProvider.class), mock(ParticipantMessagePublisher.class), mock(ThreadHandler.class)); - var migrationMsg = new AutomationCompositionMigration(); - var rollbackMsg = new AutomationCompositionMigration(); - rollbackMsg.setRollback(true); - - migrationMsg.setStage(0); - assertDoesNotThrow(() -> ach.handleAutomationCompositionMigration(migrationMsg)); - migrationMsg.setAutomationCompositionId(UUID.randomUUID()); - migrationMsg.setCompositionTargetId(UUID.randomUUID()); - assertDoesNotThrow(() -> ach.handleAutomationCompositionMigration(migrationMsg)); - - rollbackMsg.setStage(0); - assertDoesNotThrow(() -> ach.handleAutomationCompositionMigration(rollbackMsg)); - rollbackMsg.setAutomationCompositionId(UUID.randomUUID()); - rollbackMsg.setCompositionTargetId(UUID.randomUUID()); - assertDoesNotThrow(() -> ach.handleAutomationCompositionMigration(rollbackMsg)); - } - @Test void handleAutomationCompositionMigrationTest() { var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); automationComposition.setCompositionId(UUID.randomUUID()); - var instanceId = UUID.randomUUID(); - automationComposition.setInstanceId(instanceId); + automationComposition.setInstanceId(UUID.randomUUID()); automationComposition.setCompositionTargetId(UUID.randomUUID()); var definitions = CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); @@ -294,87 +274,42 @@ class AutomationCompositionHandlerTest { automationComposition.getElements().size(), false); testMigration(cacheProviderRollback, automationComposition, 0, automationComposition.getElements().size(), true); - - // New participant with new elements added in Migration - cacheProvider.removeAutomationComposition(instanceId); - for (var element : automationComposition.getElements().entrySet()) { - element.getValue().setMigrationState(MigrationState.NEW); - } - testMigration(cacheProvider, automationComposition, 0, - automationComposition.getElements().size(), false); - } - - @Test - void handleMigrationAddRemoveTest() { - var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); - automationComposition.setCompositionId(UUID.randomUUID()); - automationComposition.setInstanceId(UUID.randomUUID()); - - var acMigrate = new AutomationComposition(automationComposition); - acMigrate.setCompositionTargetId(UUID.randomUUID()); - - // remove element - var element = acMigrate.getElements().values().iterator().next(); - element.setMigrationState(MigrationState.REMOVED); - - //Add element - var newElement = new AutomationCompositionElement(element); - newElement.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.2.4")); - newElement.setId(UUID.randomUUID()); - newElement.setMigrationState(MigrationState.NEW); - - acMigrate.getElements().put(newElement.getId(), newElement); - - var migrateDefinitions = - CommonTestData.createAutomationCompositionElementDefinitionList(acMigrate); - - var participantDeploy = - CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition); - var definitions = - CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); - var cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), - automationComposition.getInstanceId(), definitions, - acMigrate.getCompositionTargetId(), migrateDefinitions); - var cacheProviderRollback = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), - automationComposition.getInstanceId(), definitions, - acMigrate.getCompositionTargetId(), migrateDefinitions); - - testMigration(cacheProvider, acMigrate, 0, acMigrate.getElements().size(), false); - testMigration(cacheProviderRollback, acMigrate, 0, acMigrate.getElements().size(), true); } - @Test void handleAcMigrationStageTest() { var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + AcmStateUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED); automationComposition.setCompositionId(UUID.randomUUID()); automationComposition.setInstanceId(UUID.randomUUID()); var acMigrate = new AutomationComposition(automationComposition); + AcmStateUtils.setCascadedState(acMigrate, DeployState.MIGRATING, LockState.LOCKED); acMigrate.setCompositionTargetId(UUID.randomUUID()); - // remove element - var element = acMigrate.getElements().values().iterator().next(); - element.setMigrationState(MigrationState.REMOVED); - - //Add element - var newElement = new AutomationCompositionElement(element); - newElement.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.2.4")); - newElement.setId(UUID.randomUUID()); - newElement.setMigrationState(MigrationState.NEW); - - acMigrate.getElements().put(newElement.getId(), newElement); + // remove first element + var elementRemoved = acMigrate.getElements().values().iterator().next(); + elementRemoved.setMigrationState(MigrationState.REMOVED); + // add new element + var element = new AutomationCompositionElement(elementRemoved); + element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.2.4")); + element.setId(UUID.randomUUID()); + element.setMigrationState(MigrationState.NEW); + acMigrate.getElements().put(element.getId(), element); - // replacing definition version - acMigrate.getElements().values().forEach(el -> el.setDefinition( - new ToscaConceptIdentifier(el.getDefinition().getName(), "1.2.4"))); + // replacing definition version excluding the removed element + acMigrate.getElements().values().stream() + .filter(el -> !el.getId().equals(elementRemoved.getId())) + .forEach(el -> el.setDefinition( + new ToscaConceptIdentifier(el.getDefinition().getName(), "1.2.4"))); var migrateDefinitions = CommonTestData.createAutomationCompositionElementDefinitionList(acMigrate); + // scenario 1,2 migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() - .setProperties(Map.of("stage", List.of(0, 1)))); + .setProperties(Map.of("stage", List.of(1, 2)))); var participantDeploy = CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition); @@ -383,41 +318,30 @@ class AutomationCompositionHandlerTest { var cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), automationComposition.getInstanceId(), definitions, acMigrate.getCompositionTargetId(), migrateDefinitions); - var cacheProviderRollback = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), - automationComposition.getInstanceId(), definitions, - acMigrate.getCompositionTargetId(), migrateDefinitions); - - // scenario 1,2 - migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() + definitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() .setProperties(Map.of("stage", List.of(1, 2)))); + automationComposition.getElements().put(element.getId(), element); // expected the element deleted testMigration(cacheProvider, acMigrate, 0, 1, false); - testMigration(cacheProviderRollback, acMigrate, 0, 1, true); // expected 4 elements from stage 1 testMigration(cacheProvider, acMigrate, 1, 4, false); - testMigration(cacheProviderRollback, acMigrate, 1, 4, true); // scenario 0,2 cacheProvider = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), automationComposition.getInstanceId(), definitions, acMigrate.getCompositionTargetId(), migrateDefinitions); - cacheProviderRollback = createCacheProvider(participantDeploy, automationComposition.getCompositionId(), - automationComposition.getInstanceId(), definitions, - acMigrate.getCompositionTargetId(), migrateDefinitions); migrateDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() .setProperties(Map.of("stage", List.of(0, 2)))); // expected the element deleted + 4 elements from stage 0 testMigration(cacheProvider, acMigrate, 0, 5, false); - testMigration(cacheProviderRollback, acMigrate, 0, 5, true); // expected 0 elements testMigration(cacheProvider, acMigrate, 1, 0, false); - testMigration(cacheProviderRollback, acMigrate, 1, 0, true); } private CacheProvider createCacheProvider(ParticipantDeploy participantDeploy, @@ -455,4 +379,65 @@ class AutomationCompositionHandlerTest { verify(listener, times(expectedMigrated)).rollback(any(), any(), any(), any(), any(), anyInt()); } } + + @Test + void handleAcRollbackStageTest() { + var automationComposition = CommonTestData.getTestAutomationCompositionMap().values().iterator().next(); + AcmStateUtils.setCascadedState(automationComposition, DeployState.MIGRATING, LockState.LOCKED); + automationComposition.setCompositionId(UUID.randomUUID()); + automationComposition.setInstanceId(UUID.randomUUID()); + automationComposition.setCompositionTargetId(UUID.randomUUID()); + + var acRollback = new AutomationComposition(automationComposition); + AcmStateUtils.setCascadedState(acRollback, DeployState.MIGRATION_REVERTING, LockState.LOCKED); + + var acRollbackDefinitions = + CommonTestData.createAutomationCompositionElementDefinitionList(acRollback); + acRollbackDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() + .setProperties(Map.of("stage", List.of(1, 2)))); + + // remove first element + var elementRemoved = automationComposition.getElements().values().iterator().next(); + elementRemoved.setMigrationState(MigrationState.REMOVED); + acRollback.getElements().get(elementRemoved.getId()).setMigrationState(MigrationState.REMOVED); + + // add new element + var element = new AutomationCompositionElement(elementRemoved); + element.setDefinition(new ToscaConceptIdentifier("policy.clamp.new.element", "1.2.4")); + element.setId(UUID.randomUUID()); + element.setMigrationState(MigrationState.NEW); + automationComposition.getElements().put(element.getId(), element); + acRollback.getElements().put(element.getId(), element); + + // replacing definition version excluding the removed element + automationComposition.getElements().values().stream() + .filter(el -> !el.getId().equals(elementRemoved.getId())) + .forEach(el -> el.setDefinition( + new ToscaConceptIdentifier(el.getDefinition().getName(), "1.2.4"))); + + var acDefinitions = + CommonTestData.createAutomationCompositionElementDefinitionList(automationComposition); + acDefinitions.forEach(el -> el.getAutomationCompositionElementToscaNodeTemplate() + .setProperties(Map.of("stage", List.of(1, 2)))); + + var participantDeploy = + CommonTestData.createparticipantDeploy(CommonTestData.getParticipantId(), automationComposition); + var cacheProvider = new CacheProvider(CommonTestData.getParticipantParameters()); + cacheProvider.addElementDefinition( + automationComposition.getCompositionTargetId(), acDefinitions, UUID.randomUUID()); + cacheProvider.initializeAutomationComposition(automationComposition.getCompositionId(), + automationComposition.getInstanceId(), participantDeploy, UUID.randomUUID()); + cacheProvider.addElementDefinition( + automationComposition.getCompositionId(), acRollbackDefinitions, UUID.randomUUID()); + + // expected the new element deleted + testMigration(cacheProvider, acRollback, 0, 1, true); + + // expected default elements + testMigration(cacheProvider, acRollback, 1, 4, true); + + // expected default elements + testMigration(cacheProvider, acRollback, 2, 4, true); + } + } diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java index edcb51590..f5e336b36 100644 --- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java +++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java @@ -38,6 +38,7 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDef import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; 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.MigrationState; import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy; import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc; import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType; @@ -297,7 +298,9 @@ public class CommonTestData { createAutomationCompositionElementDefinitionList(AutomationComposition automationComposition) { List definitions = new ArrayList<>(); for (var element : automationComposition.getElements().values()) { - definitions.add(createAutomationCompositionElementDefinition(element.getDefinition())); + if (!MigrationState.REMOVED.equals(element.getMigrationState())) { + definitions.add(createAutomationCompositionElementDefinition(element.getDefinition())); + } } return definitions; } 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 83af86d43..8531c6b99 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 @@ -40,7 +40,6 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions; 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.MigrationState; -import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; 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.messages.rest.instantiation.AcInstanceStateUpdate; @@ -52,6 +51,8 @@ import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvide import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; +import org.onap.policy.clamp.models.acm.utils.AcmStageUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; import org.onap.policy.clamp.models.acm.utils.AcmUtils; import org.onap.policy.common.parameters.BeanValidationResult; import org.onap.policy.models.base.PfModelRuntimeException; @@ -98,7 +99,7 @@ public class AutomationCompositionInstantiationProvider { var acDefinition = acDefinitionProvider.getAcDefinition(compositionId); AcDefinitionProvider.checkPrimedComposition(acDefinition); - var validationResult = validateAutomationComposition(automationComposition, acDefinition, false); + var validationResult = validateAutomationComposition(automationComposition, acDefinition, 0); if (!validationResult.isValid()) { throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } else { @@ -138,7 +139,7 @@ public class AutomationCompositionInstantiationProvider { acFromDb.setVersion(automationComposition.getVersion()); acFromDb.setDescription(automationComposition.getDescription()); acFromDb.setDerivedFrom(automationComposition.getDerivedFrom()); - var validationResult = validateAutomationComposition(acFromDb, acDefinition, false); + var validationResult = validateAutomationComposition(acFromDb, acDefinition, 0); if (!validationResult.isValid()) { throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } else { @@ -201,7 +202,7 @@ public class AutomationCompositionInstantiationProvider { AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties()); } - var validationResult = validateAutomationComposition(acToBeUpdated, acDefinition, false); + var validationResult = validateAutomationComposition(acToBeUpdated, acDefinition, 0); if (!validationResult.isValid()) { throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } else { @@ -248,14 +249,14 @@ public class AutomationCompositionInstantiationProvider { private void updateAcForMigration(AutomationComposition acFromDb, AutomationCompositionDefinition acDefinition, DeployState deployState) { - AcmUtils.setCascadedState(acFromDb, deployState, LockState.LOCKED); + AcmStateUtils.setCascadedState(acFromDb, deployState, LockState.LOCKED); acFromDb.setStateChangeResult(StateChangeResult.NO_ERROR); - var stage = ParticipantUtils.getFirstStage(acFromDb, acDefinition.getServiceTemplate()); + var stage = AcmStageUtils.getFirstStage(acFromDb, acDefinition.getServiceTemplate()); acFromDb.setPhase(stage); } private void updateAcForProperties(AutomationComposition acToBeUpdated) { - AcmUtils.setCascadedState(acToBeUpdated, DeployState.UPDATING, acToBeUpdated.getLockState()); + AcmStateUtils.setCascadedState(acToBeUpdated, DeployState.UPDATING, acToBeUpdated.getLockState()); acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR); } @@ -281,7 +282,7 @@ public class AutomationCompositionInstantiationProvider { // Publish migrate event to the participants supervisionAcHandler.migratePrecheck(copyAc, acDefinition.getRevisionId(), acDefinitionTarget.getRevisionId()); - AcmUtils.setCascadedState(acToBeUpdated, DeployState.DEPLOYED, LockState.LOCKED, + AcmStateUtils.setCascadedState(acToBeUpdated, DeployState.DEPLOYED, LockState.LOCKED, SubState.MIGRATION_PRECHECKING); acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR); @@ -296,12 +297,12 @@ public class AutomationCompositionInstantiationProvider { * @return the result of validation */ private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition, - AutomationCompositionDefinition acDefinition, boolean migrateOperation) { + AutomationCompositionDefinition acDefinition, int removeElement) { var result = new BeanValidationResult("AutomationComposition", automationComposition); participantProvider.checkRegisteredParticipant(acDefinition); result.addResult(AcmUtils.validateAutomationComposition(automationComposition, acDefinition.getServiceTemplate(), - acRuntimeParameterGroup.getAcmParameters().getToscaCompositionName(), migrateOperation)); + acRuntimeParameterGroup.getAcmParameters().getToscaCompositionName(), removeElement)); result.addResult(automationCompositionProvider.validateElementIds(automationComposition)); @@ -450,12 +451,11 @@ public class AutomationCompositionInstantiationProvider { var automationCompositionToRollback = automationCompositionProvider.getAutomationCompositionRollback(instanceId); var acFromDbCopy = new AutomationComposition(acFromDb); - acFromDbCopy.setCompositionTargetId(automationCompositionToRollback.getCompositionId()); acFromDbCopy.setElements(automationCompositionToRollback.getElements().values().stream() .collect(Collectors.toMap(AutomationCompositionElement::getId, AutomationCompositionElement::new))); - var acDefinitionTarget = acDefinitionProvider.getAcDefinition(acFromDbCopy.getCompositionTargetId()); - var validationResult = validateAutomationComposition(acFromDbCopy, acDefinitionTarget, true); + var acDefinition = acDefinitionProvider.getAcDefinition(acFromDbCopy.getCompositionId()); + var validationResult = validateAutomationComposition(acFromDbCopy, acDefinition, 0); if (!validationResult.isValid()) { throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } @@ -469,9 +469,9 @@ public class AutomationCompositionInstantiationProvider { } } - updateAcForMigration(acFromDbCopy, acDefinitionTarget, DeployState.MIGRATION_REVERTING); + updateAcForMigration(acFromDbCopy, acDefinition, DeployState.MIGRATION_REVERTING); automationCompositionProvider.updateAutomationComposition(acFromDbCopy); - var acDefinition = acDefinitionProvider.getAcDefinition(acFromDbCopy.getCompositionId()); + var acDefinitionTarget = acDefinitionProvider.getAcDefinition(acFromDbCopy.getCompositionTargetId()); supervisionAcHandler.migrate(acFromDbCopy, acDefinition.getRevisionId(), acDefinitionTarget.getRevisionId()); } @@ -499,7 +499,7 @@ public class AutomationCompositionInstantiationProvider { elementsRemoved.forEach(element -> acFromDb.getElements().get(element.getId()) .setMigrationState(MigrationState.REMOVED)); - var validationResult = validateAutomationComposition(acFromDb, acDefinitionTarget, true); + var validationResult = validateAutomationComposition(acFromDb, acDefinitionTarget, elementsRemoved.size()); if (!validationResult.isValid()) { throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult()); } else { @@ -514,12 +514,12 @@ public class AutomationCompositionInstantiationProvider { for (var element : acFromDb.getElements().values()) { var name = element.getDefinition().getName(); var migrationState = element.getMigrationState(); - if (MigrationState.REMOVED.equals(migrationState) && oldAcDefinition != null) { - var participantId = oldAcDefinition.getElementStateMap().get(name).getParticipantId(); - element.setParticipantId(participantId); - } else { + if (MigrationState.DEFAULT.equals(migrationState) || MigrationState.NEW.equals(migrationState)) { var participantId = acDefinitionTarget.getElementStateMap().get(name).getParticipantId(); element.setParticipantId(participantId); + } else if (MigrationState.REMOVED.equals(migrationState) && oldAcDefinition != null) { + var participantId = oldAcDefinition.getElementStateMap().get(name).getParticipantId(); + element.setParticipantId(participantId); } } } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java index a979bf874..eb1d3f6f0 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java @@ -42,13 +42,13 @@ import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition 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.MigrationState; -import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; 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.messages.kafka.participant.AutomationCompositionDeployAck; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.MessageProvider; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStageUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; import org.onap.policy.clamp.models.acm.utils.TimestampHelper; import org.onap.policy.models.base.PfModelRuntimeException; import org.slf4j.Logger; @@ -109,10 +109,10 @@ public class SupervisionAcHandler { } } } else { - AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYING, LockState.NONE); + AcmStateUtils.setCascadedState(automationComposition, DeployState.DEPLOYING, LockState.NONE); } automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); - var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); + var startPhase = AcmStageUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); automationComposition.setPhase(startPhase); automationCompositionProvider.updateAutomationComposition(automationComposition); executor.execute( @@ -142,10 +142,10 @@ public class SupervisionAcHandler { } } } else { - AcmUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYING, LockState.NONE); + AcmStateUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYING, LockState.NONE); } automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); - var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); + var startPhase = AcmStageUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); automationComposition.setPhase(startPhase); automationCompositionProvider.updateAutomationComposition(automationComposition); executor.execute(() -> automationCompositionStateChangePublisher.send(automationComposition, @@ -170,10 +170,10 @@ public class SupervisionAcHandler { } } } else { - AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.UNLOCKING); + AcmStateUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.UNLOCKING); } automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); - var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); + var startPhase = AcmStageUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); automationComposition.setPhase(startPhase); automationCompositionProvider.updateAutomationComposition(automationComposition); executor.execute( @@ -189,9 +189,10 @@ public class SupervisionAcHandler { */ public void prepare(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) { LOGGER.info("Prepare pre-deploy request received for instanceID: {}", automationComposition.getInstanceId()); - AcmUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYED, LockState.NONE, SubState.PREPARING); + AcmStateUtils + .setCascadedState(automationComposition, DeployState.UNDEPLOYED, LockState.NONE, SubState.PREPARING); automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); - var stage = ParticipantUtils.getFirstStage(automationComposition, acDefinition.getServiceTemplate()); + var stage = AcmStageUtils.getFirstStage(automationComposition, acDefinition.getServiceTemplate()); automationComposition.setPhase(stage); automationCompositionProvider.updateAutomationComposition(automationComposition); executor.execute(() -> { @@ -209,7 +210,8 @@ public class SupervisionAcHandler { */ public void review(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) { LOGGER.info("Prepare post-deploy request received for instanceID: {}", automationComposition.getInstanceId()); - AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED, SubState.REVIEWING); + AcmStateUtils + .setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED, SubState.REVIEWING); automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); automationCompositionProvider.updateAutomationComposition(automationComposition); executor.execute(() -> acPreparePublisher.sendReview(automationComposition, acDefinition.getRevisionId())); @@ -233,10 +235,10 @@ public class SupervisionAcHandler { } } } else { - AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKING); + AcmStateUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKING); } automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); - var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); + var startPhase = AcmStageUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); automationComposition.setPhase(startPhase); automationCompositionProvider.updateAutomationComposition(automationComposition); executor.execute( @@ -265,9 +267,9 @@ public class SupervisionAcHandler { * @param acDefinition the AutomationCompositionDefinition */ public void delete(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) { - AcmUtils.setCascadedState(automationComposition, DeployState.DELETING, LockState.NONE); + AcmStateUtils.setCascadedState(automationComposition, DeployState.DELETING, LockState.NONE); automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR); - var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); + var startPhase = AcmStageUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate()); automationComposition.setPhase(startPhase); automationCompositionProvider.updateAutomationComposition(automationComposition); executor.execute( @@ -348,7 +350,7 @@ public class SupervisionAcHandler { if ((acAckMessage.getStage() == null) && (acAckMessage.getAutomationCompositionResultMap() != null)) { for (var el : acAckMessage.getAutomationCompositionResultMap().values()) { - if (AcmUtils.isInTransitionalState(el.getDeployState(), el.getLockState(), SubState.NONE)) { + if (AcmStateUtils.isInTransitionalState(el.getDeployState(), el.getLockState(), SubState.NONE)) { LOGGER.error("Not valid AutomationCompositionDeployAck message, states are not valid"); return false; } diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java index 1cae2f862..61d04b47b 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionParticipantHandler.java @@ -41,7 +41,6 @@ import org.onap.policy.clamp.models.acm.concepts.Participant; import org.onap.policy.clamp.models.acm.concepts.ParticipantReplica; import org.onap.policy.clamp.models.acm.concepts.ParticipantState; import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType; -import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantDeregister; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantRegister; import org.onap.policy.clamp.models.acm.messages.kafka.participant.ParticipantReqSync; @@ -50,6 +49,7 @@ import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvide import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.MessageProvider; import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; +import org.onap.policy.clamp.models.acm.utils.AcmStageUtils; import org.onap.policy.clamp.models.acm.utils.TimestampHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -270,7 +270,7 @@ public class SupervisionParticipantHandler { encryptionUtils.decryptInstanceProperties(automationComposition); if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) { var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionTargetId()); - var stage = ParticipantUtils.getFirstStage(automationComposition, acDefinition.getServiceTemplate()); + var stage = AcmStageUtils.getFirstStage(automationComposition, acDefinition.getServiceTemplate()); if (automationComposition.getPhase().equals(stage)) { // scenario first stage migration var rollback = automationCompositionProvider.getAutomationCompositionRollback(automationCompositionId); diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java index df55b082d..046c44cbd 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java @@ -49,7 +49,8 @@ public class AutomationCompositionMigrationPublisher public void send(AutomationComposition automationComposition, int stage, UUID revisionIdComposition, UUID revisionIdCompositionTarget) { var acMigration = new AutomationCompositionMigration(); - acMigration.setRollback(DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState())); + var rollback = DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState()); + acMigration.setRollback(rollback); acMigration.setPrecheck(Boolean.TRUE.equals(automationComposition.getPrecheck())); acMigration.setCompositionId(automationComposition.getCompositionId()); acMigration.setAutomationCompositionId(automationComposition.getInstanceId()); @@ -59,7 +60,8 @@ public class AutomationCompositionMigrationPublisher acMigration.setRevisionIdInstance(automationComposition.getRevisionId()); acMigration.setRevisionIdComposition(revisionIdComposition); acMigration.setRevisionIdCompositionTarget(revisionIdCompositionTarget); - var participantUpdatesList = AcmUtils.createParticipantDeployList(automationComposition, DeployOrder.MIGRATE); + var participantUpdatesList = AcmUtils.createParticipantDeployList(automationComposition, + rollback ? DeployOrder.MIGRATION_REVERT : DeployOrder.MIGRATE); acMigration.setParticipantUpdatesList(participantUpdatesList); acMigration.setParticipantIdList(participantUpdatesList.stream() .map(ParticipantDeploy::getParticipantId).collect(Collectors.toSet())); diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionStateChangePublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionStateChangePublisher.java index ee358ff21..d8268c9f7 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionStateChangePublisher.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionStateChangePublisher.java @@ -26,7 +26,7 @@ import java.util.stream.Collectors; 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.messages.kafka.participant.AutomationCompositionStateChange; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; import org.springframework.stereotype.Component; /** @@ -52,8 +52,8 @@ public class AutomationCompositionStateChangePublisher acsc.setCompositionId(automationComposition.getCompositionId()); acsc.setAutomationCompositionId(automationComposition.getInstanceId()); acsc.setMessageId(UUID.randomUUID()); - acsc.setDeployOrderedState(AcmUtils.stateDeployToOrder(automationComposition.getDeployState())); - acsc.setLockOrderedState(AcmUtils.stateLockToOrder(automationComposition.getLockState())); + acsc.setDeployOrderedState(AcmStateUtils.stateDeployToOrder(automationComposition.getDeployState())); + acsc.setLockOrderedState(AcmStateUtils.stateLockToOrder(automationComposition.getLockState())); acsc.setStartPhase(startPhase); acsc.setFirstStartPhase(firstStartPhase); acsc.setRevisionIdInstance(automationComposition.getRevisionId()); diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AbstractScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AbstractScanner.java index 5ad8ea9a4..85f12b7a7 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AbstractScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AbstractScanner.java @@ -27,11 +27,11 @@ import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublish import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.DeployState; import org.onap.policy.clamp.models.acm.concepts.MigrationState; -import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; 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.AutomationCompositionProvider; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; +import org.onap.policy.clamp.models.acm.utils.AcmTimeoutUtils; import org.onap.policy.clamp.models.acm.utils.TimestampHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -61,20 +61,22 @@ public abstract class AbstractScanner { automationComposition.getSubState()); var deployState = automationComposition.getDeployState(); + if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) { + // migration completed + automationComposition.setCompositionId(automationComposition.getCompositionTargetId()); + } if (DeployState.MIGRATING.equals(automationComposition.getDeployState()) || DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState())) { - // migration scenario - automationComposition.setCompositionId(automationComposition.getCompositionTargetId()); automationComposition.setCompositionTargetId(null); - for (var acElement : automationComposition.getElements().values()) { if (MigrationState.NEW.equals(acElement.getMigrationState())) { acElement.setMigrationState(MigrationState.DEFAULT); } } } - automationComposition.setDeployState(AcmUtils.deployCompleted(deployState)); - automationComposition.setLockState(AcmUtils.lockCompleted(deployState, automationComposition.getLockState())); + automationComposition.setDeployState(AcmStateUtils.deployCompleted(deployState)); + automationComposition.setLockState( + AcmStateUtils.lockCompleted(deployState, automationComposition.getLockState())); automationComposition.setPhase(null); automationComposition.setSubState(SubState.NONE); automationComposition.setPrecheck(null); @@ -106,10 +108,10 @@ public abstract class AbstractScanner { saveAndSync(automationComposition, updateSync); return; } - var name = ParticipantUtils.getOpName(automationComposition.getDeployState()); + var name = AcmTimeoutUtils.getOpName(automationComposition.getDeployState()); var element = automationComposition.getElements().values().stream() .filter(el -> automationComposition.getDeployState().equals(el.getDeployState())).findFirst(); - var maxWaitMs = element.map(automationCompositionElement -> ParticipantUtils.getTimeout( + var maxWaitMs = element.map(automationCompositionElement -> AcmTimeoutUtils.getTimeout( automationCompositionElement.getProperties(), name, maxOperationWaitMs)).orElse(maxOperationWaitMs); var now = TimestampHelper.nowEpochMilli(); var lastMsg = TimestampHelper.toEpochMilli(automationComposition.getLastMsg()); diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AcDefinitionScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AcDefinitionScanner.java index 797fe50a3..b7e3aa019 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AcDefinitionScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/AcDefinitionScanner.java @@ -25,10 +25,10 @@ import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher; import org.onap.policy.clamp.models.acm.concepts.AcTypeState; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; -import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; import org.onap.policy.clamp.models.acm.concepts.StateChangeResult; import org.onap.policy.clamp.models.acm.document.concepts.DocMessage; import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider; +import org.onap.policy.clamp.models.acm.utils.AcmTimeoutUtils; import org.onap.policy.clamp.models.acm.utils.TimestampHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -145,8 +145,8 @@ public class AcDefinitionScanner { LOGGER.debug("The ac definition is in timeout {}", acDefinition.getCompositionId()); return result; } - var name = ParticipantUtils.getOpName(acDefinition.getState()); - var maxWaitMs = ParticipantUtils + var name = AcmTimeoutUtils.getOpName(acDefinition.getState()); + var maxWaitMs = AcmTimeoutUtils .getTimeout(acDefinition.getServiceTemplate().getMetadata(), name, maxOperationWaitMs); var lastMsg = TimestampHelper.toEpochMilli(acDefinition.getLastMsg()); var now = TimestampHelper.nowEpochMilli(); diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/MonitoringScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/MonitoringScanner.java index 38fdede6c..b48a02b6c 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/MonitoringScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/MonitoringScanner.java @@ -34,7 +34,7 @@ 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.persistence.provider.MessageProvider; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -87,21 +87,26 @@ public class MonitoringScanner { automationCompositionOpt.ifPresent(ac -> updateSync.or(simpleScanner.scanMessage(ac, message))); messageProvider.removeMessage(message.getMessageId()); } - if (automationCompositionOpt.isPresent()) { - var automationComposition = automationCompositionOpt.get(); - if (automationComposition.getCompositionTargetId() != null) { - var acDefinitionTarget = acDefinitionMap.computeIfAbsent(automationComposition.getCompositionTargetId(), - acDefinitionProvider::getAcDefinition); - var acDefinition = acDefinitionMap.computeIfAbsent(automationComposition.getCompositionId(), - acDefinitionProvider::getAcDefinition); + automationCompositionOpt.ifPresent(ac -> scanAutomationComposition(ac, updateSync, acDefinitionMap)); + } + + private void scanAutomationComposition(final AutomationComposition automationComposition, UpdateSync updateSync, + Map acDefinitionMap) { + var acDefinition = acDefinitionMap.computeIfAbsent(automationComposition.getCompositionId(), + acDefinitionProvider::getAcDefinition); + if (AcmStateUtils.isMigrating(automationComposition.getDeployState())) { + var acDefinitionTarget = acDefinitionMap.computeIfAbsent(automationComposition.getCompositionTargetId(), + acDefinitionProvider::getAcDefinition); + if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) { scanAutomationComposition(automationComposition, acDefinitionTarget, updateSync, acDefinition.getRevisionId()); } else { - var acDefinition = acDefinitionMap.computeIfAbsent(automationComposition.getCompositionId(), - acDefinitionProvider::getAcDefinition); scanAutomationComposition(automationComposition, acDefinition, updateSync, - acDefinition.getRevisionId()); + acDefinitionTarget.getRevisionId()); } + } else { + scanAutomationComposition(automationComposition, acDefinition, updateSync, + acDefinition.getRevisionId()); } } @@ -109,7 +114,7 @@ public class MonitoringScanner { AutomationCompositionDefinition acDefinition, UpdateSync updateSync, UUID revisionIdComposition) { LOGGER.debug("scanning automation composition {} . . .", automationComposition.getInstanceId()); - if (!AcmUtils.isInTransitionalState(automationComposition.getDeployState(), + if (!AcmStateUtils.isInTransitionalState(automationComposition.getDeployState(), automationComposition.getLockState(), automationComposition.getSubState()) || StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) { LOGGER.debug("automation composition {} scanned, OK", automationComposition.getInstanceId()); @@ -117,8 +122,7 @@ public class MonitoringScanner { return; } - if (DeployState.MIGRATING.equals(automationComposition.getDeployState()) - || DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState()) + if (AcmStateUtils.isMigrating(automationComposition.getDeployState()) || SubState.PREPARING.equals(automationComposition.getSubState())) { stageScanner.scanStage(automationComposition, acDefinition, updateSync, revisionIdComposition); } else if (DeployState.UPDATING.equals(automationComposition.getDeployState()) diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScanner.java index ad2204a2e..73c93dcb3 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/PhaseScanner.java @@ -28,9 +28,9 @@ import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublish import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; import org.onap.policy.clamp.models.acm.concepts.DeployState; -import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStageUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; import org.springframework.stereotype.Component; @Component @@ -79,10 +79,10 @@ public class PhaseScanner extends AbstractScanner { .get(element.getDefinition().getName()); int startPhase = toscaNodeTemplate != null && element.getDefinition().getVersion().equals(toscaNodeTemplate.getVersion()) - ? ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties()) : 0; + ? AcmStageUtils.findStartPhase(toscaNodeTemplate.getProperties()) : 0; defaultMin = Math.min(defaultMin, startPhase); defaultMax = Math.max(defaultMax, startPhase); - if (AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), + if (AcmStateUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), element.getSubState())) { completed = false; minSpNotCompleted = Math.min(minSpNotCompleted, startPhase); @@ -96,8 +96,8 @@ public class PhaseScanner extends AbstractScanner { LOGGER.debug("automation composition scan: transition state {} {} not completed", automationComposition.getDeployState(), automationComposition.getLockState()); - var isForward = - AcmUtils.isForward(automationComposition.getDeployState(), automationComposition.getLockState()); + var isForward = AcmStateUtils + .isForward(automationComposition.getDeployState(), automationComposition.getLockState()); var nextSpNotCompleted = isForward ? minSpNotCompleted : maxSpNotCompleted; diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScanner.java index 226d39a17..8105198c8 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScanner.java @@ -24,12 +24,11 @@ import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils; import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; -import org.onap.policy.clamp.models.acm.concepts.DeployState; 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.document.concepts.DocMessage; import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @@ -115,7 +114,7 @@ public class SimpleScanner extends AbstractScanner { */ public void simpleScan(final AutomationComposition automationComposition, UpdateSync updateSync) { var completed = automationComposition.getElements().values().stream() - .filter(element -> AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), + .filter(element -> AcmStateUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), element.getSubState())).findFirst().isEmpty(); if (completed) { diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScanner.java index 9b79c1b30..3df9ccb76 100644 --- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScanner.java +++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScanner.java @@ -21,10 +21,7 @@ package org.onap.policy.clamp.acm.runtime.supervision.scanner; import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashSet; import java.util.List; -import java.util.Set; import java.util.UUID; import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup; import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils; @@ -33,14 +30,12 @@ import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionM import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher; import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition; -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.MigrationState; -import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils; 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.AutomationCompositionProvider; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStageUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; import org.springframework.stereotype.Component; @Component @@ -84,13 +79,13 @@ public class StageScanner extends AbstractScanner { var minStageNotCompleted = 1000; // min stage not completed List elementsDeleted = new ArrayList<>(); for (var element : automationComposition.getElements().values()) { - if (AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), + if (AcmStateUtils.isInTransitionalState(element.getDeployState(), element.getLockState(), element.getSubState())) { - var minStage = calculateMinStage(element, automationComposition, acDefinition); - int stage = element.getStage() != null ? element.getStage() : minStage; + var firstStage = AcmStageUtils.getFirstStage(element, acDefinition.getServiceTemplate()); + int stage = element.getStage() != null ? element.getStage() : firstStage; minStageNotCompleted = Math.min(minStageNotCompleted, stage); completed = false; - } else if (DeployState.DELETED.equals(element.getDeployState()) + } else if (element.getDeployState().equals(DeployState.DELETED) && automationComposition.getStateChangeResult().equals(StateChangeResult.NO_ERROR)) { // Migration with successful removal of element elementsDeleted.add(element.getId()); @@ -115,7 +110,6 @@ public class StageScanner extends AbstractScanner { savePhase(automationComposition, minStageNotCompleted); updateSync.setUpdated(true); saveAndSync(automationComposition, updateSync); - LOGGER.debug("retry message AutomationCompositionMigration"); var acToSend = new AutomationComposition(automationComposition); decryptInstanceProperties(acToSend); sendNextStage(acToSend, minStageNotCompleted, revisionIdComposition, acDefinition); @@ -124,20 +118,6 @@ public class StageScanner extends AbstractScanner { } } - private Integer calculateMinStage(AutomationCompositionElement element, AutomationComposition automationComposition, - AutomationCompositionDefinition acDefinition) { - Set stageSet = new HashSet<>(); - if (! MigrationState.REMOVED.equals(element.getMigrationState())) { - var toscaNodeTemplate = acDefinition.getServiceTemplate().getToscaTopologyTemplate().getNodeTemplates() - .get(element.getDefinition().getName()); - stageSet = DeployState.MIGRATING.equals(automationComposition.getDeployState()) - || DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState()) - ? ParticipantUtils.findStageSetMigrate(toscaNodeTemplate.getProperties()) - : ParticipantUtils.findStageSetPrepare(toscaNodeTemplate.getProperties()); - } - return stageSet.stream().min(Comparator.comparing(Integer::valueOf)).orElse(0); - } - private void removeDeletedElements(AutomationComposition automationComposition, List elementsDeleted, UpdateSync updateSync) { for (var elementId : elementsDeleted) { @@ -150,14 +130,16 @@ public class StageScanner extends AbstractScanner { private void sendNextStage(final AutomationComposition automationComposition, int minStageNotCompleted, UUID revisionIdComposition, AutomationCompositionDefinition acDefinition) { - if (DeployState.MIGRATING.equals(automationComposition.getDeployState()) - || DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState())) { - LOGGER.debug("retry message AutomationCompositionMigration"); + if (DeployState.MIGRATING.equals(automationComposition.getDeployState())) { + LOGGER.debug("retry migrating message AutomationCompositionMigration"); // acDefinition for migration is the Composition target acMigrationPublisher.send(automationComposition, minStageNotCompleted, revisionIdComposition, acDefinition.getRevisionId()); - } - if (SubState.PREPARING.equals(automationComposition.getSubState())) { + } else if (DeployState.MIGRATION_REVERTING.equals(automationComposition.getDeployState())) { + LOGGER.debug("retry rollback message AutomationCompositionMigration"); + acMigrationPublisher.send(automationComposition, minStageNotCompleted, acDefinition.getRevisionId(), + revisionIdComposition); + } else if (SubState.PREPARING.equals(automationComposition.getSubState())) { LOGGER.debug("retry message AutomationCompositionPrepare"); acPreparePublisher.sendPrepare(automationComposition, minStageNotCompleted, acDefinition.getRevisionId()); } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java index ff0f9b005..9e63cd25c 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java @@ -63,7 +63,7 @@ import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateReso import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider; import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider; import org.onap.policy.clamp.models.acm.persistence.provider.ProviderUtils; -import org.onap.policy.clamp.models.acm.utils.AcmUtils; +import org.onap.policy.clamp.models.acm.utils.AcmStateUtils; import org.onap.policy.models.base.PfModelRuntimeException; import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate; @@ -315,7 +315,7 @@ class AutomationCompositionInstantiationProviderTest { InstantiationUtils.assertInstantiationResponse(preCheckResponse, automationCompositionTarget); automationCompositionTarget.setPrecheck(false); - AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED, + AcmStateUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE); var instantiationResponse = instantiationProvider.updateAutomationComposition(compositionId, automationCompositionTarget); @@ -596,15 +596,17 @@ class AutomationCompositionInstantiationProviderTest { @Test void testRollbackSuccess() { var acDefinitionProvider = mock(AcDefinitionProvider.class); - var acDefinition = CommonTestData.createAcDefinition(serviceTemplateMigration, AcTypeState.PRIMED); + var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); var compositionId = acDefinition.getCompositionId(); when(acDefinitionProvider.getAcDefinition(compositionId)).thenReturn(acDefinition); var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_MIGRATE_JSON, "Crud"); var instanceId = UUID.randomUUID(); + var compositionTargetId = UUID.randomUUID(); automationComposition.setInstanceId(instanceId); automationComposition.setCompositionId(compositionId); + automationComposition.setCompositionTargetId(compositionTargetId); automationComposition.setDeployState(DeployState.MIGRATING); automationComposition.setLockState(LockState.LOCKED); automationComposition.setStateChangeResult(StateChangeResult.FAILED); @@ -617,7 +619,6 @@ class AutomationCompositionInstantiationProviderTest { InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud"); var rollbackRecord = new AutomationCompositionRollback(); - var compositionTargetId = UUID.randomUUID(); rollbackRecord.setCompositionId(compositionTargetId); rollbackRecord.setInstanceId(instanceId); rollbackRecord.setElements(acRollback.getElements()); @@ -629,7 +630,7 @@ class AutomationCompositionInstantiationProviderTest { var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup(), encryptionUtils); - var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED); + var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplateMigration, AcTypeState.PRIMED); when(acDefinitionProvider.getAcDefinition(compositionTargetId)).thenReturn(acDefinitionTarget); instantiationProvider.rollback(compositionId, automationComposition.getInstanceId()); 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 4c3473da3..0a9ae36d7 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 @@ -397,10 +397,10 @@ class SupervisionScannerTest { when(automationCompositionProvider.findAutomationComposition(automationComposition.getInstanceId())) .thenReturn(Optional.of(automationComposition)); - var definitionTarget = createAutomationCompositionDefinition(AcTypeState.PRIMED); - definitionTarget.setCompositionId(compositionTargetId); + var acDefinitionTarget = createAutomationCompositionDefinition(AcTypeState.PRIMED); + acDefinitionTarget.setCompositionId(compositionTargetId); var acDefinitionProvider = createAcDefinitionProvider(AcTypeState.PRIMED); - when(acDefinitionProvider.getAcDefinition(compositionTargetId)).thenReturn(definitionTarget); + when(acDefinitionProvider.getAcDefinition(compositionTargetId)).thenReturn(acDefinitionTarget); var acDefinition = new AutomationCompositionDefinition(); acDefinition.setCompositionId(COMPOSITION_ID); when(acDefinitionProvider.getAcDefinition(COMPOSITION_ID)).thenReturn(acDefinition); @@ -415,8 +415,8 @@ class SupervisionScannerTest { messageProvider, monitoringScanner); supervisionScanner.run(); - verify(stageScanner).scanStage(automationComposition, definitionTarget, new UpdateSync(), - acDefinition.getRevisionId()); + verify(stageScanner).scanStage(automationComposition, acDefinition, new UpdateSync(), + acDefinitionTarget.getRevisionId()); verify(messageProvider).removeJob(JOB_ID); } diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScannerTest.java index 30d16d57b..16ee7acd5 100644 --- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScannerTest.java +++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/StageScannerTest.java @@ -154,7 +154,6 @@ class StageScannerTest { verify(acProvider).updateAutomationComposition(any(AutomationComposition.class)); assertEquals(DeployState.DEPLOYED, automationComposition.getDeployState()); - assertEquals(compositionTargetId, automationComposition.getCompositionId()); } @Test