Add extend instance deletion support in ACM

Extend the functionality of deletion step to also inform the participant of instance deletion. This allow the participant to take any necessary steps that might result from instance deletion.

Issue-ID: POLICY-4686
Change-Id: Ibeb44d472da20ad98dafa9ddd7ded28398f4ed10
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/DeployState.java b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/DeployState.java
index 659b312..94aa070 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/DeployState.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/concepts/DeployState.java
@@ -24,5 +24,7 @@
     DEPLOYED,
     DEPLOYING,
     UNDEPLOYED,
-    UNDEPLOYING
+    UNDEPLOYING,
+    DELETING,
+    DELETED
 }
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/DeployOrder.java b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/DeployOrder.java
index 6c1572d..f4b57f1 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/DeployOrder.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/messages/rest/instantiation/DeployOrder.java
@@ -23,5 +23,6 @@
 public enum DeployOrder {
     NONE,
     UNDEPLOY,
-    DEPLOY
+    DEPLOY,
+    DELETE
 }
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 dba64f5..8676b33 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
@@ -44,6 +44,7 @@
     // list of results
     public static final String DEPLOY = DeployOrder.DEPLOY.name();
     public static final String UNDEPLOY = DeployOrder.UNDEPLOY.name();
+    public static final String DELETE = DeployOrder.DELETE.name();
     public static final String LOCK = LockOrder.LOCK.name();
     public static final String UNLOCK = LockOrder.UNLOCK.name();
     public static final String NONE = "NONE";
@@ -56,6 +57,7 @@
 
         this.graph.put(new String[] {DEPLOY, LOCK_NONE, UNDEPLOYED, STATE_LOCKED_NONE}, DEPLOY);
         this.graph.put(new String[] {UNDEPLOY, LOCK_NONE, DEPLOYED, LOCKED}, UNDEPLOY);
+        this.graph.put(new String[] {DELETE, LOCK_NONE, UNDEPLOYED, LOCK_NONE}, DELETE);
         this.graph.put(new String[] {DEPLOY_NONE, UNLOCK, DEPLOYED, LOCKED}, UNLOCK);
         this.graph.put(new String[] {DEPLOY_NONE, LOCK, DEPLOYED, UNLOCKED}, LOCK);
     }
diff --git a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java
index 94693fd..38add31 100644
--- a/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java
+++ b/models/src/main/java/org/onap/policy/clamp/models/acm/persistence/provider/AutomationCompositionProvider.java
@@ -203,7 +203,7 @@
                 var jpa = acElementRepository.getReferenceById(element.getAutomationCompositionElementId().toString());
                 jpa.setUseState(element.getUseState());
                 jpa.setOperationalState(element.getOperationalState());
