Fix fail handling in ACM runtime 59/141259/3
authorFrancescoFioraEst <francesco.fiora@est.tech>
Thu, 12 Jun 2025 09:06:39 +0000 (10:06 +0100)
committerFrancescoFioraEst <francesco.fiora@est.tech>
Fri, 13 Jun 2025 10:53:03 +0000 (11:53 +0100)
Issue-ID: POLICY-5391
Change-Id: I3bb8fbffb7917b98ec0b3f3012872ad5801e2eba
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/SimulatorService.java
runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandler.java
runtime-acm/src/main/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspect.java
runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java
runtime-acm/src/test/resources/rest/acm/AutomationCompositionSimple.json [new file with mode: 0644]

index dfced7c..282d81d 100644 (file)
@@ -157,6 +157,12 @@ public class SimulatorService {
         return false;
     }
 
+    private void sendAcInternalState(UUID instanceId, UUID elementId, Map<String, Object> outProperties,
+            DeployState deployState) {
+        outProperties.put(INTERNAL_STATE, deployState.name());
+        intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, outProperties);
+    }
+
     /**
      * Handle deploying an automation composition element.
      *
@@ -165,20 +171,20 @@ public class SimulatorService {
      * @param outProperties the outProperties
      */
     public void deploy(UUID instanceId, UUID elementId, Map<String, Object> outProperties) {
+        sendAcInternalState(instanceId, elementId, outProperties, DeployState.DEPLOYING);
+
         if (isInterrupted(getConfig().getDeployTimerMs(),
             "Current Thread deploy is Interrupted during execution {}", elementId)) {
             return;
         }
 
         if (getConfig().isDeploySuccess()) {
-            outProperties.put(INTERNAL_STATE, DeployState.DEPLOYED.name());
-            intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, outProperties);
+            sendAcInternalState(instanceId, elementId, outProperties, DeployState.DEPLOYED);
 
             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
                 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
         } else {
-            outProperties.put(INTERNAL_STATE, DeployState.UNDEPLOYED.name());
-            intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, outProperties);
+            sendAcInternalState(instanceId, elementId, outProperties, DeployState.UNDEPLOYED);
 
             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
                 DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Deploy failed!");
