Fix stuck in Deleting State in ACM 30/140830/1
authorFrancescoFioraEst <francesco.fiora@est.tech>
Tue, 29 Apr 2025 14:45:23 +0000 (15:45 +0100)
committerFrancescoFioraEst <francesco.fiora@est.tech>
Tue, 29 Apr 2025 16:42:34 +0000 (17:42 +0100)
Issue-ID: POLICY-5348
Change-Id: Ib6fa558cf7c17061c03516401d8f51adeeb2039a
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
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/scanner/SimpleScanner.java
runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAcHandlerTest.java
runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/scanner/SimpleScannerTest.java

index d332339..a42dca8 100644 (file)
@@ -281,22 +281,14 @@ public class SupervisionAcHandler {
 
         if (automationCompositionAckMessage.getAutomationCompositionResultMap() == null
                 || automationCompositionAckMessage.getAutomationCompositionResultMap().isEmpty()) {
-            if (DeployState.DELETING.equals(automationComposition.getDeployState())) {
-                // scenario automationComposition has never deployed
-                automationCompositionAckMessage.setAutomationCompositionResultMap(new HashMap<>());
-                for (var element : automationComposition.getElements().values()) {
-                    if (element.getParticipantId().equals(automationCompositionAckMessage.getParticipantId())) {
-                        var acElement = new AcElementDeployAck(DeployState.DELETED, LockState.NONE,
-                                null, null, Map.of(), true, "");
-                        automationCompositionAckMessage.getAutomationCompositionResultMap()
-                                .put(element.getId(), acElement);
-                    }
+            // scenario automationComposition has never been deployed
+            automationCompositionAckMessage.setAutomationCompositionResultMap(new HashMap<>());
+            for (var element : automationComposition.getElements().values()) {
+                if (element.getParticipantId().equals(automationCompositionAckMessage.getParticipantId())) {
+                    var acElement =
+                            new AcElementDeployAck(DeployState.DELETED, LockState.NONE, null, null, Map.of(), true, "");
+                    automationCompositionAckMessage.getAutomationCompositionResultMap().put(element.getId(), acElement);
                 }
-            } else {
-                LOGGER.warn("Empty AutomationCompositionResultMap  {} {}",
-                        automationCompositionAckMessage.getAutomationCompositionId(),
-                        automationCompositionAckMessage.getMessage());
-                return;
             }
         }
         messageProvider.save(automationCompositionAckMessage);
index 51dadfa..8706891 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2025 Nordix Foundation.
+ * Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup
 import org.onap.policy.clamp.acm.runtime.main.utils.EncryptionUtils;
 import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantSyncPublisher;
 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
 import org.onap.policy.clamp.models.acm.concepts.SubState;
 import org.onap.policy.clamp.models.acm.document.concepts.DocMessage;
@@ -73,25 +74,30 @@ public class SimpleScanner extends AbstractScanner {
 
     private UpdateSync handleAcStateChange(AutomationComposition automationComposition, DocMessage message) {
         var result = new UpdateSync();
+        var element = automationComposition.getElements().get(message.getInstanceElementId());
+        if (element == null || !validateStateMessage(automationComposition, message)) {
+            return result;
+        }
+        result.setUpdated(true);
         if (StateChangeResult.FAILED.equals(message.getStateChangeResult())) {
             automationComposition.setStateChangeResult(StateChangeResult.FAILED);
-            result.setUpdated(true);
             result.setToBeSync(true);
         }
-        var element = automationComposition.getElements().get(message.getInstanceElementId());
-        if (element != null) {
-            element.setDeployState(message.getDeployState());
-            element.setLockState(message.getLockState());
-            if (message.getStage() == null) {
-                element.setSubState(SubState.NONE);
-            }
-            element.setStage(message.getStage());
-            element.setMessage(message.getMessage());
-            result.setUpdated(true);
+        element.setDeployState(message.getDeployState());
+        element.setLockState(message.getLockState());
+        if (message.getStage() == null) {
+            element.setSubState(SubState.NONE);
         }
+        element.setStage(message.getStage());
+        element.setMessage(message.getMessage());
         return result;
     }
 
+    private boolean validateStateMessage(AutomationComposition automationComposition, DocMessage message) {
+        return !DeployState.DELETED.equals(message.getDeployState())
+                || (DeployState.DELETING.equals(automationComposition.getDeployState()));
+    }
+
     private UpdateSync handleOutProperties(AutomationComposition automationComposition, DocMessage message) {
         var element = automationComposition.getElements().get(message.getInstanceElementId());
         var result = new UpdateSync();
index 2218932..dd7a491 100644 (file)
@@ -96,7 +96,7 @@ class SupervisionAcHandlerTest {
                 .thenReturn(Optional.of(automationComposition));
         automationCompositionAckMessage.setAutomationCompositionResultMap(null);
         handler.handleAutomationCompositionStateChangeAckMessage(automationCompositionAckMessage);
-        verify(messageProvider, times(0)).save(any(AutomationCompositionDeployAck.class));
+        verify(messageProvider).save(any(AutomationCompositionDeployAck.class));
     }
 
     @Test
index c82969d..b155eda 100644 (file)
@@ -1,6 +1,6 @@
 /*-
  * ============LICENSE_START=======================================================
- * Copyright (C) 2025 Nordix Foundation.
+ * Copyright (C) 2025 OpenInfra Foundation Europe. All rights reserved.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -118,6 +118,14 @@ class SimpleScannerTest {
         result = simpleScanner.scanMessage(automationComposition, docMessage);
         assertFalse(result.isUpdated());
         assertFalse(result.isToBeSync());
+
+        // wrong Delete State
+        docMessage.setMessageType(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
+        docMessage.setInstanceElementId(elementId);
+        docMessage.setDeployState(DeployState.DELETED);
+        result = simpleScanner.scanMessage(automationComposition, docMessage);
+        assertFalse(result.isUpdated());
+        assertFalse(result.isToBeSync());
     }
 
     @Test
@@ -166,6 +174,34 @@ class SimpleScannerTest {
                 automationComposition.getElements().get(elementId).getLockState());
     }
 
+
+    @Test
+    void testScanMessageStateChangeDelete() {
+        var automationComposition = createDeploying();
+        automationComposition.setDeployState(DeployState.DELETING);
+        automationComposition.setLockState(LockState.NONE);
+        var elementId = automationComposition.getElements().values().iterator().next().getId();
+        var docMessage = new DocMessage();
+        docMessage.setMessageType(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY_ACK);
+        docMessage.setStateChangeResult(StateChangeResult.NO_ERROR);
+        docMessage.setInstanceId(INSTANCE_ID);
+        docMessage.setInstanceElementId(elementId);
+        docMessage.setDeployState(DeployState.DELETED);
+        docMessage.setLockState(LockState.NONE);
+        var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+        var acProvider = mock(AutomationCompositionProvider.class);
+        var encryptionUtils = new EncryptionUtils(acRuntimeParameterGroup);
+        var simpleScanner = new SimpleScanner(acProvider, mock(ParticipantSyncPublisher.class),
+                acRuntimeParameterGroup, encryptionUtils);
+        var result = simpleScanner.scanMessage(automationComposition, docMessage);
+        assertTrue(result.isUpdated());
+        assertFalse(result.isToBeSync());
+        assertEquals(docMessage.getDeployState(),
+                automationComposition.getElements().get(elementId).getDeployState());
+        assertEquals(docMessage.getLockState(),
+                automationComposition.getElements().get(elementId).getLockState());
+    }
+
     private AutomationComposition createDeploying() {
         var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
         automationComposition.setInstanceId(INSTANCE_ID);