aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java153
-rw-r--r--models/src/main/java/org/onap/policy/clamp/models/acm/utils/AcmUtils.java28
-rw-r--r--models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolverTest.java74
-rw-r--r--models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java19
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProvider.java134
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java43
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java17
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcPreparePublisher.java78
-rw-r--r--runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AutomationCompositionMigrationPublisher.java6
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java121
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java68
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java24
12 files changed, 615 insertions, 150 deletions
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java
index ace246c5d..fd8b63582 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolver.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation.
+ * Copyright (C) 2023-2024 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,8 +23,10 @@ package org.onap.policy.clamp.models.acm.persistence.provider;
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.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.messages.rest.instantiation.SubOrder;
import org.onap.policy.clamp.models.acm.utils.StateDefinition;
import org.springframework.stereotype.Component;
@@ -39,6 +41,10 @@ public class AcInstanceStateResolver {
private static final String UPDATING = DeployState.UPDATING.name();
private static final String DELETING = DeployState.DELETING.name();
private static final String MIGRATING = DeployState.MIGRATING.name();
+ private static final String MIGRATION_PRECHECKING = SubState.MIGRATION_PRECHECKING.name();
+ private static final String PREPARING = SubState.PREPARING.name();
+ private static final String REVIEWING = SubState.REVIEWING.name();
+ private static final String SUB_STATE_NONE = SubState.NONE.name();
private static final String LOCKED = LockState.LOCKED.name();
private static final String LOCKING = LockState.LOCKING.name();
@@ -48,6 +54,7 @@ public class AcInstanceStateResolver {
private static final String DEPLOY_NONE = DeployOrder.NONE.name();
private static final String LOCK_NONE = LockOrder.NONE.name();
+ private static final String SUB_NONE = SubOrder.NONE.name();
private static final String NO_ERROR = StateChangeResult.NO_ERROR.name();
private static final String FAILED = StateChangeResult.FAILED.name();
@@ -60,55 +67,105 @@ public class AcInstanceStateResolver {
public static final String LOCK = LockOrder.LOCK.name();
public static final String UNLOCK = LockOrder.UNLOCK.name();
public static final String MIGRATE = DeployOrder.MIGRATE.name();
+ public static final String MIGRATE_PRECHECK = SubOrder.MIGRATE_PRECHECK.name();
+ public static final String PREPARE = SubOrder.PREPARE.name();
+ public static final String REVIEW = SubOrder.REVIEW.name();
+ public static final String UPDATE = DeployOrder.UPDATE.name();
public static final String NONE = "NONE";
/**
* Construct.
*/
public AcInstanceStateResolver() {
- this.graph = new StateDefinition<>(5, NONE);
-
- // no error
- this.graph.put(new String[] {DEPLOY, LOCK_NONE, UNDEPLOYED, STATE_LOCKED_NONE, NO_ERROR}, DEPLOY);
- this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, DEPLOYED, LOCKED, NO_ERROR}, UNDEPLOY);
- this.graph.put(new String[] {DELETE, LOCK_NONE, UNDEPLOYED, LOCK_NONE, NO_ERROR}, DELETE);
- this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, LOCKED, NO_ERROR}, UNLOCK);
- this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, UNLOCKED, NO_ERROR}, LOCK);
- this.graph.put(new String[] {MIGRATE, LOCK_NONE, DEPLOYED, LOCKED, NO_ERROR}, MIGRATE);
-
- // failed
- this.graph.put(new String[] {DEPLOY, LOCK_NONE, UNDEPLOYING, STATE_LOCKED_NONE, FAILED}, DEPLOY);
- this.graph.put(new String[] {DEPLOY, LOCK_NONE, DEPLOYING, STATE_LOCKED_NONE, FAILED}, DEPLOY);
-
- this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UNDEPLOYING, STATE_LOCKED_NONE, FAILED}, UNDEPLOY);
- this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UPDATING, LOCKED, FAILED}, UNDEPLOY);
- this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, MIGRATING, LOCKED, FAILED}, UNDEPLOY);
- this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, DEPLOYING, STATE_LOCKED_NONE, FAILED}, UNDEPLOY);
-
- this.graph.put(new String[] {DELETE, LOCK_NONE, DELETING, LOCK_NONE, FAILED}, DELETE);
-
- this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, LOCKING, FAILED}, UNLOCK);
- this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, UNLOCKING, FAILED}, UNLOCK);
-
- this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, LOCKING, FAILED}, LOCK);
- this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, UNLOCKING, FAILED}, LOCK);
+ this.graph = new StateDefinition<>(7, NONE);
+
+ // make an order when there are no fails
+ this.graph.put(new String[] {DEPLOY, LOCK_NONE, SUB_NONE,
+ UNDEPLOYED, STATE_LOCKED_NONE, SUB_STATE_NONE, NO_ERROR}, DEPLOY);
+ this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE,
+ DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, UNDEPLOY);
+ this.graph.put(new String[] {DELETE, LOCK_NONE, SUB_NONE,
+ UNDEPLOYED, LOCK_NONE, SUB_STATE_NONE, NO_ERROR}, DELETE);
+ this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, SUB_NONE,
+ DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, UNLOCK);
+ this.graph.put(new String[] {DEPLOY_NONE, LOCK, SUB_NONE,
+ DEPLOYED, UNLOCKED, SUB_STATE_NONE, NO_ERROR}, LOCK);
+ this.graph.put(new String[] {MIGRATE, LOCK_NONE, SUB_NONE,
+ DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, MIGRATE);
+ this.graph.put(new String[] {UPDATE, LOCK_NONE, SUB_NONE,
+ DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, UPDATE);
+ this.graph.put(new String[] {DEPLOY_NONE, LOCK_NONE, REVIEW,
+ DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, REVIEW);
+ this.graph.put(new String[] {DEPLOY_NONE, LOCK_NONE, PREPARE,
+ UNDEPLOYED, STATE_LOCKED_NONE, SUB_STATE_NONE, NO_ERROR}, PREPARE);
+ this.graph.put(new String[] {DEPLOY_NONE, LOCK_NONE, MIGRATE_PRECHECK,
+ DEPLOYED, LOCKED, SUB_STATE_NONE, NO_ERROR}, MIGRATE_PRECHECK);
+
+ // make an order in a failed scenario
+ this.graph.put(new String[] {DEPLOY, LOCK_NONE, SUB_NONE,
+ UNDEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, FAILED}, DEPLOY);
+ this.graph.put(new String[] {DEPLOY, LOCK_NONE, SUB_NONE,
+ DEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, FAILED}, DEPLOY);
+
+ this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE,
+ UNDEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, FAILED}, UNDEPLOY);
+ this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE,
+ UPDATING, LOCKED, SUB_STATE_NONE, FAILED}, UNDEPLOY);
+ this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE,
+ MIGRATING, LOCKED, SUB_STATE_NONE, FAILED}, UNDEPLOY);
+ this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE,
+ DEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, FAILED}, UNDEPLOY);
+
+ this.graph.put(new String[] {DELETE, LOCK_NONE, SUB_NONE,
+ DELETING, LOCK_NONE, SUB_STATE_NONE, FAILED}, DELETE);
+
+ this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, SUB_NONE,
+ DEPLOYED, LOCKING, SUB_STATE_NONE, FAILED}, UNLOCK);
+ this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, SUB_NONE,
+ DEPLOYED, UNLOCKING, SUB_STATE_NONE, FAILED}, UNLOCK);
+
+ this.graph.put(new String[] {DEPLOY_NONE, LOCK, SUB_NONE, DEPLOYED, LOCKING, SUB_STATE_NONE, FAILED}, LOCK);
+ this.graph.put(new String[] {DEPLOY_NONE, LOCK, SUB_NONE, DEPLOYED, UNLOCKING, SUB_STATE_NONE, FAILED}, LOCK);
+
+ this.graph.put(new String[] {UPDATE, LOCK_NONE, SUB_NONE, UPDATING, LOCKED, SUB_STATE_NONE, FAILED}, UPDATE);
+
+ this.graph.put(new String[] {DEPLOY_NONE, LOCK_NONE, MIGRATE_PRECHECK,
+ DEPLOYED, LOCKED, MIGRATION_PRECHECKING, FAILED}, MIGRATE_PRECHECK);
// timeout
- this.graph.put(new String[] {DEPLOY, LOCK_NONE, UNDEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, DEPLOY);
- this.graph.put(new String[] {DEPLOY, LOCK_NONE, DEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, DEPLOY);
-
- this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UNDEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, UNDEPLOY);
- this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, UPDATING, LOCKED, TIMEOUT}, UNDEPLOY);
- this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, MIGRATING, LOCKED, TIMEOUT}, UNDEPLOY);
- this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, DEPLOYING, STATE_LOCKED_NONE, TIMEOUT}, UNDEPLOY);
-
- this.graph.put(new String[] {DELETE, LOCK_NONE, DELETING, LOCK_NONE, TIMEOUT}, DELETE);
-
- this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, LOCKING, TIMEOUT}, UNLOCK);
- this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, LOCKING, TIMEOUT}, LOCK);
-
- this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, UNLOCKING, TIMEOUT}, LOCK);
- this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, UNLOCKING, TIMEOUT}, UNLOCK);
+ this.graph.put(new String[] {DEPLOY, LOCK_NONE, SUB_NONE,
+ UNDEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, TIMEOUT}, DEPLOY);
+ this.graph.put(new String[] {DEPLOY, LOCK_NONE, SUB_NONE,
+ DEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, TIMEOUT}, DEPLOY);
+
+ this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE,
+ UNDEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY);
+ this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE,
+ UPDATING, LOCKED, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY);
+ this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE,
+ MIGRATING, LOCKED, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY);
+ this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE,
+ MIGRATION_PRECHECKING, LOCKED, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY);
+ this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, SUB_NONE,
+ DEPLOYING, STATE_LOCKED_NONE, SUB_STATE_NONE, TIMEOUT}, UNDEPLOY);
+
+ this.graph.put(new String[] {DELETE, LOCK_NONE, SUB_NONE,
+ DELETING, LOCK_NONE, SUB_STATE_NONE, TIMEOUT}, DELETE);
+
+ this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, SUB_NONE,
+ DEPLOYED, LOCKING, SUB_STATE_NONE, TIMEOUT}, UNLOCK);
+ this.graph.put(new String[] {DEPLOY_NONE, LOCK, SUB_NONE,
+ DEPLOYED, LOCKING, SUB_STATE_NONE, TIMEOUT}, LOCK);
+
+ this.graph.put(new String[] {DEPLOY_NONE, LOCK, SUB_NONE,
+ DEPLOYED, UNLOCKING, SUB_STATE_NONE, TIMEOUT}, LOCK);
+ this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, SUB_NONE,
+ DEPLOYED, UNLOCKING, SUB_STATE_NONE, TIMEOUT}, UNLOCK);
+
+ this.graph.put(new String[] {UPDATE, LOCK_NONE, SUB_NONE, UPDATING, LOCKED, SUB_STATE_NONE, TIMEOUT}, UPDATE);
+
+ this.graph.put(new String[] {DEPLOY_NONE, LOCK_NONE, MIGRATE_PRECHECK,
+ DEPLOYED, LOCKED, MIGRATION_PRECHECKING, TIMEOUT}, MIGRATE_PRECHECK);
}
/**
@@ -116,20 +173,24 @@ public class AcInstanceStateResolver {
*
* @param acDeployOrder the Deploy Ordered
* @param acLockOrder the Lock Ordered
+ * @param acSubOrder the Sub Ordered
* @param acDeployState then current Deploy State
* @param acLockState the current Lock State
+ * @param acSubState the current Sub State
* @param acStateChangeResult the current Result of the State Change
* @return the order (DEPLOY/UNDEPLOY/LOCK/UNLOCK) to send to participant or NONE if order is not consistent
*/
- public String resolve(DeployOrder acDeployOrder, LockOrder acLockOrder, DeployState acDeployState,
- LockState acLockState, StateChangeResult acStateChangeResult) {
+ public String resolve(DeployOrder acDeployOrder, LockOrder acLockOrder, SubOrder acSubOrder,
+ DeployState acDeployState, LockState acLockState, SubState acSubState, StateChangeResult acStateChangeResult) {
var deployOrder = acDeployOrder != null ? acDeployOrder : DeployOrder.NONE;
var lockOrder = acLockOrder != null ? acLockOrder : LockOrder.NONE;
+ var subOrder = acSubOrder != null ? acSubOrder : SubOrder.NONE;
var stateChangeResult = acStateChangeResult != null ? acStateChangeResult : StateChangeResult.NO_ERROR;
var deployState = acDeployState != null ? acDeployState : DeployState.UNDEPLOYED;
var lockState = acLockState != null ? acLockState : LockState.NONE;
- return this.graph.get(new String[] {deployOrder.name(), lockOrder.name(), deployState.name(), lockState.name(),
- stateChangeResult.name()});
+ var subState = acSubState != null ? acSubState : SubState.NONE;
+ return this.graph.get(new String[] {deployOrder.name(), lockOrder.name(), subOrder.name(),
+ deployState.name(), lockState.name(), subState.name(), stateChangeResult.name()});
}
}
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 f90e5a807..50b8d14ad 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
@@ -51,6 +51,7 @@ 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;
@@ -288,16 +289,20 @@ public final class AcmUtils {
// @formatter:on
}
+
/**
- * Return true if DeployState and LockState are in a Transitional State.
+ * Return true if DeployState, LockState and SubState are in a Transitional State.
*
- * @return true if DeployState and LockState 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) {
+ 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.MIGRATING.equals(deployState) || !SubState.NONE.equals(subState);
}
/**
@@ -381,9 +386,23 @@ public final class AcmUtils {
*/
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;
@@ -392,6 +411,7 @@ public final class AcmUtils {
for (var element : automationComposition.getElements().values()) {
element.setDeployState(deployState);
element.setLockState(lockState);
+ element.setSubState(subState);
element.setMessage(null);
}
}
diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolverTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolverTest.java
index 7f6cb2f0c..a807a1179 100644
--- a/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolverTest.java
+++ b/models/src/test/java/org/onap/policy/clamp/models/acm/persistence/provider/AcInstanceStateResolverTest.java
@@ -1,6 +1,6 @@
/*-
* ============LICENSE_START=======================================================
- * Copyright (C) 2023 Nordix Foundation.
+ * Copyright (C) 2023-2024 Nordix Foundation.
* ================================================================================
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,42 +26,78 @@ import org.junit.jupiter.api.Test;
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.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.messages.rest.instantiation.SubOrder;
class AcInstanceStateResolverTest {
@Test
void testResolve() {
var acTypeStateResolver = new AcInstanceStateResolver();
- var result = acTypeStateResolver.resolve(DeployOrder.DEPLOY, LockOrder.NONE, DeployState.UNDEPLOYED,
- LockState.NONE, StateChangeResult.NO_ERROR);
+ // deploy
+ var result = acTypeStateResolver.resolve(DeployOrder.DEPLOY, LockOrder.NONE, SubOrder.NONE,
+ DeployState.UNDEPLOYED, LockState.NONE, SubState.NONE, StateChangeResult.NO_ERROR);
assertThat(result).isEqualTo(AcInstanceStateResolver.DEPLOY);
- result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.NONE, DeployState.DEPLOYED,
- LockState.LOCKED, StateChangeResult.NO_ERROR);
+
+ // undeploy
+ result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.NONE, SubOrder.NONE,
+ DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR);
assertThat(result).isEqualTo(AcInstanceStateResolver.UNDEPLOY);
- result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.UNLOCK, DeployState.DEPLOYED, LockState.LOCKED,
- StateChangeResult.NO_ERROR);
+
+ // unlock
+ result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.UNLOCK, SubOrder.NONE,
+ DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR);
assertThat(result).isEqualTo(AcInstanceStateResolver.UNLOCK);
- result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.LOCK, DeployState.DEPLOYED, LockState.UNLOCKED,
- StateChangeResult.NO_ERROR);
+
+ // lock
+ result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.LOCK, SubOrder.NONE,
+ DeployState.DEPLOYED, LockState.UNLOCKED, SubState.NONE, StateChangeResult.NO_ERROR);
assertThat(result).isEqualTo(AcInstanceStateResolver.LOCK);
- result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.NONE, DeployState.UNDEPLOYED, LockState.NONE,
- StateChangeResult.NO_ERROR);
+ // migrate
+ result = acTypeStateResolver.resolve(DeployOrder.MIGRATE, LockOrder.NONE, SubOrder.NONE,
+ DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR);
+ assertThat(result).isEqualTo(AcInstanceStateResolver.MIGRATE);
+
+ // migrate-precheck
+ result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.NONE, SubOrder.MIGRATE_PRECHECK,
+ DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR);
+ assertThat(result).isEqualTo(AcInstanceStateResolver.MIGRATE_PRECHECK);
+
+ // prepare
+ result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.NONE, SubOrder.PREPARE,
+ DeployState.UNDEPLOYED, LockState.NONE, SubState.NONE, StateChangeResult.NO_ERROR);
+ assertThat(result).isEqualTo(AcInstanceStateResolver.PREPARE);
+
+ // review
+ result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.NONE, SubOrder.REVIEW,
+ DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR);
+ assertThat(result).isEqualTo(AcInstanceStateResolver.REVIEW);
+ }
+
+ @Test
+ void testResolveWrongOrder() {
+ var acTypeStateResolver = new AcInstanceStateResolver();
+
+ var result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.NONE, SubOrder.NONE,
+ DeployState.UNDEPLOYED, LockState.NONE, SubState.NONE, StateChangeResult.NO_ERROR);
assertThat(result).isEqualTo(AcInstanceStateResolver.NONE);
- result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.UNLOCK, DeployState.DEPLOYED,
- LockState.LOCKED, StateChangeResult.NO_ERROR);
+
+ result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.UNLOCK, SubOrder.NONE,
+ DeployState.DEPLOYED, LockState.LOCKED, SubState.NONE, StateChangeResult.NO_ERROR);
assertThat(result).isEqualTo(AcInstanceStateResolver.NONE);
- result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.UNLOCK, DeployState.UNDEPLOYED, LockState.NONE,
- StateChangeResult.NO_ERROR);
+
+ result = acTypeStateResolver.resolve(DeployOrder.NONE, LockOrder.UNLOCK, SubOrder.NONE,
+ DeployState.UNDEPLOYED, LockState.NONE, SubState.NONE, StateChangeResult.NO_ERROR);
assertThat(result).isEqualTo(AcInstanceStateResolver.NONE);
- result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.NONE, DeployState.DEPLOYING,
- LockState.NONE, StateChangeResult.NO_ERROR);
+
+ result = acTypeStateResolver.resolve(DeployOrder.UNDEPLOY, LockOrder.NONE, SubOrder.NONE,
+ DeployState.DEPLOYING, LockState.NONE, SubState.NONE, StateChangeResult.NO_ERROR);
assertThat(result).isEqualTo(AcInstanceStateResolver.NONE);
- result = acTypeStateResolver.resolve(null, null, null, null, null);
+ result = acTypeStateResolver.resolve(null, null, null, null, null, null, null);
assertThat(result).isEqualTo(AcInstanceStateResolver.NONE);
}
-
}
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 f17eff398..5d0a7d95a 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
@@ -43,6 +43,7 @@ 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;
@@ -68,14 +69,16 @@ class AcmUtilsTest {
@Test
void testIsInTransitionalState() {
- assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKED)).isFalse();
- assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYING, LockState.NONE)).isTrue();
- assertThat(AcmUtils.isInTransitionalState(DeployState.UNDEPLOYING, LockState.NONE)).isTrue();
- assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.LOCKING)).isTrue();
- assertThat(AcmUtils.isInTransitionalState(DeployState.DEPLOYED, LockState.UNLOCKING)).isTrue();
- assertThat(AcmUtils.isInTransitionalState(DeployState.DELETING, LockState.NONE)).isTrue();
- assertThat(AcmUtils.isInTransitionalState(DeployState.UPDATING, LockState.LOCKED)).isTrue();
- assertThat(AcmUtils.isInTransitionalState(DeployState.MIGRATING, LockState.LOCKED)).isTrue();
+ 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.DEPLOYED, LockState.LOCKED,
+ SubState.MIGRATION_PRECHECKING)).isTrue();
}
@Test
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 2bf08220a..c732654f2 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
@@ -22,7 +22,6 @@
package org.onap.policy.clamp.acm.runtime.instantiation;
import jakarta.validation.Valid;
-import jakarta.ws.rs.core.Response;
import jakarta.ws.rs.core.Response.Status;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -37,8 +36,12 @@ import org.onap.policy.clamp.models.acm.concepts.DeployState;
import org.onap.policy.clamp.models.acm.concepts.LockState;
import org.onap.policy.clamp.models.acm.concepts.NodeTemplateState;
import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
+import org.onap.policy.clamp.models.acm.concepts.SubState;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.LockOrder;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.SubOrder;
import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver;
import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
@@ -82,19 +85,19 @@ public class AutomationCompositionInstantiationProvider {
public InstantiationResponse createAutomationComposition(UUID compositionId,
AutomationComposition automationComposition) {
if (!compositionId.equals(automationComposition.getCompositionId())) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
}
var checkAutomationCompositionOpt =
automationCompositionProvider.findAutomationComposition(automationComposition.getKey().asIdentifier());
if (checkAutomationCompositionOpt.isPresent()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
automationComposition.getKey().asIdentifier() + " already defined");
}
var validationResult = validateAutomationComposition(automationComposition);
if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
}
automationComposition = automationCompositionProvider.createAutomationComposition(automationComposition);
@@ -120,7 +123,7 @@ public class AutomationCompositionInstantiationProvider {
var instanceId = automationComposition.getInstanceId();
var acToUpdate = automationCompositionProvider.getAutomationComposition(instanceId);
if (!compositionId.equals(acToUpdate.getCompositionId())) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
}
if (DeployState.UNDEPLOYED.equals(acToUpdate.getDeployState())) {
@@ -131,22 +134,42 @@ public class AutomationCompositionInstantiationProvider {
acToUpdate.setDerivedFrom(automationComposition.getDerivedFrom());
var validationResult = validateAutomationComposition(acToUpdate);
if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
}
automationComposition = automationCompositionProvider.updateAutomationComposition(acToUpdate);
return createInstantiationResponse(automationComposition);
- } else if ((DeployState.DEPLOYED.equals(acToUpdate.getDeployState())
- || DeployState.UPDATING.equals(acToUpdate.getDeployState()))
- && LockState.LOCKED.equals(acToUpdate.getLockState())) {
- if (automationComposition.getCompositionTargetId() != null) {
- return migrateAutomationComposition(automationComposition, acToUpdate);
+ }
+
+ if (automationComposition.getRestarting() != null) {
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Update not allowed");
+ }
+
+ var deployOrder = DeployOrder.UPDATE;
+ var subOrder = SubOrder.NONE;
+
+ if (automationComposition.getCompositionTargetId() != null) {
+
+ if (Boolean.TRUE.equals(automationComposition.getPrecheck())) {
+ subOrder = SubOrder.MIGRATE_PRECHECK;
+ deployOrder = DeployOrder.NONE;
} else {
- return updateDeployedAutomationComposition(automationComposition, acToUpdate);
+ deployOrder = DeployOrder.MIGRATE;
}
}
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
- "Not allowed to update in the state " + acToUpdate.getDeployState());
+ var result = acInstanceStateResolver.resolve(deployOrder, LockOrder.NONE, subOrder,
+ acToUpdate.getDeployState(), acToUpdate.getLockState(), acToUpdate.getSubState(),
+ acToUpdate.getStateChangeResult());
+ return switch (result) {
+ case "UPDATE" -> updateDeployedAutomationComposition(automationComposition, acToUpdate);
+
+ case "MIGRATE" -> migrateAutomationComposition(automationComposition, acToUpdate);
+
+ case "MIGRATE_PRECHECK" -> migratePrecheckAc(automationComposition, acToUpdate);
+
+ default -> throw new PfModelRuntimeException(Status.BAD_REQUEST,
+ "Not allowed to " + deployOrder + " in the state " + acToUpdate.getDeployState());
+ };
}
/**
@@ -164,17 +187,14 @@ public class AutomationCompositionInstantiationProvider {
var elementId = element.getKey();
var dbAcElement = acToBeUpdated.getElements().get(elementId);
if (dbAcElement == null) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, "Element id not present " + elementId);
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, "Element id not present " + elementId);
}
AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties());
}
- if (automationComposition.getRestarting() != null) {
- throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Update not allowed");
- }
var validationResult = validateAutomationComposition(acToBeUpdated);
if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
}
// Publish property update event to the participants
supervisionAcHandler.update(acToBeUpdated);
@@ -187,26 +207,23 @@ public class AutomationCompositionInstantiationProvider {
AutomationComposition automationComposition, AutomationComposition acToBeUpdated) {
if (!DeployState.DEPLOYED.equals(acToBeUpdated.getDeployState())) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
"Not allowed to migrate in the state " + acToBeUpdated.getDeployState());
}
- if (automationComposition.getRestarting() != null) {
- throw new PfModelRuntimeException(Status.BAD_REQUEST, "There is a restarting process, Migrate not allowed");
- }
// Iterate and update the element property values
for (var element : automationComposition.getElements().entrySet()) {
var elementId = element.getKey();
var dbAcElement = acToBeUpdated.getElements().get(elementId);
if (dbAcElement == null) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, "Element id not present " + elementId);
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, "Element id not present " + elementId);
}
AcmUtils.recursiveMerge(dbAcElement.getProperties(), element.getValue().getProperties());
var newDefinition = element.getValue().getDefinition();
var compatibility =
newDefinition.asConceptKey().getCompatibility(dbAcElement.getDefinition().asConceptKey());
if (PfKey.Compatibility.DIFFERENT.equals(compatibility)) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
dbAcElement.getDefinition() + " is not compatible with " + newDefinition);
}
if (PfKey.Compatibility.MAJOR.equals(compatibility) || PfKey.Compatibility.MINOR.equals(compatibility)) {
@@ -219,17 +236,57 @@ public class AutomationCompositionInstantiationProvider {
var validationResult =
validateAutomationComposition(acToBeUpdated, automationComposition.getCompositionTargetId());
if (!validationResult.isValid()) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST, validationResult.getResult());
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
}
acToBeUpdated.setCompositionTargetId(automationComposition.getCompositionTargetId());
// Publish migrate event to the participants
- supervisionAcHandler.migrate(acToBeUpdated, automationComposition.getCompositionTargetId());
+ supervisionAcHandler.migrate(acToBeUpdated);
automationComposition = automationCompositionProvider.updateAutomationComposition(acToBeUpdated);
return createInstantiationResponse(automationComposition);
}
+ private InstantiationResponse migratePrecheckAc(
+ AutomationComposition automationComposition, AutomationComposition acToBeUpdated) {
+
+ acToBeUpdated.setPrecheck(true);
+ var copyAc = new AutomationComposition(acToBeUpdated);
+ // Iterate and update the element property values
+ for (var element : automationComposition.getElements().entrySet()) {
+ var elementId = element.getKey();
+ var copyElement = copyAc.getElements().get(elementId);
+ if (copyElement == null) {
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, "Element id not present " + elementId);
+ }
+ AcmUtils.recursiveMerge(copyElement.getProperties(), element.getValue().getProperties());
+ var newDefinition = element.getValue().getDefinition();
+ var compatibility =
+ newDefinition.asConceptKey().getCompatibility(copyElement.getDefinition().asConceptKey());
+ if (PfKey.Compatibility.DIFFERENT.equals(compatibility)) {
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
+ copyElement.getDefinition() + " is not compatible with " + newDefinition);
+ }
+ copyElement.setDefinition(element.getValue().getDefinition());
+ }
+
+ var validationResult =
+ validateAutomationComposition(copyAc, automationComposition.getCompositionTargetId());
+ if (!validationResult.isValid()) {
+ throw new PfModelRuntimeException(Status.BAD_REQUEST, validationResult.getResult());
+ }
+ copyAc.setCompositionTargetId(automationComposition.getCompositionTargetId());
+
+ // Publish migrate event to the participants
+ supervisionAcHandler.migratePrecheck(copyAc);
+
+ AcmUtils.setCascadedState(acToBeUpdated, DeployState.DEPLOYED, LockState.LOCKED,
+ SubState.MIGRATION_PRECHECKING);
+ acToBeUpdated.setStateChangeResult(StateChangeResult.NO_ERROR);
+
+ return createInstantiationResponse(automationCompositionProvider.updateAutomationComposition(acToBeUpdated));
+ }
+
private BeanValidationResult validateAutomationComposition(AutomationComposition automationComposition) {
return validateAutomationComposition(automationComposition, automationComposition.getCompositionId());
}
@@ -296,7 +353,7 @@ public class AutomationCompositionInstantiationProvider {
var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
if (!compositionId.equals(automationComposition.getCompositionId())
&& !compositionId.equals(automationComposition.getCompositionTargetId())) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
}
return automationComposition;
@@ -312,17 +369,17 @@ public class AutomationCompositionInstantiationProvider {
public InstantiationResponse deleteAutomationComposition(UUID compositionId, UUID instanceId) {
var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
if (!compositionId.equals(automationComposition.getCompositionId())) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
}
if (!DeployState.UNDEPLOYED.equals(automationComposition.getDeployState())
&& !DeployState.DELETING.equals(automationComposition.getDeployState())) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
"Automation composition state is still " + automationComposition.getDeployState());
}
if (DeployState.DELETING.equals(automationComposition.getDeployState())
&& StateChangeResult.NO_ERROR.equals(automationComposition.getStateChangeResult())) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
"Automation composition state is still " + automationComposition.getDeployState());
}
if (automationComposition.getRestarting() != null) {
@@ -366,7 +423,7 @@ public class AutomationCompositionInstantiationProvider {
@Valid AcInstanceStateUpdate acInstanceStateUpdate) {
var automationComposition = automationCompositionProvider.getAutomationComposition(instanceId);
if (!compositionId.equals(automationComposition.getCompositionId())) {
- throw new PfModelRuntimeException(Response.Status.BAD_REQUEST,
+ throw new PfModelRuntimeException(Status.BAD_REQUEST,
automationComposition.getCompositionId() + DO_NOT_MATCH + compositionId);
}
var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId());
@@ -376,8 +433,9 @@ public class AutomationCompositionInstantiationProvider {
participantProvider.verifyParticipantState(participantIds);
var result = acInstanceStateResolver.resolve(acInstanceStateUpdate.getDeployOrder(),
- acInstanceStateUpdate.getLockOrder(), automationComposition.getDeployState(),
- automationComposition.getLockState(), automationComposition.getStateChangeResult());
+ acInstanceStateUpdate.getLockOrder(), acInstanceStateUpdate.getSubOrder(),
+ automationComposition.getDeployState(), automationComposition.getLockState(),
+ automationComposition.getSubState(), automationComposition.getStateChangeResult());
switch (result) {
case "DEPLOY":
supervisionAcHandler.deploy(automationComposition, acDefinition);
@@ -395,6 +453,14 @@ public class AutomationCompositionInstantiationProvider {
supervisionAcHandler.unlock(automationComposition, acDefinition);
break;
+ case "PREPARE":
+ supervisionAcHandler.prepare(automationComposition);
+ break;
+
+ case "REVIEW":
+ supervisionAcHandler.review(automationComposition);
+ break;
+
default:
throw new PfModelRuntimeException(Status.BAD_REQUEST, "Not valid " + acInstanceStateUpdate);
}
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 75477866a..a8d26871a 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
@@ -30,6 +30,7 @@ import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import lombok.AllArgsConstructor;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AcElementPropertiesPublisher;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.AcPreparePublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionMigrationPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher;
@@ -42,6 +43,7 @@ import org.onap.policy.clamp.models.acm.concepts.DeployState;
import org.onap.policy.clamp.models.acm.concepts.LockState;
import org.onap.policy.clamp.models.acm.concepts.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.AcDefinitionProvider;
import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
@@ -68,6 +70,7 @@ public class SupervisionAcHandler {
private final AcElementPropertiesPublisher acElementPropertiesPublisher;
private final AutomationCompositionMigrationPublisher acCompositionMigrationPublisher;
private final ParticipantSyncPublisher participantSyncPublisher;
+ private final AcPreparePublisher acPreparePublisher;
private final ExecutorService executor = Context.taskWrapping(Executors.newFixedThreadPool(1));
@@ -150,6 +153,30 @@ public class SupervisionAcHandler {
}
/**
+ * Handle prepare Pre Deploy an AutomationComposition instance.
+ *
+ * @param automationComposition the AutomationComposition
+ */
+ public void prepare(AutomationComposition automationComposition) {
+ AcmUtils.setCascadedState(automationComposition, DeployState.UNDEPLOYED, LockState.NONE, SubState.PREPARING);
+ automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
+ executor.execute(() -> acPreparePublisher.sendPrepare(automationComposition));
+ }
+
+ /**
+ * Handle prepare Post Deploy an AutomationComposition instance.
+ *
+ * @param automationComposition the AutomationComposition
+ */
+ public void review(AutomationComposition automationComposition) {
+ AcmUtils.setCascadedState(automationComposition, DeployState.DEPLOYED, LockState.LOCKED, SubState.REVIEWING);
+ automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
+ automationCompositionProvider.updateAutomationComposition(automationComposition);
+ executor.execute(() -> acPreparePublisher.sendRevew(automationComposition));
+ }
+
+ /**
* Handle Lock an AutomationComposition instance.
*
* @param automationComposition the AutomationComposition
@@ -285,6 +312,7 @@ public class SupervisionAcHandler {
element.setOutProperties(acElementAck.getValue().getOutProperties());
element.setOperationalState(acElementAck.getValue().getOperationalState());
element.setUseState(acElementAck.getValue().getUseState());
+ element.setSubState(SubState.NONE);
element.setDeployState(acElementAck.getValue().getDeployState());
element.setLockState(acElementAck.getValue().getLockState());
element.setRestarting(null);
@@ -308,12 +336,19 @@ public class SupervisionAcHandler {
* Handle Migration of an AutomationComposition instance to other ACM Definition.
*
* @param automationComposition the AutomationComposition
- * @param compositionTargetId the ACM Definition Id
*/
- public void migrate(AutomationComposition automationComposition, UUID compositionTargetId) {
+ public void migrate(AutomationComposition automationComposition) {
AcmUtils.setCascadedState(automationComposition, DeployState.MIGRATING, LockState.LOCKED);
automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
- executor.execute(
- () -> acCompositionMigrationPublisher.send(automationComposition, compositionTargetId));
+ executor.execute(() -> acCompositionMigrationPublisher.send(automationComposition));
+ }
+
+ /**
+ * Handle Migration precheck of an AutomationComposition instance to other ACM Definition.
+ *
+ * @param automationComposition the AutomationComposition
+ */
+ public void migratePrecheck(AutomationComposition automationComposition) {
+ executor.execute(() -> acCompositionMigrationPublisher.send(automationComposition));
}
}
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java
index d1aa6c239..e723d2c0b 100644
--- a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScanner.java
@@ -34,6 +34,7 @@ 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.concepts.StateChangeResult;
+import org.onap.policy.clamp.models.acm.concepts.SubState;
import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
import org.onap.policy.clamp.models.acm.utils.AcmUtils;
@@ -133,7 +134,7 @@ public class SupervisionScanner {
LOGGER.debug("scanning automation composition {} . . .", automationComposition.getInstanceId());
if (!AcmUtils.isInTransitionalState(automationComposition.getDeployState(),
- automationComposition.getLockState())
+ automationComposition.getLockState(), automationComposition.getSubState())
|| StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) {
LOGGER.debug("automation composition {} scanned, OK", automationComposition.getInstanceId());
@@ -151,7 +152,8 @@ public class SupervisionScanner {
int startPhase = ParticipantUtils.findStartPhase(toscaNodeTemplate.getProperties());
defaultMin = Math.min(defaultMin, startPhase);
defaultMax = Math.max(defaultMax, startPhase);
- if (AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState())) {
+ if (AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState(),
+ element.getSubState())) {
completed = false;
minSpNotCompleted = Math.min(minSpNotCompleted, startPhase);
maxSpNotCompleted = Math.max(maxSpNotCompleted, startPhase);
@@ -168,7 +170,8 @@ public class SupervisionScanner {
automationComposition.getDeployState(), automationComposition.getLockState());
if (DeployState.UPDATING.equals(automationComposition.getDeployState())
- || DeployState.MIGRATING.equals(automationComposition.getDeployState())) {
+ || DeployState.MIGRATING.equals(automationComposition.getDeployState())
+ || !SubState.NONE.equals(automationComposition.getSubState())) {
// UPDATING do not need phases
handleTimeoutUpdate(automationComposition);
return;
@@ -198,6 +201,8 @@ public class SupervisionScanner {
automationComposition.setDeployState(AcmUtils.deployCompleted(deployState));
automationComposition.setLockState(AcmUtils.lockCompleted(deployState, automationComposition.getLockState()));
automationComposition.setPhase(null);
+ automationComposition.setSubState(SubState.NONE);
+ automationComposition.setPrecheck(null);
if (StateChangeResult.TIMEOUT.equals(automationComposition.getStateChangeResult())) {
automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
}
@@ -233,7 +238,8 @@ public class SupervisionScanner {
var now = TimestampHelper.nowEpochMilli();
var lastMsg = TimestampHelper.toEpochMilli(automationComposition.getLastMsg());
for (var element : automationComposition.getElements().values()) {
- if (!AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState())) {
+ if (!AcmUtils.isInTransitionalState(
+ element.getDeployState(), element.getLockState(), element.getSubState())) {
continue;
}
if ((now - lastMsg) > maxStatusWaitMs) {
@@ -255,7 +261,8 @@ public class SupervisionScanner {
var now = TimestampHelper.nowEpochMilli();
var lastMsg = TimestampHelper.toEpochMilli(automationComposition.getLastMsg());
for (var element : automationComposition.getElements().values()) {
- if (!AcmUtils.isInTransitionalState(element.getDeployState(), element.getLockState())) {
+ if (!AcmUtils.isInTransitionalState(
+ element.getDeployState(), element.getLockState(), element.getSubState())) {
continue;
}
var toscaNodeTemplate = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates()
diff --git a/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcPreparePublisher.java b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcPreparePublisher.java
new file mode 100644
index 000000000..acf403595
--- /dev/null
+++ b/runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/comm/AcPreparePublisher.java
@@ -0,0 +1,78 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2024 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.runtime.supervision.comm;
+
+import io.micrometer.core.annotation.Timed;
+import java.time.Instant;
+import java.util.UUID;
+import lombok.AllArgsConstructor;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCompositionPrepare;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+@Component
+@AllArgsConstructor
+public class AcPreparePublisher extends AbstractParticipantPublisher<AutomationCompositionPrepare> {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(AcPreparePublisher.class);
+
+ /**
+ * Send AutomationCompositionPrepare Prepare message to Participant.
+ *
+ * @param automationComposition the AutomationComposition
+ */
+ @Timed(value = "publisher.prepare", description = "AC Prepare Pre Deploy published")
+ public void sendPrepare(AutomationComposition automationComposition) {
+ var acPrepare = createAutomationCompositionPrepare(automationComposition.getCompositionId(),
+ automationComposition.getInstanceId());
+ acPrepare.setParticipantList(
+ AcmUtils.createParticipantDeployList(automationComposition, DeployOrder.NONE));
+ LOGGER.debug("AC Prepare sent {}", acPrepare);
+ super.send(acPrepare);
+ }
+
+ /**
+ * Send AutomationCompositionPrepare Review message to Participant.
+ *
+ * @param automationComposition the AutomationComposition
+ */
+ @Timed(value = "publisher.review", description = "AC Review Post Deploy published")
+ public void sendRevew(AutomationComposition automationComposition) {
+ var acPrepare = createAutomationCompositionPrepare(automationComposition.getCompositionId(),
+ automationComposition.getInstanceId());
+ acPrepare.setPreDeploy(false);
+ LOGGER.debug("AC Review sent {}", acPrepare);
+ super.send(acPrepare);
+ }
+
+ private AutomationCompositionPrepare createAutomationCompositionPrepare(UUID compositionId, UUID instanceId) {
+ var acPrepare = new AutomationCompositionPrepare();
+ acPrepare.setCompositionId(compositionId);
+ acPrepare.setAutomationCompositionId(instanceId);
+ acPrepare.setMessageId(UUID.randomUUID());
+ acPrepare.setTimestamp(Instant.now());
+ return acPrepare;
+ }
+}
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 e26a5403b..b961eab93 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
@@ -36,17 +36,17 @@ public class AutomationCompositionMigrationPublisher
* Send AutomationCompositionMigration message to Participant.
*
* @param automationComposition the AutomationComposition
- * @param compositionTargetId the Composition Definition Target
*/
@Timed(
value = "publisher.automation_composition_migration",
description = "AUTOMATION_COMPOSITION_MIGRATION messages published")
- public void send(AutomationComposition automationComposition, UUID compositionTargetId) {
+ public void send(AutomationComposition automationComposition) {
var acsc = new AutomationCompositionMigration();
+ acsc.setPrecheck(Boolean.TRUE.equals(automationComposition.getPrecheck()));
acsc.setCompositionId(automationComposition.getCompositionId());
acsc.setAutomationCompositionId(automationComposition.getInstanceId());
acsc.setMessageId(UUID.randomUUID());
- acsc.setCompositionTargetId(compositionTargetId);
+ acsc.setCompositionTargetId(automationComposition.getCompositionTargetId());
acsc.setParticipantUpdatesList(
AcmUtils.createParticipantDeployList(automationComposition, DeployOrder.MIGRATE));
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 2ee6a152e..0591ab02c 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
@@ -48,6 +48,7 @@ import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
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.messages.rest.instantiation.SubOrder;
import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
import org.onap.policy.clamp.models.acm.persistence.provider.AcInstanceStateResolver;
import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
@@ -169,7 +170,7 @@ class AutomationCompositionInstantiationProviderTest {
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var participantProvider = mock(ParticipantProvider.class);
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
- null, supervisionAcHandler, participantProvider,
+ new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
CommonTestData.getTestParamaterGroup());
var instantiationResponse = instantiationProvider.updateAutomationComposition(
automationCompositionUpdate.getCompositionId(), automationCompositionUpdate);
@@ -200,15 +201,15 @@ class AutomationCompositionInstantiationProviderTest {
.thenReturn(automationCompositionUpdate);
var instantiationProvider =
- new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class), null,
- mock(SupervisionAcHandler.class), mock(ParticipantProvider.class),
- mock(AcRuntimeParameterGroup.class));
+ new AutomationCompositionInstantiationProvider(acProvider, mock(AcDefinitionProvider.class),
+ new AcInstanceStateResolver(), mock(SupervisionAcHandler.class), mock(ParticipantProvider.class),
+ mock(AcRuntimeParameterGroup.class));
var compositionId = automationCompositionUpdate.getCompositionId();
assertThatThrownBy(
() -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
.hasMessageMatching(
- "Not allowed to update in the state " + automationCompositionUpdate.getDeployState());
+ "Not allowed to UPDATE in the state " + automationCompositionUpdate.getDeployState());
automationCompositionUpdate.setDeployState(DeployState.UPDATING);
automationCompositionUpdate.setLockState(LockState.LOCKED);
@@ -216,7 +217,7 @@ class AutomationCompositionInstantiationProviderTest {
assertThatThrownBy(
() -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
.hasMessageMatching(
- "Not allowed to migrate in the state " + automationCompositionUpdate.getDeployState());
+ "Not allowed to MIGRATE in the state " + automationCompositionUpdate.getDeployState());
}
@Test
@@ -243,7 +244,7 @@ class AutomationCompositionInstantiationProviderTest {
automationCompositionUpdate.setCompositionTargetId(UUID.randomUUID());
assertThatThrownBy(
() -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
- .hasMessageMatching("There is a restarting process, Migrate not allowed");
+ .hasMessageMatching("There is a restarting process, Update not allowed");
automationCompositionUpdate.setDeployState(DeployState.UNDEPLOYED);
automationCompositionUpdate.setLockState(LockState.NONE);
@@ -275,7 +276,7 @@ class AutomationCompositionInstantiationProviderTest {
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var participantProvider = mock(ParticipantProvider.class);
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
- null, supervisionAcHandler, participantProvider,
+ new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
mock(AcRuntimeParameterGroup.class));
assertThatThrownBy(
() -> instantiationProvider.updateAutomationComposition(compositionId, automationCompositionUpdate))
@@ -305,7 +306,7 @@ class AutomationCompositionInstantiationProviderTest {
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var participantProvider = mock(ParticipantProvider.class);
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
- null, supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup());
+ new AcInstanceStateResolver(), supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup());
assertThatThrownBy(() -> instantiationProvider
.updateAutomationComposition(automationComposition.getCompositionId(), automationComposition))
@@ -321,7 +322,51 @@ class AutomationCompositionInstantiationProviderTest {
var instantiationResponse = instantiationProvider
.updateAutomationComposition(automationComposition.getCompositionId(), automationComposition);
- verify(supervisionAcHandler).migrate(any(), any());
+ verify(supervisionAcHandler).migrate(any());
+ verify(acProvider).updateAutomationComposition(automationComposition);
+ InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationComposition);
+ }
+
+
+ @Test
+ void testInstantiationMigrationPrecheck() {
+ var acDefinitionProvider = mock(AcDefinitionProvider.class);
+ var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+ var compositionId = acDefinition.getCompositionId();
+ when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
+
+ var automationComposition =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+ automationComposition.setCompositionId(compositionId);
+ automationComposition.setDeployState(DeployState.DEPLOYED);
+ automationComposition.setLockState(LockState.LOCKED);
+ automationComposition.setCompositionTargetId(UUID.randomUUID());
+ automationComposition.setPrecheck(true);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
+ .thenReturn(automationComposition);
+ when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition);
+
+ var supervisionAcHandler = mock(SupervisionAcHandler.class);
+ var acmParticipantProvider = mock(ParticipantProvider.class);
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
+ new AcInstanceStateResolver(), supervisionAcHandler, acmParticipantProvider, new AcRuntimeParameterGroup());
+
+ assertThatThrownBy(() -> instantiationProvider
+ .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition))
+ .hasMessageMatching(
+ String.format(AC_DEFINITION_NOT_FOUND, automationComposition.getCompositionTargetId()));
+
+ var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+ var compositionTargetId = acDefinitionTarget.getCompositionId();
+ when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget));
+
+ automationComposition.setCompositionTargetId(compositionTargetId);
+
+ var instantiationResponse = instantiationProvider
+ .updateAutomationComposition(automationComposition.getCompositionId(), automationComposition);
+
+ verify(supervisionAcHandler).migratePrecheck(any());
verify(acProvider).updateAutomationComposition(automationComposition);
InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationComposition);
}
@@ -354,7 +399,45 @@ class AutomationCompositionInstantiationProviderTest {
var supervisionAcHandler = mock(SupervisionAcHandler.class);
var participantProvider = mock(ParticipantProvider.class);
var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
- null, supervisionAcHandler, participantProvider, new AcRuntimeParameterGroup());
+ new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
+ new AcRuntimeParameterGroup());
+
+ assertThatThrownBy(() -> instantiationProvider
+ .updateAutomationComposition(automationComposition.getCompositionId(), acMigrate))
+ .hasMessageStartingWith("Element id not present");
+ }
+
+ @Test
+ void testMigratePrecheckBadRequest() {
+ var acDefinitionProvider = mock(AcDefinitionProvider.class);
+ var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+ var compositionId = acDefinition.getCompositionId();
+ when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
+
+ var automationComposition =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+ automationComposition.setCompositionId(compositionId);
+ automationComposition.setDeployState(DeployState.DEPLOYED);
+ automationComposition.setLockState(LockState.LOCKED);
+ automationComposition.setPrecheck(true);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
+ .thenReturn(automationComposition);
+ when(acProvider.updateAutomationComposition(automationComposition)).thenReturn(automationComposition);
+
+ var acDefinitionTarget = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
+ var compositionTargetId = acDefinitionTarget.getCompositionId();
+ when(acDefinitionProvider.findAcDefinition(compositionTargetId)).thenReturn(Optional.of(acDefinitionTarget));
+
+ var acMigrate = new AutomationComposition(automationComposition);
+ acMigrate.setCompositionTargetId(compositionTargetId);
+ automationComposition.getElements().clear();
+
+ var supervisionAcHandler = mock(SupervisionAcHandler.class);
+ var participantProvider = mock(ParticipantProvider.class);
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
+ new AcInstanceStateResolver(), supervisionAcHandler, participantProvider,
+ new AcRuntimeParameterGroup());
assertThatThrownBy(() -> instantiationProvider
.updateAutomationComposition(automationComposition.getCompositionId(), acMigrate))
@@ -605,5 +688,21 @@ class AutomationCompositionInstantiationProviderTest {
acInstanceStateUpdate.setLockOrder(LockOrder.LOCK);
provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
verify(supervisionAcHandler).lock(any(AutomationComposition.class), any(AutomationCompositionDefinition.class));
+
+ automationComposition.setDeployState(DeployState.UNDEPLOYED);
+ automationComposition.setLockState(LockState.NONE);
+ acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE);
+ acInstanceStateUpdate.setLockOrder(LockOrder.NONE);
+ acInstanceStateUpdate.setSubOrder(SubOrder.PREPARE);
+ provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
+ verify(supervisionAcHandler).prepare(any(AutomationComposition.class));
+
+ automationComposition.setDeployState(DeployState.DEPLOYED);
+ automationComposition.setLockState(LockState.LOCKED);
+ acInstanceStateUpdate.setDeployOrder(DeployOrder.NONE);
+ acInstanceStateUpdate.setLockOrder(LockOrder.NONE);
+ acInstanceStateUpdate.setSubOrder(SubOrder.REVIEW);
+ provider.compositionInstanceState(compositionId, instanceId, acInstanceStateUpdate);
+ verify(supervisionAcHandler).review(any(AutomationComposition.class));
}
}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java
index e895401a4..2d9c1280b 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java
@@ -36,6 +36,7 @@ import java.util.UUID;
import org.junit.jupiter.api.Test;
import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AcElementPropertiesPublisher;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.AcPreparePublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionDeployPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionMigrationPublisher;
import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher;
@@ -76,7 +77,7 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider, acDefinitionProvider,
mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class),
mock(AcElementPropertiesPublisher.class), null,
- mock(ParticipantSyncPublisher.class));
+ mock(ParticipantSyncPublisher.class), null);
var automationCompositionAckMessage =
getAutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK,
@@ -124,7 +125,7 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider, acDefinitionProvider,
mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class),
mock(AcElementPropertiesPublisher.class), null,
- mock(ParticipantSyncPublisher.class));
+ mock(ParticipantSyncPublisher.class), null);
handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage);
@@ -161,7 +162,7 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class),
mock(AutomationCompositionDeployPublisher.class), automationCompositionStateChangePublisher, null,
- null, mock(ParticipantSyncPublisher.class));
+ null, mock(ParticipantSyncPublisher.class), null);
handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage);
@@ -175,7 +176,8 @@ class SupervisionAcHandlerTest {
var automationCompositionProvider = mock(AutomationCompositionProvider.class);
var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class),
automationCompositionDeployPublisher, mock(AutomationCompositionStateChangePublisher.class),
- mock(AcElementPropertiesPublisher.class), null, mock(ParticipantSyncPublisher.class));
+ mock(AcElementPropertiesPublisher.class), null,
+ mock(ParticipantSyncPublisher.class), null);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
@@ -195,7 +197,7 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class),
mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher,
mock(AcElementPropertiesPublisher.class), null,
- mock(ParticipantSyncPublisher.class));
+ mock(ParticipantSyncPublisher.class), null);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var automationComposition =
@@ -213,7 +215,7 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class),
mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher,
mock(AcElementPropertiesPublisher.class), null,
- mock(ParticipantSyncPublisher.class));
+ mock(ParticipantSyncPublisher.class), null);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
@@ -234,7 +236,7 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class),
mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher,
mock(AcElementPropertiesPublisher.class), null,
- mock(ParticipantSyncPublisher.class));
+ mock(ParticipantSyncPublisher.class), null);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var automationComposition =
@@ -252,7 +254,7 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class),
mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher,
mock(AcElementPropertiesPublisher.class), null,
- mock(ParticipantSyncPublisher.class));
+ mock(ParticipantSyncPublisher.class), null);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var automationComposition =
@@ -272,7 +274,7 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class),
mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher,
mock(AcElementPropertiesPublisher.class), null,
- mock(ParticipantSyncPublisher.class));
+ mock(ParticipantSyncPublisher.class), null);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var automationComposition =
@@ -290,7 +292,7 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class),
mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher,
mock(AcElementPropertiesPublisher.class), null,
- mock(ParticipantSyncPublisher.class));
+ mock(ParticipantSyncPublisher.class), null);
var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
var automationComposition =
@@ -321,7 +323,7 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class),
mock(AutomationCompositionDeployPublisher.class), mock(AutomationCompositionStateChangePublisher.class),
mock(AcElementPropertiesPublisher.class), null,
- mock(ParticipantSyncPublisher.class));
+ mock(ParticipantSyncPublisher.class), null);
handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage);
@@ -335,7 +337,7 @@ class SupervisionAcHandlerTest {
var handler = new SupervisionAcHandler(mock(AutomationCompositionProvider.class),
mock(AcDefinitionProvider.class), mock(AutomationCompositionDeployPublisher.class),
mock(AutomationCompositionStateChangePublisher.class), acElementPropertiesPublisher, null,
- mock(ParticipantSyncPublisher.class));
+ mock(ParticipantSyncPublisher.class), null);
var automationComposition =
InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Lock");
handler.update(automationComposition);
@@ -348,10 +350,46 @@ class SupervisionAcHandlerTest {
var acCompositionMigrationPublisher = mock(AutomationCompositionMigrationPublisher.class);
var handler = new SupervisionAcHandler(automationCompositionProvider, mock(AcDefinitionProvider.class),
null, null, null,
- acCompositionMigrationPublisher, mock(ParticipantSyncPublisher.class));
+ acCompositionMigrationPublisher, mock(ParticipantSyncPublisher.class), null);
+ var automationComposition =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate");
+ handler.migrate(automationComposition);
+ verify(acCompositionMigrationPublisher, timeout(1000)).send(any(AutomationComposition.class));
+ }
+
+ @Test
+ void testMigratePrecheck() {
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var acCompositionMigrationPublisher = mock(AutomationCompositionMigrationPublisher.class);
+ var handler = new SupervisionAcHandler(automationCompositionProvider, null, null, null,
+ null, acCompositionMigrationPublisher, null, null);
+ var automationComposition =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate");
+ handler.migratePrecheck(automationComposition);
+ verify(acCompositionMigrationPublisher, timeout(1000)).send(any(AutomationComposition.class));
+ }
+
+ @Test
+ void testPrepare() {
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var acPreparePublisher = mock(AcPreparePublisher.class);
+ var handler = new SupervisionAcHandler(automationCompositionProvider, null, null, null,
+ null, null, null, acPreparePublisher);
+ var automationComposition =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate");
+ handler.prepare(automationComposition);
+ verify(acPreparePublisher, timeout(1000)).sendPrepare(any(AutomationComposition.class));
+ }
+
+ @Test
+ void testReview() {
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var acPreparePublisher = mock(AcPreparePublisher.class);
+ var handler = new SupervisionAcHandler(automationCompositionProvider, null, null, null,
+ null, null, null, acPreparePublisher);
var automationComposition =
InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Migrate");
- handler.migrate(automationComposition, UUID.randomUUID());
- verify(acCompositionMigrationPublisher, timeout(1000)).send(any(AutomationComposition.class), any());
+ handler.review(automationComposition);
+ verify(acPreparePublisher, timeout(1000)).sendRevew(any(AutomationComposition.class));
}
}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java
index 7cf0bf84f..77b47f4e3 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java
@@ -231,7 +231,29 @@ class SupervisionMessagesTest {
publisher.active(topicSink);
var automationComposition =
InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
- publisher.send(automationComposition, UUID.randomUUID());
+ publisher.send(automationComposition);
+ verify(topicSink).send(anyString());
+ }
+
+ @Test
+ void testAcPreparePublisher() {
+ var publisher = new AcPreparePublisher();
+ var topicSink = mock(TopicSink.class);
+ publisher.active(topicSink);
+ var automationComposition =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+ publisher.sendPrepare(automationComposition);
+ verify(topicSink).send(anyString());
+ }
+
+ @Test
+ void testAcReviewPublisher() {
+ var publisher = new AcPreparePublisher();
+ var topicSink = mock(TopicSink.class);
+ publisher.active(topicSink);
+ var automationComposition =
+ InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+ publisher.sendRevew(automationComposition);
verify(topicSink).send(anyString());
}