@@ -193,20 +199,20 @@ public class SimulatorService {
      * @param outProperties the outProperties
      */
     public void undeploy(UUID instanceId, UUID elementId, Map<String, Object> outProperties) {
+        sendAcInternalState(instanceId, elementId, outProperties, DeployState.UNDEPLOYING);
+
         if (isInterrupted(getConfig().getUndeployTimerMs(),
             "Current Thread undeploy is Interrupted during execution {}", elementId)) {
             return;
         }
 
         if (getConfig().isUndeploySuccess()) {
-            outProperties.put(INTERNAL_STATE, DeployState.UNDEPLOYED.name());
-            intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, outProperties);
+            sendAcInternalState(instanceId, elementId, outProperties, DeployState.UNDEPLOYED);
 
             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
                 DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed");
         } else {
-            outProperties.put(INTERNAL_STATE, DeployState.DEPLOYED.name());
-            intermediaryApi.sendAcElementInfo(instanceId, elementId, null, null, outProperties);
+            sendAcInternalState(instanceId, elementId, outProperties, DeployState.DEPLOYED);
 
             intermediaryApi.updateAutomationCompositionElementState(instanceId, elementId,
                 DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Undeploy failed!");
index 21b6c1f..991a653 100644 (file)
@@ -45,6 +45,7 @@ import org.onap.policy.clamp.models.acm.messages.kafka.participant.AutomationCom
 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.TimestampHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -79,8 +80,10 @@ public class SupervisionAcHandler {
      * @param acDefinition the AutomationCompositionDefinition
      */
     public void deploy(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) {
-        if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) {
-            automationComposition.setDeployState(DeployState.DEPLOYING);
+        if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())
+                && DeployState.DEPLOYING.equals(automationComposition.getDeployState())
+                && automationComposition.getElements().size() > 1) {
+            automationComposition.setLastMsg(TimestampHelper.now());
             for (var element : automationComposition.getElements().values()) {
                 if (!DeployState.DEPLOYED.equals(element.getDeployState())) {
                     element.setDeployState(DeployState.DEPLOYING);
@@ -109,11 +112,14 @@ public class SupervisionAcHandler {
      * @param acDefinition the AutomationCompositionDefinition
      */
     public void undeploy(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) {
-        if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) {
-            automationComposition.setDeployState(DeployState.UNDEPLOYING);
+        if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())
+                && DeployState.UNDEPLOYING.equals(automationComposition.getDeployState())
+                && automationComposition.getElements().size() > 1) {
+            automationComposition.setLastMsg(TimestampHelper.now());
             for (var element : automationComposition.getElements().values()) {
                 if (!DeployState.UNDEPLOYED.equals(element.getDeployState())) {
                     element.setDeployState(DeployState.UNDEPLOYING);
+                    element.setMessage(null);
                 }
             }
         } else {
@@ -135,8 +141,10 @@ public class SupervisionAcHandler {
      * @param acDefinition the AutomationCompositionDefinition
      */
     public void unlock(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) {
-        if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) {
-            automationComposition.setLockState(LockState.UNLOCKING);
+        if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())
+                && LockState.UNLOCKING.equals(automationComposition.getLockState())
+                && automationComposition.getElements().size() > 1) {
+            automationComposition.setLastMsg(TimestampHelper.now());
             for (var element : automationComposition.getElements().values()) {
                 if (!LockState.UNLOCKED.equals(element.getLockState())) {
                     element.setLockState(LockState.UNLOCKING);
@@ -191,8 +199,10 @@ public class SupervisionAcHandler {
      * @param acDefinition the AutomationCompositionDefinition
      */
     public void lock(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) {
-        if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())) {
-            automationComposition.setLockState(LockState.LOCKING);
+        if (StateChangeResult.FAILED.equals(automationComposition.getStateChangeResult())
+                && LockState.LOCKING.equals(automationComposition.getLockState())
+                && automationComposition.getElements().size() > 1) {
+            automationComposition.setLastMsg(TimestampHelper.now());
             for (var element : automationComposition.getElements().values()) {
                 if (!LockState.LOCKED.equals(element.getLockState())) {
                     element.setLockState(LockState.LOCKING);
index e74d5b8..1dc5f12 100644 (file)
@@ -65,7 +65,7 @@ public class SupervisionAspect implements Closeable {
     @After("@annotation(MessageIntercept)")
     public void doCheck() {
         if (executor.getQueue().size() < 2) {
-            LOGGER.debug("Add scanning Message");
+            LOGGER.info("Add scanning Message");
             executor.execute(supervisionScanner::run);
         }
     }
index dd7a491..689a4ba 100644 (file)
@@ -55,6 +55,8 @@ import org.onap.policy.clamp.models.acm.persistence.provider.MessageProvider;
 
 class SupervisionAcHandlerTest {
     private static final String AC_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/acm/AutomationComposition.json";
+    private static final String AC_INSTANTIATION_SIMPLE_JSON =
+            "src/test/resources/rest/acm/AutomationCompositionSimple.json";
     private static final UUID IDENTIFIER = UUID.randomUUID();
 
     @Test
@@ -224,27 +226,77 @@ class SupervisionAcHandlerTest {
         verify(messageProvider).save(any(AutomationCompositionDeployAck.class));
     }
 
+    @Test
+    void testDeploy() {
+        var automationComposition =
+                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Deploy");
+        automationComposition.setDeployState(DeployState.UNDEPLOYED);
+        deploy(automationComposition);
+    }
+
     @Test
     void testDeployFailed() {
-        var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
-        var automationCompositionProvider = mock(AutomationCompositionProvider.class);
-        var handler = new SupervisionAcHandler(automationCompositionProvider,
-                automationCompositionDeployPublisher, mock(AutomationCompositionStateChangePublisher.class),
+        var automationComposition =
+                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Deploy");
+        automationComposition.setDeployState(DeployState.UNDEPLOYING);
+        automationComposition.getElements().values()
+                .forEach(element -> element.setDeployState(DeployState.UNDEPLOYING));
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        deploy(automationComposition);
+
+        automationComposition.setDeployState(DeployState.DEPLOYING);
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.getElements().values()
+                .forEach(element -> element.setDeployState(DeployState.DEPLOYING));
+        automationComposition.getElements().values().iterator().next().setDeployState(DeployState.DEPLOYED);
+        deploy(automationComposition);
+    }
+
+    @Test
+    void testDeployFailedSimple() {
+        var automationComposition =
+                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_SIMPLE_JSON, "Deploy");
+        automationComposition.setDeployState(DeployState.UNDEPLOYED);
+        automationComposition.getElements().values().iterator().next().setDeployState(DeployState.UNDEPLOYED);
+        deploy(automationComposition);
+
+        automationComposition.setDeployState(DeployState.UNDEPLOYING);
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.getElements().values().iterator().next().setDeployState(DeployState.DEPLOYED);
+        deploy(automationComposition);
+
+        automationComposition.setDeployState(DeployState.DEPLOYING);
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.getElements().values().iterator().next().setDeployState(DeployState.UNDEPLOYED);
+        deploy(automationComposition);
+    }
+
+    private void deploy(AutomationComposition automationComposition) {
+        var acDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
+        var acProvider = mock(AutomationCompositionProvider.class);
+        var handler = new SupervisionAcHandler(acProvider, acDeployPublisher,
+                mock(AutomationCompositionStateChangePublisher.class),
                 mock(AcElementPropertiesPublisher.class), mock(AutomationCompositionMigrationPublisher.class),
                 mock(AcPreparePublisher.class), mock(MessageProvider.class), mock(EncryptionUtils.class));
-
         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
-        var automationComposition =
-                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Deploy");
-        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
         handler.deploy(automationComposition, acDefinition);
-        verify(automationCompositionProvider).updateAutomationComposition(automationComposition);
-        verify(automationCompositionDeployPublisher, timeout(1000)).send(automationComposition, 0, true);
+        verify(acProvider).updateAutomationComposition(automationComposition);
+        verify(acDeployPublisher, timeout(1000)).send(automationComposition, 0, true);
     }
 
     @Test
     void testUndeploy() {
+        var automationComposition =
+                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Undeploy");
+        automationComposition.setDeployState(DeployState.DEPLOYED);
+        automationComposition.setStateChangeResult(StateChangeResult.NO_ERROR);
+        automationComposition.getElements().values()
+                .forEach(element -> element.setDeployState(DeployState.DEPLOYED));
+        undeploy(automationComposition);
+    }
+
+    private void undeploy(AutomationComposition automationComposition) {
         var automationCompositionProvider = mock(AutomationCompositionProvider.class);
         var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
         var handler = new SupervisionAcHandler(automationCompositionProvider,
@@ -253,8 +305,6 @@ class SupervisionAcHandlerTest {
                 mock(AcPreparePublisher.class), mock(MessageProvider.class), mock(EncryptionUtils.class));
         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
-        var automationComposition =
-                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Undeploy");
         handler.undeploy(automationComposition, acDefinition);
 
         verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class));
@@ -263,65 +313,103 @@ class SupervisionAcHandlerTest {
 
     @Test
     void testUndeployFailed() {
-        var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
-        var automationCompositionProvider = mock(AutomationCompositionProvider.class);
-        var handler = new SupervisionAcHandler(automationCompositionProvider,
-                mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher,
-                mock(AcElementPropertiesPublisher.class), mock(AutomationCompositionMigrationPublisher.class),
-                mock(AcPreparePublisher.class), mock(MessageProvider.class), mock(EncryptionUtils.class));
-
-        var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
-        var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
         var automationComposition =
                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "UnDeploy");
+        automationComposition.setDeployState(DeployState.DEPLOYING);
         automationComposition.setStateChangeResult(StateChangeResult.FAILED);
         automationComposition.getElements().values()
-                .forEach(element -> element.setDeployState(DeployState.UNDEPLOYING));
-        handler.undeploy(automationComposition, acDefinition);
-        verify(automationCompositionProvider).updateAutomationComposition(automationComposition);
-        verify(acStateChangePublisher, timeout(1000)).send(any(AutomationComposition.class), anyInt(), anyBoolean());
+                .forEach(element -> element.setDeployState(DeployState.UNDEPLOYED));
+        undeploy(automationComposition);
+
+        automationComposition.setDeployState(DeployState.UNDEPLOYING);
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.getElements().values()
+                .forEach(element -> element.setDeployState(DeployState.DEPLOYING));
+        automationComposition.getElements().values().iterator().next().setDeployState(DeployState.UNDEPLOYED);
+        undeploy(automationComposition);
+    }
+
+    @Test
+    void testUndeployFailedSimple() {
+        var automationComposition =
+                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_SIMPLE_JSON, "UnDeploy");
+        automationComposition.setDeployState(DeployState.DEPLOYING);
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.getElements().values().iterator().next().setDeployState(DeployState.UNDEPLOYED);
+        undeploy(automationComposition);
+
+        automationComposition.setDeployState(DeployState.UNDEPLOYING);
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.getElements().values().iterator().next().setDeployState(DeployState.DEPLOYED);
+        undeploy(automationComposition);
     }
 
     @Test
     void testUnlock() {
-        var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+        var automationComposition =
+                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "UnLock");
+        automationComposition.setLockState(LockState.LOCKED);
+        automationComposition.getElements().values()
+                .forEach(element -> element.setLockState(LockState.LOCKED));
+        unlock(automationComposition);
+    }
+
+    private void unlock(AutomationComposition automationComposition) {
+        var acProvider = mock(AutomationCompositionProvider.class);
         var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
-        var handler = new SupervisionAcHandler(automationCompositionProvider,
+        var handler = new SupervisionAcHandler(acProvider,
                 mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher,
                 mock(AcElementPropertiesPublisher.class), mock(AutomationCompositionMigrationPublisher.class),
                 mock(AcPreparePublisher.class), mock(MessageProvider.class), mock(EncryptionUtils.class));
         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
-        var automationComposition =
-                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "UnLock");
         handler.unlock(automationComposition, acDefinition);
 
-        verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class));
+        verify(acProvider).updateAutomationComposition(any(AutomationComposition.class));
         verify(acStateChangePublisher, timeout(1000)).send(any(AutomationComposition.class), anyInt(), anyBoolean());
     }
 
     @Test
     void testUnlockFailed() {
-        var automationCompositionProvider = mock(AutomationCompositionProvider.class);
-        var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
-        var handler = new SupervisionAcHandler(automationCompositionProvider,
-                mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher,
-                mock(AcElementPropertiesPublisher.class), mock(AutomationCompositionMigrationPublisher.class),
-                mock(AcPreparePublisher.class), mock(MessageProvider.class), mock(EncryptionUtils.class));
-        var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
-        var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
         var automationComposition =
                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "UnLock");
         automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.setLockState(LockState.LOCKING);
+        automationComposition.getElements().values().forEach(element -> element.setLockState(LockState.LOCKING));
+        unlock(automationComposition);
+
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.setLockState(LockState.UNLOCKING);
         automationComposition.getElements().values().forEach(element -> element.setLockState(LockState.UNLOCKING));
-        handler.unlock(automationComposition, acDefinition);
+        automationComposition.getElements().values().iterator().next().setLockState(LockState.UNLOCKED);
+        unlock(automationComposition);
+    }
 
-        verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class));
-        verify(acStateChangePublisher, timeout(1000)).send(any(AutomationComposition.class), anyInt(), anyBoolean());
+    @Test
+    void testUnlockSimple() {
+        var automationComposition =
+                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_SIMPLE_JSON, "UnLock");
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.setLockState(LockState.LOCKING);
+        automationComposition.getElements().values().iterator().next().setLockState(LockState.UNLOCKED);
+        unlock(automationComposition);
+
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.setLockState(LockState.UNLOCKING);
+        automationComposition.getElements().values().iterator().next().setLockState(LockState.LOCKED);
+        unlock(automationComposition);
     }
 
     @Test
     void testLock() {
+        var automationComposition =
+                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Lock");
+        automationComposition.setLockState(LockState.UNLOCKED);
+        automationComposition.getElements().values().forEach(element -> element.setLockState(LockState.UNLOCKED));
+        lock(automationComposition);
+    }
+
+    private void lock(AutomationComposition automationComposition) {
         var automationCompositionProvider = mock(AutomationCompositionProvider.class);
         var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
         var handler = new SupervisionAcHandler(automationCompositionProvider,
@@ -330,8 +418,6 @@ class SupervisionAcHandlerTest {
                 mock(AcPreparePublisher.class), mock(MessageProvider.class), mock(EncryptionUtils.class));
         var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
         var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
-        var automationComposition =
-                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Lock");
         handler.lock(automationComposition, acDefinition);
 
         verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class));
@@ -340,22 +426,33 @@ class SupervisionAcHandlerTest {
 
     @Test
     void testLockFailed() {
-        var automationCompositionProvider = mock(AutomationCompositionProvider.class);
-        var acStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
-        var handler = new SupervisionAcHandler(automationCompositionProvider,
-                mock(AutomationCompositionDeployPublisher.class), acStateChangePublisher,
-                mock(AcElementPropertiesPublisher.class), mock(AutomationCompositionMigrationPublisher.class),
-                mock(AcPreparePublisher.class), mock(MessageProvider.class), mock(EncryptionUtils.class));
-        var serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
-        var acDefinition = CommonTestData.createAcDefinition(serviceTemplate, AcTypeState.PRIMED);
         var automationComposition =
                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Lock");
+        automationComposition.setLockState(LockState.UNLOCKING);
         automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.getElements().values().forEach(element -> element.setLockState(LockState.UNLOCKING));
+        lock(automationComposition);
+
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.setLockState(LockState.LOCKING);
         automationComposition.getElements().values().forEach(element -> element.setLockState(LockState.LOCKING));
-        handler.lock(automationComposition, acDefinition);
+        automationComposition.getElements().values().iterator().next().setLockState(LockState.LOCKED);
+        lock(automationComposition);
+    }
 
-        verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class));
-        verify(acStateChangePublisher, timeout(1000)).send(any(AutomationComposition.class), anyInt(), anyBoolean());
+    @Test
+    void testLockSimple() {
+        var automationComposition =
+                InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_SIMPLE_JSON, "Lock");
+        automationComposition.setLockState(LockState.UNLOCKING);
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.getElements().values().iterator().next().setLockState(LockState.LOCKED);
+        lock(automationComposition);
+
+        automationComposition.setStateChangeResult(StateChangeResult.FAILED);
+        automationComposition.setLockState(LockState.LOCKING);
+        automationComposition.getElements().values().iterator().next().setLockState(LockState.UNLOCKED);
+        lock(automationComposition);
     }
 
     @Test
diff --git a/runtime-acm/src/test/resources/rest/acm/AutomationCompositionSimple.json b/runtime-acm/src/test/resources/rest/acm/AutomationCompositionSimple.json
new file mode 100644 (file)
index 0000000..f1937b4
--- /dev/null
@@ -0,0 +1,25 @@
+{
+    "name": "PMSHInstance0",
+    "version": "1.0.1",
+    "compositionId": "709c62b3-8918-41b9-a747-d21eb79c6c40",
+    "deployState": "UNDEPLOYED",
+    "lockState": "NONE",
+    "description": "PMSH automation composition instance 0",
+    "elements": {
+        "709c62b3-8918-41b9-a747-d21eb79c6c20": {
+            "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+            "definition": {
+                "name": "org.onap.domain.database.PMSH_K8SMicroserviceAutomationCompositionElement",
+                "version": "1.2.3"
+            },
+            "deployState": "UNDEPLOYED",
+            "lockState": "NONE",
+            "description": "Automation composition element for the K8S microservice for PMSH",
+            "deployTimeoutMs": "200000",
+            "undeployTimeoutMs": "150000",
+            "updateTimeoutMs": "200000",
+            "migrateTimeoutMs": "200000",
+            "deleteTimeoutMs": "100000"
+        }
+    }
+}