-                jpa.setProperties(element.getStatusProperties());
+                jpa.setStatusProperties(element.getStatusProperties());
                 jpaList.add(jpa);
             }
         }
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 35482b9..7de4720 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
@@ -284,7 +284,8 @@
      */
     public static boolean isInTransitionalState(DeployState deployState, LockState lockState) {
         return DeployState.DEPLOYING.equals(deployState) || DeployState.UNDEPLOYING.equals(deployState)
-                || LockState.LOCKING.equals(lockState) || LockState.UNLOCKING.equals(lockState);
+                || LockState.LOCKING.equals(lockState) || LockState.UNLOCKING.equals(lockState)
+                || DeployState.DELETING.equals(deployState);
     }
 
     /**
@@ -294,12 +295,24 @@
      * @return the DeployOrder
      */
     public static DeployOrder stateDeployToOrder(DeployState deployState) {
-        if (DeployState.DEPLOYING.equals(deployState)) {
-            return DeployOrder.DEPLOY;
-        } else if (DeployState.UNDEPLOYING.equals(deployState)) {
-            return DeployOrder.UNDEPLOY;
+        DeployOrder result = null;
+        switch (deployState) {
+            case DEPLOYING:
+                result = DeployOrder.DEPLOY;
+                break;
+
+            case UNDEPLOYING:
+                result = DeployOrder.UNDEPLOY;
+                break;
+
+            case DELETING:
+                result = DeployOrder.DELETE;
+                break;
+
+            default:
+                result = DeployOrder.NONE;
         }
-        return DeployOrder.NONE;
+        return result;
     }
 
     /**
@@ -324,12 +337,24 @@
      * @return the DeployState
      */
     public static DeployState deployCompleted(DeployState deployState) {
-        if (DeployState.DEPLOYING.equals(deployState)) {
-            return DeployState.DEPLOYED;
-        } else if (DeployState.UNDEPLOYING.equals(deployState)) {
-            return DeployState.UNDEPLOYED;
+        DeployState result = null;
+        switch (deployState) {
+            case DEPLOYING:
+                result = DeployState.DEPLOYED;
+                break;
+
+            case UNDEPLOYING:
+                result = DeployState.UNDEPLOYED;
+                break;
+
+            case DELETING:
+                result = DeployState.DELETED;
+                break;
+
+            default:
+                return deployState;
         }
-        return deployState;
+        return result;
     }
 
     /**
diff --git a/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java b/models/src/test/java/org/onap/policy/clamp/models/acm/utils/AcmUtilsTest.java
index b332d7d..046d1b8 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
@@ -145,6 +145,7 @@
         // from transitional state to order state
         assertEquals(DeployOrder.DEPLOY, AcmUtils.stateDeployToOrder(DeployState.DEPLOYING));
         assertEquals(DeployOrder.UNDEPLOY, AcmUtils.stateDeployToOrder(DeployState.UNDEPLOYING));
+        assertEquals(DeployOrder.DELETE, AcmUtils.stateDeployToOrder(DeployState.DELETING));
         assertEquals(DeployOrder.NONE, AcmUtils.stateDeployToOrder(DeployState.DEPLOYED));
     }
 
@@ -162,6 +163,7 @@
         assertEquals(DeployState.DEPLOYED, AcmUtils.deployCompleted(DeployState.DEPLOYING));
         assertEquals(DeployState.UNDEPLOYED, AcmUtils.deployCompleted(DeployState.UNDEPLOYING));
         assertEquals(DeployState.DEPLOYED, AcmUtils.deployCompleted(DeployState.DEPLOYED));
+        assertEquals(DeployState.DELETED, AcmUtils.deployCompleted(DeployState.DELETING));
     }
 
     @Test
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java
index 2339069..d6ef80f 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/AutomationCompositionElementListener.java
@@ -57,4 +57,9 @@
             throws PfModelException {
         // default Unlock Operation
     }
+
+    public default void delete(UUID automationCompositionId, UUID automationCompositionElementId)
+            throws PfModelException {
+        // default Delete Operation
+    }
 }
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java
index 509b6ed..f355727 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/ParticipantIntermediaryApi.java
@@ -23,6 +23,7 @@
 
 import java.util.Map;
 import java.util.UUID;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
 
@@ -52,6 +53,13 @@
             LockState lockState, String message);
 
     /**
+     * Get AutomationCompositions.
+     *
+     * @return get all AutomationCompositions
+     */
+    Map<UUID, AutomationComposition> getAutomationCompositions();
+
+    /**
      * Send Automation Composition Element update Info to AC-runtime.
      *
      * @param automationCompositionId the ID of the automation composition to update the states
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java
index 20f222a..69fd9f3 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java
@@ -26,8 +26,10 @@
 import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener;
 import org.onap.policy.clamp.acm.participant.intermediary.api.ParticipantIntermediaryApi;
 import org.onap.policy.clamp.acm.participant.intermediary.handler.AutomationCompositionHandler;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
+import org.onap.policy.models.base.PfUtils;
 import org.springframework.stereotype.Component;
 
 /**
@@ -67,4 +69,9 @@
         automationCompositionHandler.sendAcElementInfo(automationCompositionId, elementId, useState, operationalState,
                 statusProperties);
     }
+
+    @Override
+    public Map<UUID, AutomationComposition> getAutomationCompositions() {
+        return PfUtils.mapMap(automationCompositionHandler.getAutomationCompositionMap(), AutomationComposition::new);
+    }
 }
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java
index e355820..26ec146 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandler.java
@@ -129,13 +129,14 @@
 
         if (deployState != null) {
             element.setDeployState(deployState);
+            element.setLockState(
+                    DeployState.DEPLOYED.equals(element.getDeployState()) ? LockState.LOCKED : LockState.NONE);
             var checkOpt = automationComposition.getElements().values().stream()
                     .filter(acElement -> !deployState.equals(acElement.getDeployState())).findAny();
             if (checkOpt.isEmpty()) {
                 automationComposition.setDeployState(deployState);
+                automationComposition.setLockState(element.getLockState());
             }
-            element.setLockState(
-                    DeployState.DEPLOYED.equals(element.getDeployState()) ? LockState.LOCKED : LockState.NONE);
         }
         if (lockState != null) {
             element.setLockState(lockState);
@@ -191,14 +192,8 @@
 
         if (!checkConsistantOrderState(automationComposition, stateChangeMsg.getDeployOrderedState(),
                 stateChangeMsg.getLockOrderedState())) {
-            var automationCompositionAck =
-                    new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
-            automationCompositionAck.setParticipantId(participantId);
-            automationCompositionAck.setMessage("Automation composition is already in state "
-                    + stateChangeMsg.getDeployOrderedState() + " and " + stateChangeMsg.getLockOrderedState());
-            automationCompositionAck.setResult(false);
-            automationCompositionAck.setAutomationCompositionId(automationComposition.getInstanceId());
-            publisher.sendAutomationCompositionAck(automationCompositionAck);
+            LOGGER.warn("Not Consistant OrderState Automation composition {}",
+                    stateChangeMsg.getAutomationCompositionId());
             return;
         }
 
@@ -228,10 +223,17 @@
     private void handleDeployOrderState(final AutomationComposition automationComposition, DeployOrder orderedState,
             Integer startPhaseMsg, List<AutomationCompositionElementDefinition> acElementDefinitions) {
 
-        if (DeployOrder.UNDEPLOY.equals(orderedState)) {
-            handleUndeployState(automationComposition, startPhaseMsg, acElementDefinitions);
-        } else {
-            LOGGER.debug("StateChange message has no state, state is null {}", automationComposition.getKey());
+        switch (orderedState) {
+            case UNDEPLOY:
+                handleUndeployState(automationComposition, startPhaseMsg, acElementDefinitions);
+                break;
+            case DELETE:
+                handleDeleteState(automationComposition, startPhaseMsg, acElementDefinitions);
+                break;
+
+            default:
+                LOGGER.debug("StateChange message has no state, state is null {}", automationComposition.getKey());
+                break;
         }
     }
 
@@ -287,23 +289,7 @@
     }
 
     private void initializeDeploy(UUID messageId, UUID instanceId, ParticipantDeploy participantDeploy) {
-        var automationComposition = automationCompositionMap.get(instanceId);
-
-        if (automationComposition != null) {
-            var automationCompositionUpdateAck =
-                    new AutomationCompositionDeployAck(ParticipantMessageType.AUTOMATION_COMPOSITION_DEPLOY_ACK);
-            automationCompositionUpdateAck.setParticipantId(participantId);
-
-            automationCompositionUpdateAck.setMessage(
-                    "Automation composition " + instanceId + " already defined on participant " + participantId);
-            automationCompositionUpdateAck.setResult(false);
-            automationCompositionUpdateAck.setResponseTo(messageId);
-            automationCompositionUpdateAck.setAutomationCompositionId(instanceId);
-            publisher.sendAutomationCompositionAck(automationCompositionUpdateAck);
-            return;
-        }
-
-        automationComposition = new AutomationComposition();
+        var automationComposition = new AutomationComposition();
         automationComposition.setInstanceId(instanceId);
         var acElements = storeElementsOnThisParticipant(participantDeploy);
         automationComposition.setElements(prepareAcElementMap(acElements));
@@ -379,9 +365,17 @@
         automationComposition.getElements().values().stream()
                 .forEach(acElement -> automationCompositionElementUndeploy(automationComposition.getInstanceId(),
                         acElement, startPhaseMsg, acElementDefinitions));
+    }
+
+    private void handleDeleteState(final AutomationComposition automationComposition, Integer startPhaseMsg,
+            List<AutomationCompositionElementDefinition> acElementDefinitions) {
+
+        automationComposition.getElements().values().stream()
+                .forEach(acElement -> automationCompositionElementDelete(automationComposition.getInstanceId(),
+                        acElement, startPhaseMsg, acElementDefinitions));
 
         boolean isAllUninitialised = automationComposition.getElements().values().stream()
-                .filter(element -> !DeployState.UNDEPLOYED.equals(element.getDeployState())).findAny().isEmpty();
+                .filter(element -> !DeployState.DELETED.equals(element.getDeployState())).findAny().isEmpty();
         if (isAllUninitialised) {
             automationCompositionMap.remove(automationComposition.getInstanceId());
         }
@@ -464,6 +458,24 @@
         }
     }
 
+    private void automationCompositionElementDelete(UUID instanceId, AutomationCompositionElement acElement,
+            Integer startPhaseMsg, List<AutomationCompositionElementDefinition> acElementDefinitions) {
+        var acElementNodeTemplate = getAcElementNodeTemplate(acElementDefinitions, acElement.getDefinition());
+        if (acElementNodeTemplate != null) {
+            int startPhase = ParticipantUtils.findStartPhase(acElementNodeTemplate.getProperties());
+            if (startPhaseMsg.equals(startPhase)) {
+                for (var acElementListener : listeners) {
+                    try {
+                        acElementListener.delete(instanceId, acElement.getId());
+                        updateAutomationCompositionElementState(instanceId, acElement.getId(), DeployState.DELETED,
+                                null, "Deleted");
+                    } catch (PfModelException e) {
+                        LOGGER.error("Automation composition element unlock failed {}", instanceId);
+                    }
+                }
+            }
+        }
+    }
 
     /**
      * Undeploy Instance Elements On Participant.
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 02e5b1a..4665fec 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
@@ -196,8 +196,8 @@
                     "Automation composition state is still " + automationComposition.getDeployState());
         }
         var response = new InstantiationResponse();
-        automationComposition =
-                automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId());
+        var acDefinition = acDefinitionProvider.getAcDefinition(automationComposition.getCompositionId());
+        supervisionAcHandler.delete(automationComposition, acDefinition);
         response.setInstanceId(automationComposition.getInstanceId());
         response.setAffectedAutomationComposition(automationComposition.getKey().asIdentifier());
         return response;
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 0eb4ecb..8032b4d 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
@@ -109,6 +109,19 @@
     }
 
     /**
+     * Handle Delete an AutomationComposition instance.
+     *
+     * @param automationComposition the AutomationComposition
+     * @param acDefinition the AutomationCompositionDefinition
+     */
+    public void delete(AutomationComposition automationComposition, AutomationCompositionDefinition acDefinition) {
+        AcmUtils.setCascadedState(automationComposition, DeployState.DELETING, LockState.NONE);
+        automationCompositionProvider.updateAutomationComposition(automationComposition);
+        var startPhase = ParticipantUtils.getFirstStartPhase(automationComposition, acDefinition.getServiceTemplate());
+        automationCompositionStateChangePublisher.send(automationComposition, startPhase, true);
+    }
+
+    /**
      * Handle a AutomationComposition deploy acknowledge message from a participant.
      *
      * @param automationCompositionAckMessage the AutomationCompositionAck message received from a participant
@@ -139,19 +152,33 @@
     }
 
     private void setAcElementStateInDb(AutomationCompositionDeployAck automationCompositionAckMessage) {
-        if (automationCompositionAckMessage.getAutomationCompositionResultMap() != null) {
-            var automationComposition = automationCompositionProvider
-                    .findAutomationComposition(automationCompositionAckMessage.getAutomationCompositionId());
-            if (automationComposition.isPresent()) {
-                var updated = updateState(automationComposition.get(),
-                        automationCompositionAckMessage.getAutomationCompositionResultMap().entrySet());
-                if (updated) {
-                    automationCompositionProvider.updateAutomationComposition(automationComposition.get());
-                }
+        var automationComposition = automationCompositionProvider
+                .findAutomationComposition(automationCompositionAckMessage.getAutomationCompositionId());
+        if (automationComposition.isEmpty()) {
+            LOGGER.warn("AutomationComposition not found in database {}",
+                    automationCompositionAckMessage.getAutomationCompositionId());
+            return;
+        }
+
+        if (automationCompositionAckMessage.getAutomationCompositionResultMap() == null
+                || automationCompositionAckMessage.getAutomationCompositionResultMap().isEmpty()) {
+            if (DeployState.DELETING.equals(automationComposition.get().getDeployState())) {
+                // scenario when Automation Composition instance has never been deployed
+                automationComposition.get().getElements().values()
+                        .forEach(element -> element.setDeployState(DeployState.DELETED));
+                automationCompositionProvider.updateAutomationComposition(automationComposition.get());
             } else {
-                LOGGER.warn("AutomationComposition not found in database {}",
-                        automationCompositionAckMessage.getAutomationCompositionId());
+                LOGGER.warn("Empty AutomationCompositionResultMap  {} {}",
+                        automationCompositionAckMessage.getAutomationCompositionId(),
+                        automationCompositionAckMessage.getMessage());
             }
+            return;
+        }
+
+        var updated = updateState(automationComposition.get(),
+                automationCompositionAckMessage.getAutomationCompositionResultMap().entrySet());
+        if (updated) {
+            automationCompositionProvider.updateAutomationComposition(automationComposition.get());
         }
     }
 
@@ -163,15 +190,9 @@
             if (element != null) {
                 element.setDeployState(acElementAck.getValue().getDeployState());
                 element.setLockState(acElementAck.getValue().getLockState());
-                if (DeployState.DEPLOYED.equals(element.getDeployState())) {
-                    element.setOperationalState(acElementAck.getValue().getOperationalState());
-                    element.setUseState(acElementAck.getValue().getUseState());
-                    element.setStatusProperties(acElementAck.getValue().getStatusProperties());
-                } else {
-                    element.setOperationalState(null);
-                    element.setUseState(null);
-                    element.setStatusProperties(Map.of());
-                }
+                element.setOperationalState(acElementAck.getValue().getOperationalState());
+                element.setUseState(acElementAck.getValue().getUseState());
+                element.setStatusProperties(acElementAck.getValue().getStatusProperties());
                 updated = true;
             }
         }
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 7ee7267..e23d79d 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
@@ -133,14 +133,7 @@
             LOGGER.debug("automation composition scan: transition state {} {} ", automationComposition.getDeployState(),
                     automationComposition.getLockState());
 
-            var deployState = automationComposition.getDeployState();
-            automationComposition.setDeployState(AcmUtils.deployCompleted(deployState));
-            automationComposition
-                    .setLockState(AcmUtils.lockCompleted(deployState, automationComposition.getLockState()));
-            automationCompositionProvider.updateAutomationComposition(automationComposition);
-
-            // Clear missed report counter on automation composition
-            clearFaultAndCounter(automationComposition);
+            complete(automationComposition);
         } else {
             LOGGER.debug("automation composition scan: transition from state {} to {} not completed",
                     automationComposition.getDeployState(), automationComposition.getLockState());
@@ -163,6 +156,21 @@
         }
     }
 
+    private void complete(final AutomationComposition automationComposition) {
+        var deployState = automationComposition.getDeployState();
+        automationComposition.setDeployState(AcmUtils.deployCompleted(deployState));
+        automationComposition
+                .setLockState(AcmUtils.lockCompleted(deployState, automationComposition.getLockState()));
+        if (DeployState.DELETED.equals(automationComposition.getDeployState())) {
+            automationCompositionProvider.deleteAutomationComposition(automationComposition.getInstanceId());
+        } else {
+            automationCompositionProvider.updateAutomationComposition(automationComposition);
+        }
+
+        // Clear missed report counter on automation composition
+        clearFaultAndCounter(automationComposition);
+    }
+
     private void clearFaultAndCounter(AutomationComposition automationComposition) {
         automationCompositionCounter.clear(automationComposition.getInstanceId());
         phaseMap.remove(automationComposition.getInstanceId());
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 9f39d8d..faf356c 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
@@ -95,8 +95,9 @@
         var compositionId = acDefinition.getCompositionId();
         when(acDefinitionProvider.findAcDefinition(compositionId)).thenReturn(Optional.of(acDefinition));
         var acProvider = mock(AutomationCompositionProvider.class);
-        var instantiationProvider =
-                new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider, null, null);
+        var supervisionAcHandler = mock(SupervisionAcHandler.class);
+        var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, acDefinitionProvider,
+                null, supervisionAcHandler);
         var automationCompositionCreate =
                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
         automationCompositionCreate.setCompositionId(compositionId);
@@ -136,7 +137,7 @@
         instantiationProvider.deleteAutomationComposition(automationCompositionCreate.getCompositionId(),
                 automationCompositionCreate.getInstanceId());
 
-        verify(acProvider).deleteAutomationComposition(automationCompositionCreate.getInstanceId());
+        verify(supervisionAcHandler).delete(any(), any());
     }
 
     @Test
@@ -146,9 +147,10 @@
 
         var acProvider = mock(AutomationCompositionProvider.class);
         var acDefinitionProvider = mock(AcDefinitionProvider.class);
+        var supervisionAcHandler = mock(SupervisionAcHandler.class);
 
         var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider,
-                acDefinitionProvider, null, null);
+                acDefinitionProvider, null, supervisionAcHandler);
 
         when(acProvider.getAutomationComposition(automationComposition.getInstanceId()))
                 .thenReturn(automationComposition);
@@ -168,6 +170,7 @@
         when(acProvider.deleteAutomationComposition(instanceId)).thenReturn(automationComposition);
 
         instantiationProvider.deleteAutomationComposition(compositionId, instanceId);
+        verify(supervisionAcHandler).delete(any(), any());
     }
 
     private void assertThatDeleteThrownBy(AutomationComposition automationComposition,
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java
index fe0a477..5380d67 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java
@@ -42,6 +42,7 @@
 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
 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;
@@ -268,7 +269,8 @@
 
         var automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(compositionId,
                 automationCompositionFromRsc.getKey().getName(), automationCompositionFromRsc.getKey().getVersion());
-        assertThat(automationCompositionsFromDb.getAutomationCompositionList()).isEmpty();
+        assertEquals(DeployState.DELETING,
+                automationCompositionsFromDb.getAutomationCompositionList().get(0).getDeployState());
     }
 
     @Test
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java
index 032468a..8ead9a7 100644
--- a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java
@@ -101,7 +101,28 @@
                 acRuntimeParameterGroup);
         supervisionScanner.run(false);
 
-        verify(automationCompositionProvider, times(1)).updateAutomationComposition(any(AutomationComposition.class));
+        verify(automationCompositionProvider).updateAutomationComposition(any(AutomationComposition.class));
+    }
+
+    @Test
+    void testScannerDelete() {
+        var automationComposition = InstantiationUtils.getAutomationCompositionFromResource(AC_JSON, "Crud");
+        automationComposition.setDeployState(DeployState.DELETING);
+        automationComposition.setLockState(LockState.NONE);
+        var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+        when(automationCompositionProvider.getAcInstancesByCompositionId(compositionId))
+                .thenReturn(List.of(automationComposition));
+
+        var automationCompositionDeployPublisher = mock(AutomationCompositionDeployPublisher.class);
+        var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
+        var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+
+        var supervisionScanner = new SupervisionScanner(automationCompositionProvider, acDefinitionProvider,
+                automationCompositionStateChangePublisher, automationCompositionDeployPublisher,
+                acRuntimeParameterGroup);
+        supervisionScanner.run(false);
+
+        verify(automationCompositionProvider).deleteAutomationComposition(automationComposition.getInstanceId());
     }
 
     @Test