Add restart support inside participants

Issue-ID: POLICY-4747
Change-Id: I15a6c584062d0fcf0c0c0a6b15a8f3c2c96f7c98
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
diff --git a/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AutomationCompositionElementHandler.java
index d653c5a..e2a5367 100755
--- a/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AutomationCompositionElementHandler.java
+++ b/participant/participant-impl/participant-impl-a1pms/src/main/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AutomationCompositionElementHandler.java
@@ -21,10 +21,10 @@
 package org.onap.policy.clamp.acm.participant.a1pms.handler;
 
 import java.lang.invoke.MethodHandles;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
 import javax.validation.Validation;
 import javax.validation.ValidationException;
 import lombok.AccessLevel;
@@ -42,6 +42,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.StateChangeResult;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
@@ -67,7 +68,7 @@
 
     // Map of acElement Id and A1PMS services
     @Getter(AccessLevel.PACKAGE)
-    private final Map<UUID, ConfigurationEntity> configRequestMap = new HashMap<>();
+    private final Map<UUID, ConfigurationEntity> configRequestMap = new ConcurrentHashMap<>();
 
     /**
      * Handle a automation composition element state change.
@@ -162,4 +163,39 @@
         intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR,
                 "Deprimed");
     }
+
+    @Override
+    public void handleRestartComposition(UUID compositionId,
+            List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state)
+            throws PfModelException {
+        var finalState = AcTypeState.PRIMED.equals(state) || AcTypeState.PRIMING.equals(state) ? AcTypeState.PRIMED
+                : AcTypeState.COMMISSIONED;
+        intermediaryApi.updateCompositionState(compositionId, finalState, StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Override
+    public void handleRestartInstance(UUID automationCompositionId, AcElementDeploy element,
+            Map<String, Object> properties, DeployState deployState, LockState lockState) throws PfModelException {
+        if (DeployState.DEPLOYING.equals(deployState)) {
+            deploy(automationCompositionId, element, properties);
+            return;
+        }
+        if (DeployState.UNDEPLOYING.equals(deployState) || DeployState.DEPLOYED.equals(deployState)
+                || DeployState.UPDATING.equals(deployState)) {
+            try {
+                var configurationEntity = CODER.convert(properties, ConfigurationEntity.class);
+                configRequestMap.put(element.getId(), configurationEntity);
+            } catch (ValidationException | CoderException e) {
+                throw new A1PolicyServiceException(HttpStatus.SC_BAD_REQUEST, "Invalid Configuration", e);
+            }
+        }
+        if (DeployState.UNDEPLOYING.equals(deployState)) {
+            undeploy(automationCompositionId, element.getId());
+            return;
+        }
+        deployState = AcmUtils.deployCompleted(deployState);
+        lockState = AcmUtils.lockCompleted(deployState, lockState);
+        intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), deployState,
+                lockState, StateChangeResult.NO_ERROR, "Restarted");
+    }
 }
diff --git a/participant/participant-impl/participant-impl-a1pms/src/test/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AcElementHandlerTest.java b/participant/participant-impl/participant-impl-a1pms/src/test/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AcElementHandlerTest.java
index 50f4932..dec11fd 100755
--- a/participant/participant-impl/participant-impl-a1pms/src/test/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AcElementHandlerTest.java
+++ b/participant/participant-impl/participant-impl-a1pms/src/test/java/org/onap/policy/clamp/acm/participant/a1pms/handler/AcElementHandlerTest.java
@@ -213,4 +213,67 @@
         verify(participantIntermediaryApi).updateCompositionState(compositionId, AcTypeState.COMMISSIONED,
                 StateChangeResult.NO_ERROR, "Deprimed");
     }
+
+    @Test
+    void testHandleRestartComposition() throws PfModelException {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acA1PmsClient);
+
+        var compositionId = UUID.randomUUID();
+        automationCompositionElementHandler.handleRestartComposition(compositionId, List.of(), AcTypeState.PRIMED);
+
+        verify(participantIntermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED,
+                StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Test
+    void testHandleRestartInstanceDeploying() throws PfModelException {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, acA1PmsClient);
+
+        var automationCompositionId = UUID.randomUUID();
+        var element = commonTestData.getAutomationCompositionElement();
+        var automationCompositionElementId = element.getId();
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        automationCompositionElementHandler.handleRestartInstance(automationCompositionId, element,
+                nodeTemplatesMap.get(A1_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.DEPLOYING,
+                LockState.NONE);
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(automationCompositionId,
+                automationCompositionElementId, DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
+    }
+
+    @Test
+    void testHandleRestartInstanceDeployed() throws PfModelException {
+        var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(intermediaryApi, acA1PmsClient);
+
+        var automationCompositionId = UUID.randomUUID();
+        var element = commonTestData.getAutomationCompositionElement();
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        automationCompositionElementHandler.handleRestartInstance(automationCompositionId, element,
+                nodeTemplatesMap.get(A1_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.DEPLOYED,
+                LockState.LOCKED);
+        verify(intermediaryApi).updateAutomationCompositionElementState(automationCompositionId, element.getId(),
+                DeployState.DEPLOYED, LockState.LOCKED, StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Test
+    void testHandleRestartInstanceUndeployed() throws PfModelException {
+        var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(intermediaryApi, acA1PmsClient);
+
+        var automationCompositionId = UUID.randomUUID();
+        var element = commonTestData.getAutomationCompositionElement();
+        var automationCompositionElementId = element.getId();
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        automationCompositionElementHandler.handleRestartInstance(automationCompositionId, element,
+                nodeTemplatesMap.get(A1_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.UNDEPLOYING,
+                LockState.LOCKED);
+        verify(intermediaryApi).updateAutomationCompositionElementState(automationCompositionId,
+                automationCompositionElementId, DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed");
+    }
 }
diff --git a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java
index e3ebf3b..9d4718b 100644
--- a/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java
+++ b/participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/acm/participant/http/main/handler/AutomationCompositionElementHandler.java
@@ -39,6 +39,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.StateChangeResult;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
@@ -156,4 +157,26 @@
         intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR,
                 "Deprimed");
     }
+
+    @Override
+    public void handleRestartComposition(UUID compositionId,
+            List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state)
+            throws PfModelException {
+        var finalState = AcTypeState.PRIMED.equals(state) || AcTypeState.PRIMING.equals(state) ? AcTypeState.PRIMED
+                : AcTypeState.COMMISSIONED;
+        intermediaryApi.updateCompositionState(compositionId, finalState, StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Override
+    public void handleRestartInstance(UUID automationCompositionId, AcElementDeploy element,
+            Map<String, Object> properties, DeployState deployState, LockState lockState) throws PfModelException {
+        if (DeployState.DEPLOYING.equals(deployState)) {
+            deploy(automationCompositionId, element, properties);
+            return;
+        }
+        deployState = AcmUtils.deployCompleted(deployState);
+        lockState = AcmUtils.lockCompleted(deployState, lockState);
+        intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), deployState,
+                lockState, StateChangeResult.NO_ERROR, "Restarted");
+    }
 }
diff --git a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java
index f0f9913..de0d21e 100644
--- a/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java
+++ b/participant/participant-impl/participant-impl-http/src/test/java/org/onap/policy/clamp/acm/participant/http/handler/AcElementHandlerTest.java
@@ -196,4 +196,48 @@
         verify(participantIntermediaryApi).updateCompositionState(compositionId, AcTypeState.COMMISSIONED,
                 StateChangeResult.NO_ERROR, "Deprimed");
     }
+
+    @Test
+    void testHandleRestartComposition() throws PfModelException {
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, mock(AcHttpClient.class));
+
+        var compositionId = UUID.randomUUID();
+        automationCompositionElementHandler.handleRestartComposition(compositionId, List.of(), AcTypeState.PRIMED);
+        verify(participantIntermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED,
+                StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Test
+    void testHandleRestartInstanceDeploying() throws PfModelException {
+        var serviceTemplate = ToscaUtils.readAutomationCompositionFromTosca();
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        var map = new HashMap<>(nodeTemplatesMap.get(HTTP_AUTOMATION_COMPOSITION_ELEMENT).getProperties());
+        var element = commonTestData.getAutomationCompositionElement();
+        map.putAll(element.getProperties());
+        var instanceId = commonTestData.getAutomationCompositionId();
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, mock(AcHttpClient.class));
+
+        automationCompositionElementHandler.handleRestartInstance(instanceId, element, map, DeployState.DEPLOYING,
+                LockState.NONE);
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(),
+                DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
+    }
+
+    @Test
+    void testHandleRestartInstanceDeployed() throws PfModelException {
+        var element = commonTestData.getAutomationCompositionElement();
+        var instanceId = commonTestData.getAutomationCompositionId();
+        var participantIntermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(participantIntermediaryApi, mock(AcHttpClient.class));
+
+        automationCompositionElementHandler.handleRestartInstance(instanceId, element, element.getProperties(),
+                DeployState.DEPLOYED, LockState.LOCKED);
+        verify(participantIntermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(),
+                DeployState.DEPLOYED, LockState.LOCKED, StateChangeResult.NO_ERROR, "Restarted");
+    }
 }
diff --git a/participant/participant-impl/participant-impl-kserve/src/main/java/org/onap/policy/clamp/acm/participant/kserve/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-kserve/src/main/java/org/onap/policy/clamp/acm/participant/kserve/handler/AutomationCompositionElementHandler.java
index ed02314..3a53a7a 100755
--- a/participant/participant-impl/participant-impl-kserve/src/main/java/org/onap/policy/clamp/acm/participant/kserve/handler/AutomationCompositionElementHandler.java
+++ b/participant/participant-impl/participant-impl-kserve/src/main/java/org/onap/policy/clamp/acm/participant/kserve/handler/AutomationCompositionElementHandler.java
@@ -23,10 +23,10 @@
 import io.kubernetes.client.openapi.ApiException;
 import java.io.IOException;
 import java.lang.invoke.MethodHandles;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -50,6 +50,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.StateChangeResult;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
@@ -76,7 +77,7 @@
     private final KserveClient kserveClient;
 
     @Getter(AccessLevel.PACKAGE)
-    private final Map<UUID, ConfigurationEntity> configRequestMap = new HashMap<>();
+    private final Map<UUID, ConfigurationEntity> configRequestMap = new ConcurrentHashMap<>();
 
     private static class ThreadConfig {
 
@@ -206,4 +207,39 @@
         intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR,
                 "Deprimed");
     }
+
+    @Override
+    public void handleRestartComposition(UUID compositionId,
+            List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state)
+            throws PfModelException {
+        var finalState = AcTypeState.PRIMED.equals(state) || AcTypeState.PRIMING.equals(state) ? AcTypeState.PRIMED
+                : AcTypeState.COMMISSIONED;
+        intermediaryApi.updateCompositionState(compositionId, finalState, StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Override
+    public void handleRestartInstance(UUID automationCompositionId, AcElementDeploy element,
+            Map<String, Object> properties, DeployState deployState, LockState lockState) throws PfModelException {
+        if (DeployState.DEPLOYING.equals(deployState)) {
+            deploy(automationCompositionId, element, properties);
+            return;
+        }
+        if (DeployState.UNDEPLOYING.equals(deployState) || DeployState.DEPLOYED.equals(deployState)
+                || DeployState.UPDATING.equals(deployState)) {
+            try {
+                var configurationEntity = CODER.convert(properties, ConfigurationEntity.class);
+                configRequestMap.put(element.getId(), configurationEntity);
+            } catch (CoderException e) {
+                throw new KserveException(HttpStatus.SC_BAD_REQUEST, "Invalid inference service configuration", e);
+            }
+        }
+        if (DeployState.UNDEPLOYING.equals(deployState)) {
+            undeploy(automationCompositionId, element.getId());
+            return;
+        }
+        deployState = AcmUtils.deployCompleted(deployState);
+        lockState = AcmUtils.lockCompleted(deployState, lockState);
+        intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), deployState,
+                lockState, StateChangeResult.NO_ERROR, "Restarted");
+    }
 }
diff --git a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java
index 6112488..1c1699f 100755
--- a/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java
+++ b/participant/participant-impl/participant-impl-kserve/src/test/java/org/onap/policy/clamp/acm/participant/kserve/handler/AcElementHandlerTest.java
@@ -49,6 +49,9 @@
 import org.onap.policy.clamp.acm.participant.kserve.k8s.KserveClient;
 import org.onap.policy.clamp.acm.participant.kserve.utils.CommonTestData;
 import org.onap.policy.clamp.acm.participant.kserve.utils.ToscaUtils;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
+import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
@@ -165,4 +168,45 @@
     void testDeprime() throws PfModelException {
         assertDoesNotThrow(() -> automationCompositionElementHandler.deprime(UUID.randomUUID()));
     }
+
+    @Test
+    void testHandleRestartComposition() throws PfModelException {
+        assertDoesNotThrow(() -> automationCompositionElementHandler.handleRestartComposition(UUID.randomUUID(),
+                List.of(), AcTypeState.PRIMED));
+    }
+
+    @Test
+    void testHandleRestartInstanceDeploying() throws PfModelException {
+        var element = commonTestData.getAutomationCompositionElement();
+
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        assertDoesNotThrow(() -> automationCompositionElementHandler.handleRestartInstance(
+                commonTestData.getAutomationCompositionId(), element,
+                nodeTemplatesMap.get(KSERVE_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.DEPLOYING,
+                LockState.NONE));
+        assertThat(automationCompositionElementHandler.getConfigRequestMap()).containsKey(element.getId());
+    }
+
+    @Test
+    void testHandleRestartInstanceDeployed() throws PfModelException {
+        var element = commonTestData.getAutomationCompositionElement();
+
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        assertDoesNotThrow(() -> automationCompositionElementHandler.handleRestartInstance(
+                commonTestData.getAutomationCompositionId(), element,
+                nodeTemplatesMap.get(KSERVE_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.DEPLOYED,
+                LockState.LOCKED));
+        assertThat(automationCompositionElementHandler.getConfigRequestMap()).containsKey(element.getId());
+    }
+
+    @Test
+    void testHandleRestartInstanceUndeployed() throws PfModelException {
+        var element = commonTestData.getAutomationCompositionElement();
+
+        var nodeTemplatesMap = serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        assertDoesNotThrow(() -> automationCompositionElementHandler.handleRestartInstance(
+                commonTestData.getAutomationCompositionId(), element,
+                nodeTemplatesMap.get(KSERVE_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.UNDEPLOYING,
+                LockState.LOCKED));
+    }
 }
diff --git a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java
index 7385a1f..a0ea316 100644
--- a/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java
+++ b/participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandler.java
@@ -44,6 +44,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.StateChangeResult;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
@@ -212,4 +213,40 @@
         intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR,
                 "Deprimed");
     }
+
+    @Override
+    public void handleRestartComposition(UUID compositionId,
+            List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state)
+            throws PfModelException {
+        var finalState = AcTypeState.PRIMED.equals(state) || AcTypeState.PRIMING.equals(state) ? AcTypeState.PRIMED
+                : AcTypeState.COMMISSIONED;
+        intermediaryApi.updateCompositionState(compositionId, finalState, StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Override
+    public void handleRestartInstance(UUID automationCompositionId, AcElementDeploy element,
+            Map<String, Object> properties, DeployState deployState, LockState lockState) throws PfModelException {
+        if (DeployState.DEPLOYING.equals(deployState)) {
+            deploy(automationCompositionId, element, properties);
+            return;
+        }
+        if (DeployState.UNDEPLOYING.equals(deployState) || DeployState.DEPLOYED.equals(deployState)
+                || DeployState.UPDATING.equals(deployState)) {
+            try {
+                var chartInfo = getChartInfo(properties);
+                chartMap.put(element.getId(), chartInfo);
+            } catch (AutomationCompositionException e) {
+                intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
+                        DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, e.getMessage());
+            }
+        }
+        if (DeployState.UNDEPLOYING.equals(deployState)) {
+            undeploy(automationCompositionId, element.getId());
+            return;
+        }
+        deployState = AcmUtils.deployCompleted(deployState);
+        lockState = AcmUtils.lockCompleted(deployState, lockState);
+        intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), deployState,
+                lockState, StateChangeResult.NO_ERROR, "Restarted");
+    }
 }
diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java
index 6b24c0f..6cf344f 100644
--- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java
+++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/handler/AutomationCompositionElementHandlerTest.java
@@ -52,14 +52,13 @@
 import org.onap.policy.clamp.acm.participant.kubernetes.parameters.CommonTestData;
 import org.onap.policy.clamp.acm.participant.kubernetes.service.ChartService;
 import org.onap.policy.clamp.acm.participant.kubernetes.utils.TestUtils;
-import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
-import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
-import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
+import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.models.base.PfModelException;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
@@ -121,12 +120,7 @@
     void test_AutomationCompositionElementUpdate()
             throws PfModelException, IOException, ServiceException, ExecutionException, InterruptedException {
         doNothing().when(automationCompositionElementHandler).checkPodStatus(any(), any(), any(), anyInt(), anyInt());
-        var elementId1 = UUID.randomUUID();
-        var element = new AcElementDeploy();
-        element.setId(elementId1);
-        element.setDefinition(new ToscaConceptIdentifier(KEY_NAME, "1.0.1"));
-        element.setOrderedState(DeployOrder.DEPLOY);
-
+        var element = CommonTestData.createAcElementDeploy();
         var nodeTemplatesMap = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
 
         doReturn(false).when(chartService).installChart(any());
@@ -137,7 +131,7 @@
         automationCompositionElementHandler.deploy(commonTestData.getAutomationCompositionId(), element,
                 nodeTemplatesMap.get(K8S_AUTOMATION_COMPOSITION_ELEMENT).getProperties());
 
-        assertThat(automationCompositionElementHandler.getChartMap()).hasSize(1).containsKey(elementId1);
+        assertThat(automationCompositionElementHandler.getChartMap()).hasSize(1).containsKey(element.getId());
 
         doThrow(new ServiceException("Error installing the chart")).when(chartService).installChart(Mockito.any());
 
@@ -154,18 +148,13 @@
     void test_checkPodStatus() throws ExecutionException, InterruptedException {
         var chartInfo = charts.get(0);
         var automationCompositionId = UUID.randomUUID();
-        var element = new AutomationCompositionElement();
         assertThrows(ServiceException.class, () -> automationCompositionElementHandler
-                .checkPodStatus(automationCompositionId, element.getId(), chartInfo, 1, 1));
+                .checkPodStatus(automationCompositionId, UUID.randomUUID(), chartInfo, 1, 1));
     }
 
     @Test
     void testUpdate() throws PfModelException {
-        var elementId1 = UUID.randomUUID();
-        var element = new AcElementDeploy();
-        element.setId(elementId1);
-        element.setDefinition(new ToscaConceptIdentifier(KEY_NAME, "1.0.1"));
-        element.setOrderedState(DeployOrder.DEPLOY);
+        var element = CommonTestData.createAcElementDeploy();
         var automationCompositionId = commonTestData.getAutomationCompositionId();
         assertDoesNotThrow(
                 () -> automationCompositionElementHandler.update(automationCompositionId, element, Map.of()));
@@ -195,4 +184,54 @@
     void testDeprime() throws PfModelException {
         assertDoesNotThrow(() -> automationCompositionElementHandler.deprime(UUID.randomUUID()));
     }
+
+    @Test
+    void testHandleRestartComposition() throws PfModelException {
+        assertDoesNotThrow(() -> automationCompositionElementHandler.handleRestartComposition(UUID.randomUUID(),
+                List.of(), AcTypeState.PRIMED));
+    }
+
+    @Test
+    void testHandleRestartInstanceDeploying()
+            throws PfModelException, InterruptedException, ServiceException, IOException {
+        doNothing().when(automationCompositionElementHandler).checkPodStatus(any(), any(), any(), anyInt(), anyInt());
+        var element = CommonTestData.createAcElementDeploy();
+        var nodeTemplatesMap = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+
+        doReturn(true).when(chartService).installChart(any());
+        assertDoesNotThrow(() -> automationCompositionElementHandler.handleRestartInstance(
+                commonTestData.getAutomationCompositionId(), element,
+                nodeTemplatesMap.get(K8S_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.DEPLOYING,
+                LockState.NONE));
+
+        assertThat(automationCompositionElementHandler.getChartMap()).containsKey(element.getId());
+    }
+
+    @Test
+    void testHandleRestartInstanceDeployed()
+            throws PfModelException, InterruptedException, ServiceException, IOException {
+        doNothing().when(automationCompositionElementHandler).checkPodStatus(any(), any(), any(), anyInt(), anyInt());
+        var element = CommonTestData.createAcElementDeploy();
+        var nodeTemplatesMap = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+
+        assertDoesNotThrow(() -> automationCompositionElementHandler.handleRestartInstance(
+                commonTestData.getAutomationCompositionId(), element,
+                nodeTemplatesMap.get(K8S_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.DEPLOYED,
+                LockState.LOCKED));
+
+        assertThat(automationCompositionElementHandler.getChartMap()).containsKey(element.getId());
+    }
+
+    @Test
+    void testHandleRestartInstanceUndeploying()
+            throws PfModelException, InterruptedException, ServiceException, IOException {
+        doNothing().when(automationCompositionElementHandler).checkPodStatus(any(), any(), any(), anyInt(), anyInt());
+        var element = CommonTestData.createAcElementDeploy();
+        var nodeTemplatesMap = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+
+        assertDoesNotThrow(() -> automationCompositionElementHandler.handleRestartInstance(
+                commonTestData.getAutomationCompositionId(), element,
+                nodeTemplatesMap.get(K8S_AUTOMATION_COMPOSITION_ELEMENT).getProperties(), DeployState.UNDEPLOYING,
+                LockState.LOCKED));
+    }
 }
diff --git a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java
index 8041a4e..8de972b 100644
--- a/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java
+++ b/participant/participant-impl/participant-impl-kubernetes/src/test/java/org/onap/policy/clamp/acm/participant/kubernetes/parameters/CommonTestData.java
@@ -26,10 +26,13 @@
 import java.util.Map;
 import java.util.TreeMap;
 import java.util.UUID;
+import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
 import org.onap.policy.common.endpoints.parameters.TopicParameters;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 
 public class CommonTestData {
 
@@ -39,6 +42,8 @@
     public static final List<TopicParameters> TOPIC_PARAMS = List.of(getTopicParams());
     public static final Coder CODER = new StandardCoder();
     private static final UUID AC_ID = UUID.randomUUID();
+    private static final String KEY_NAME =
+            "org.onap.domain.database.HelloWorld_K8SMicroserviceAutomationCompositionElement";
 
     /**
      * Get ParticipantK8sParameters.
@@ -154,4 +159,17 @@
     public UUID getAutomationCompositionId() {
         return AC_ID;
     }
+
+    /**
+     * Create an AcElementDeploy.
+     *
+     * @return an AcElementDeploy
+     */
+    public static AcElementDeploy createAcElementDeploy() {
+        var element = new AcElementDeploy();
+        element.setId(UUID.randomUUID());
+        element.setDefinition(new ToscaConceptIdentifier(KEY_NAME, "1.0.1"));
+        element.setOrderedState(DeployOrder.DEPLOY);
+        return element;
+    }
 }
diff --git a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java
index 2962214..6b94a79 100644
--- a/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java
+++ b/participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandler.java
@@ -40,6 +40,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.StateChangeResult;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.pdp.concepts.DeploymentSubGroup;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
@@ -244,4 +245,35 @@
         intermediaryApi.updateCompositionState(compositionId, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR,
                 "Deprimed");
     }
+
+    @Override
+    public void handleRestartComposition(UUID compositionId,
+            List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state)
+            throws PfModelException {
+        var finalState = AcTypeState.PRIMED.equals(state) || AcTypeState.PRIMING.equals(state) ? AcTypeState.PRIMED
+                : AcTypeState.COMMISSIONED;
+        intermediaryApi.updateCompositionState(compositionId, finalState, StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Override
+    public void handleRestartInstance(UUID automationCompositionId, AcElementDeploy element,
+            Map<String, Object> properties, DeployState deployState, LockState lockState) throws PfModelException {
+        if (DeployState.DEPLOYING.equals(deployState)) {
+            deploy(automationCompositionId, element, properties);
+            return;
+        }
+        if (DeployState.UNDEPLOYING.equals(deployState) || DeployState.DEPLOYED.equals(deployState)
+                || DeployState.UPDATING.equals(deployState)) {
+            var automationCompositionDefinition = element.getToscaServiceTemplateFragment();
+            serviceTemplateMap.put(element.getId(), automationCompositionDefinition);
+        }
+        if (DeployState.UNDEPLOYING.equals(deployState)) {
+            undeploy(automationCompositionId, element.getId());
+            return;
+        }
+        deployState = AcmUtils.deployCompleted(deployState);
+        lockState = AcmUtils.lockCompleted(deployState, lockState);
+        intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(), deployState,
+                lockState, StateChangeResult.NO_ERROR, "Restarted");
+    }
 }
diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java
index 84ddeed..16530d6 100644
--- a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java
+++ b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/acm/participant/policy/main/handler/AutomationCompositionElementHandlerTest.java
@@ -218,4 +218,53 @@
         verify(intermediaryApi).updateCompositionState(AC_ID, AcTypeState.COMMISSIONED, StateChangeResult.NO_ERROR,
                 "Deprimed");
     }
+
+    @Test
+    void testHandleRestartComposition() throws PfModelException {
+        var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var automationCompositionElementHandler =
+                new AutomationCompositionElementHandler(mock(PolicyApiHttpClient.class),
+                        mock(PolicyPapHttpClient.class), intermediaryApi);
+
+        var compositionId = UUID.randomUUID();
+        automationCompositionElementHandler.handleRestartComposition(compositionId, List.of(), AcTypeState.PRIMED);
+
+        verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED,
+                StateChangeResult.NO_ERROR, "Restarted");
+    }
+
+    @Test
+    void testHandleRestartInstanceDeploying() throws PfModelException {
+        // Mock success scenario for policy creation and deployment
+        var api = mock(PolicyApiHttpClient.class);
+        doReturn(Response.ok().build()).when(api).createPolicyType(any());
+        doReturn(Response.ok().build()).when(api).createPolicy(any());
+
+        var pap = mock(PolicyPapHttpClient.class);
+        doReturn(Response.accepted().build()).when(pap).handlePolicyDeployOrUndeploy(any(), any(), any());
+
+        var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var handler = new AutomationCompositionElementHandler(api, pap, intermediaryApi);
+        var element = getTestingAcElement();
+
+        handler.handleRestartInstance(AC_ID, element, Map.of(), DeployState.DEPLOYING, LockState.NONE);
+        verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId,
+                DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
+
+        handler.handleRestartInstance(AC_ID, element, Map.of(), DeployState.UNDEPLOYING, LockState.LOCKED);
+        verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId,
+                DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed");
+    }
+
+    @Test
+    void testHandleRestartInstanceDeployed() throws PfModelException {
+        var api = mock(PolicyApiHttpClient.class);
+        var pap = mock(PolicyPapHttpClient.class);
+        var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var handler = new AutomationCompositionElementHandler(api, pap, intermediaryApi);
+        var element = getTestingAcElement();
+        handler.handleRestartInstance(AC_ID, element, Map.of(), DeployState.DEPLOYED, LockState.LOCKED);
+        verify(intermediaryApi).updateAutomationCompositionElementState(AC_ID, automationCompositionElementId,
+                DeployState.DEPLOYED, LockState.LOCKED, StateChangeResult.NO_ERROR, "Restarted");
+    }
 }
diff --git a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandler.java b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandler.java
index 7554c0b..eaf9455 100644
--- a/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandler.java
+++ b/participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandler.java
@@ -40,6 +40,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.StateChangeResult;
+import org.onap.policy.clamp.models.acm.utils.AcmUtils;
 import org.onap.policy.models.base.PfModelException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -188,7 +189,7 @@
     @Override
     public void update(UUID automationCompositionId, AcElementDeploy element, Map<String, Object> properties)
             throws PfModelException {
-        LOGGER.debug("updat call");
+        LOGGER.debug("update call");
 
         if (!execution(config.getUpdateTimerMs(), "Current Thread update is Interrupted during execution {}",
                 element.getId())) {
@@ -233,6 +234,7 @@
     @Override
     public void prime(UUID compositionId, List<AutomationCompositionElementDefinition> elementDefinitionList)
             throws PfModelException {
+        LOGGER.debug("prime call");
 
         if (!execution(config.getPrimeTimerMs(), "Current Thread prime is Interrupted during execution {}",
                 compositionId)) {
@@ -250,6 +252,7 @@
 
     @Override
     public void deprime(UUID compositionId) throws PfModelException {
+        LOGGER.debug("deprime call");
 
         if (!execution(config.getDeprimeTimerMs(), "Current Thread deprime is Interrupted during execution {}",
                 compositionId)) {
@@ -287,4 +290,57 @@
         }
         return result;
     }
+
+    @Override
+    public void handleRestartComposition(UUID compositionId,
+            List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state)
+            throws PfModelException {
+        LOGGER.debug("restart composition definition call");
+        switch (state) {
+            case PRIMING:
+                prime(compositionId, elementDefinitionList);
+                break;
+
+            case DEPRIMING:
+                deprime(compositionId);
+                break;
+
+            default:
+                intermediaryApi.updateCompositionState(compositionId, state, StateChangeResult.NO_ERROR, "Restarted");
+        }
+    }
+
+    @Override
+    public void handleRestartInstance(UUID automationCompositionId, AcElementDeploy element,
+            Map<String, Object> properties, DeployState deployState, LockState lockState) throws PfModelException {
+        LOGGER.debug("restart instance call");
+        if (!AcmUtils.isInTransitionalState(deployState, lockState)) {
+            intermediaryApi.updateAutomationCompositionElementState(automationCompositionId, element.getId(),
+                    deployState, lockState, StateChangeResult.NO_ERROR, "Restarted");
+            return;
+        }
+        if (DeployState.DEPLOYING.equals(deployState)) {
+            deploy(automationCompositionId, element, properties);
+            return;
+        }
+        if (DeployState.UNDEPLOYING.equals(deployState)) {
+            undeploy(automationCompositionId, element.getId());
+            return;
+        }
+        if (DeployState.UPDATING.equals(deployState)) {
+            update(automationCompositionId, element, properties);
+            return;
+        }
+        if (DeployState.DELETING.equals(deployState)) {
+            delete(automationCompositionId, element.getId());
+            return;
+        }
+        if (LockState.LOCKING.equals(lockState)) {
+            lock(automationCompositionId, element.getId());
+            return;
+        }
+        if (LockState.UNLOCKING.equals(lockState)) {
+            unlock(automationCompositionId, element.getId());
+        }
+    }
 }
diff --git a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerTest.java b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerTest.java
index 977b9d8..70111cb 100644
--- a/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerTest.java
+++ b/participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/acm/participant/sim/main/handler/AutomationCompositionElementHandlerTest.java
@@ -192,9 +192,9 @@
         when(intermediaryApi.getAutomationCompositions()).thenReturn(map);
         var result = acElementHandler.getDataList();
         var data = result.getList().get(0);
-        var autocomposition = map.values().iterator().next();
-        assertEquals(autocomposition.getInstanceId(), data.getAutomationCompositionId());
-        var element = autocomposition.getElements().values().iterator().next();
+        var automationcomposition = map.values().iterator().next();
+        assertEquals(automationcomposition.getInstanceId(), data.getAutomationCompositionId());
+        var element = automationcomposition.getElements().values().iterator().next();
         assertEquals(element.getId(), data.getAutomationCompositionElementId());
     }
 
@@ -233,4 +233,66 @@
         verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.FAILED,
                 "Deprime failed!");
     }
+
+    @Test
+    void testHandleRestartComposition() throws PfModelException {
+        var config = new SimConfig();
+        config.setPrimeTimerMs(1);
+        var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi);
+        acElementHandler.setConfig(config);
+        var compositionId = UUID.randomUUID();
+        acElementHandler.handleRestartComposition(compositionId, List.of(), AcTypeState.PRIMING);
+        verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR,
+                "Primed");
+
+        acElementHandler.handleRestartComposition(compositionId, List.of(), AcTypeState.PRIMED);
+        verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.NO_ERROR,
+                "Restarted");
+
+        acElementHandler.handleRestartComposition(compositionId, List.of(), AcTypeState.DEPRIMING);
+        verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.COMMISSIONED,
+                StateChangeResult.NO_ERROR, "Deprimed");
+    }
+
+    @Test
+    void testHandleRestartInstance() throws PfModelException {
+        var config = new SimConfig();
+        config.setDeployTimerMs(1);
+        var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var acElementHandler = new AutomationCompositionElementHandler(intermediaryApi);
+        acElementHandler.setConfig(config);
+        var instanceId = UUID.randomUUID();
+        var element = new AcElementDeploy();
+        element.setId(UUID.randomUUID());
+        acElementHandler.handleRestartInstance(instanceId, element, Map.of(), DeployState.DEPLOYING, LockState.NONE);
+        verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(),
+                DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Deployed");
+
+        acElementHandler.handleRestartInstance(instanceId, element, Map.of(), DeployState.DEPLOYED, LockState.LOCKED);
+        verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(),
+                DeployState.DEPLOYED, LockState.LOCKED, StateChangeResult.NO_ERROR, "Restarted");
+
+        acElementHandler.handleRestartInstance(instanceId, element, Map.of(), DeployState.UPDATING, LockState.LOCKED);
+        verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(),
+                DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "Updated");
+
+        acElementHandler.handleRestartInstance(instanceId, element, Map.of(), DeployState.UNDEPLOYING,
+                LockState.LOCKED);
+        verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(),
+                DeployState.UNDEPLOYED, null, StateChangeResult.NO_ERROR, "Undeployed");
+
+        acElementHandler.handleRestartInstance(instanceId, element, Map.of(), DeployState.DELETING, LockState.NONE);
+        verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(),
+                DeployState.DELETED, null, StateChangeResult.NO_ERROR, "Deleted");
+
+        acElementHandler.handleRestartInstance(instanceId, element, Map.of(), DeployState.DEPLOYED, LockState.LOCKING);
+        verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), null,
+                LockState.LOCKED, StateChangeResult.NO_ERROR, "Locked");
+
+        acElementHandler.handleRestartInstance(instanceId, element, Map.of(), DeployState.DEPLOYED,
+                LockState.UNLOCKING);
+        verify(intermediaryApi).updateAutomationCompositionElementState(instanceId, element.getId(), null,
+                LockState.UNLOCKED, StateChangeResult.NO_ERROR, "Unlocked");
+    }
 }
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 48b60dc..2002ba4 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
@@ -24,7 +24,10 @@
 import java.util.Map;
 import java.util.UUID;
 import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
+import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.models.base.PfModelException;
 
 /**
@@ -63,4 +66,11 @@
             throws PfModelException;
 
     void deprime(UUID compositionId) throws PfModelException;
+
+    void handleRestartComposition(UUID compositionId,
+            List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state)
+            throws PfModelException;
+
+    void handleRestartInstance(UUID automationCompositionId, AcElementDeploy element, Map<String, Object> properties,
+            DeployState deployState, LockState lockState) throws PfModelException;
 }
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 c75750c..8b800a8 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
@@ -25,6 +25,7 @@
 import java.util.UUID;
 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.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.StateChangeResult;
@@ -38,23 +39,32 @@
      * Update the state of a automation composition element.
      *
      * @param automationCompositionId the ID of the automation composition to update the state on
-     * @param id the ID of the automation composition element to update the state on
+     * @param elementId the ID of the automation composition element to update the state on
      * @param deployState the Deploy State of the automation composition element
      * @param lockState the Lock State of the automation composition element
      * @param stateChangeResult the indicator if error occurs
      * @param message the message
      */
-    void updateAutomationCompositionElementState(UUID automationCompositionId, UUID id, DeployState deployState,
+    void updateAutomationCompositionElementState(UUID automationCompositionId, UUID elementId, DeployState deployState,
             LockState lockState, StateChangeResult stateChangeResult, String message);
 
     /**
-     * Get AutomationCompositions.
+     * Get a copy of all AutomationCompositions.
      *
      * @return get all AutomationCompositions
      */
     Map<UUID, AutomationComposition> getAutomationCompositions();
 
     /**
+     * Get a copy of the AutomationCompositionElement by automationCompositionId and elementId.
+     *
+     * @param automationCompositionId the ID of the automation composition to update the state on
+     * @param elementId the ID of the automation composition element to update the state on
+     * @return get the AutomationCompositionElement
+     */
+    AutomationCompositionElement getAutomationCompositionElement(UUID automationCompositionId, UUID elementId);
+
+    /**
      * 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 96d96ca..ca5f087 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
@@ -29,6 +29,7 @@
 import org.onap.policy.clamp.acm.participant.intermediary.handler.CacheProvider;
 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.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.StateChangeResult;
@@ -70,4 +71,14 @@
             String message) {
         automationCompositionHandler.updateCompositionState(compositionId, state, stateChangeResult, message);
     }
+
+    @Override
+    public AutomationCompositionElement getAutomationCompositionElement(UUID automationCompositionId, UUID elementId) {
+        var automationComposition = cacheProvider.getAutomationCompositions().get(automationCompositionId);
+        if (automationComposition == null) {
+            return null;
+        }
+        var element = automationComposition.getElements().get(elementId);
+        return element != null ? new AutomationCompositionElement(element) : null;
+    }
 }
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java
index 65ad131..2018d43 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandler.java
@@ -22,6 +22,7 @@
 
 import java.io.Closeable;
 import java.io.IOException;
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
@@ -33,6 +34,7 @@
 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.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.concepts.AcElementRestart;
 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
@@ -272,7 +274,47 @@
      */
     public void restarted(UUID messageId, UUID compositionId, List<AutomationCompositionElementDefinition> list,
             AcTypeState state, List<ParticipantRestartAc> automationCompositionList) {
-        // TODO
+        try {
+            listener.handleRestartComposition(compositionId, list, state);
+        } catch (PfModelException e) {
+            LOGGER.error("Composition Defintion restarted failed {} {}", compositionId, e.getMessage());
+            intermediaryApi.updateCompositionState(compositionId, state, StateChangeResult.FAILED,
+                    "Composition Defintion restarted failed");
+        }
+
+        for (var automationComposition : automationCompositionList) {
+            for (var element : automationComposition.getAcElementList()) {
+                cleanExecution(element.getId(), messageId);
+                var result = executor.submit(() -> this
+                        .restartedInstanceProcess(automationComposition.getAutomationCompositionId(), element));
+                executionMap.put(element.getId(), result);
+            }
+        }
+    }
+
+    private void restartedInstanceProcess(UUID instanceId, AcElementRestart element) {
+        try {
+            var map = new HashMap<>(cacheProvider.getCommonProperties(instanceId, element.getId()));
+            map.putAll(element.getProperties());
+
+            listener.handleRestartInstance(instanceId, getAcElementDeploy(element), map, element.getDeployState(),
+                    element.getLockState());
+            executionMap.remove(element.getId());
+        } catch (PfModelException e) {
+            LOGGER.error("Automation composition element deploy failed {} {}", instanceId, e.getMessage());
+            intermediaryApi.updateAutomationCompositionElementState(instanceId, element.getId(),
+                    element.getDeployState(), element.getLockState(), StateChangeResult.FAILED,
+                    "Automation composition element restart failed");
+        }
+    }
+
+    private AcElementDeploy getAcElementDeploy(AcElementRestart element) {
+        var acElementDeploy = new AcElementDeploy();
+        acElementDeploy.setId(element.getId());
+        acElementDeploy.setDefinition(element.getDefinition());
+        acElementDeploy.setProperties(element.getProperties());
+        acElementDeploy.setToscaServiceTemplateFragment(element.getToscaServiceTemplateFragment());
+        return acElementDeploy;
     }
 
     /**
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java
index fcd8650..acf86f2 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/api/impl/ParticipantIntermediaryApiImplTest.java
@@ -20,6 +20,7 @@
 
 package org.onap.policy.clamp.acm.participant.intermediary.api.impl;
 
+import static org.assertj.core.api.Assertions.assertThat;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -32,6 +33,7 @@
 import org.onap.policy.clamp.acm.participant.intermediary.handler.CacheProvider;
 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.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.StateChangeResult;
@@ -65,11 +67,24 @@
         verify(automationComposiitonHandler).updateAutomationCompositionElementState(automationCompositionId, uuid,
                 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "");
 
-        var map = Map.of(uuid, new AutomationComposition());
+        var map = Map.of(automationCompositionId, new AutomationComposition());
         when(cacheProvider.getAutomationCompositions()).thenReturn(map);
+        var acElement = new AutomationCompositionElement();
+        acElement.setId(uuid);
+        map.get(automationCompositionId).setElements(Map.of(uuid, acElement));
+
         var result = apiImpl.getAutomationCompositions();
         assertEquals(map, result);
 
+        var element = apiImpl.getAutomationCompositionElement(UUID.randomUUID(), UUID.randomUUID());
+        assertThat(element).isNull();
+
+        element = apiImpl.getAutomationCompositionElement(automationCompositionId, UUID.randomUUID());
+        assertThat(element).isNull();
+
+        element = apiImpl.getAutomationCompositionElement(automationCompositionId, uuid);
+        assertEquals(acElement, element);
+
         apiImpl.updateCompositionState(uuid, AcTypeState.PRIMED, StateChangeResult.NO_ERROR, "");
         verify(automationComposiitonHandler).updateCompositionState(uuid, AcTypeState.PRIMED,
                 StateChangeResult.NO_ERROR, "");
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/DummyAcElementListener.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/DummyAcElementListener.java
index 0a724ed..a4994cb 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/DummyAcElementListener.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/DummyAcElementListener.java
@@ -25,7 +25,10 @@
 import java.util.UUID;
 import org.onap.policy.clamp.acm.participant.intermediary.api.AutomationCompositionElementListener;
 import org.onap.policy.clamp.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
+import org.onap.policy.clamp.models.acm.concepts.DeployState;
+import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.models.base.PfModelException;
 
 public class DummyAcElementListener implements AutomationCompositionElementListener {
@@ -36,7 +39,7 @@
 
     @Override
     public void deploy(UUID automationCompositionId, AcElementDeploy element, Map<String, Object> properties)
-        throws PfModelException {
+            throws PfModelException {
 
     }
 
@@ -65,4 +68,15 @@
     @Override
     public void deprime(UUID compositionId) throws PfModelException {
     }
+
+    @Override
+    public void handleRestartComposition(UUID compositionId,
+            List<AutomationCompositionElementDefinition> elementDefinitionList, AcTypeState state)
+            throws PfModelException {
+    }
+
+    @Override
+    public void handleRestartInstance(UUID automationCompositionId, AcElementDeploy element,
+            Map<String, Object> properties, DeployState deployState, LockState lockState) throws PfModelException {
+    }
 }
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java
index 55d84c5..2776ed8 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ThreadHandlerTest.java
@@ -20,6 +20,7 @@
 
 package org.onap.policy.clamp.acm.participant.intermediary.handler;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
@@ -35,10 +36,12 @@
 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.models.acm.concepts.AcElementDeploy;
+import org.onap.policy.clamp.models.acm.concepts.AcElementRestart;
 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc;
 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
 import org.onap.policy.models.base.PfModelException;
 
@@ -164,6 +167,30 @@
             threadHandler.deprime(messageId, compositionId);
             verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.PRIMED,
                     StateChangeResult.FAILED, "Composition Defintion deprime failed");
+
+            clearInvocations(listener);
+            doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener)
+                    .handleRestartComposition(compositionId, List.of(), AcTypeState.PRIMING);
+            threadHandler.restarted(messageId, compositionId, List.of(), AcTypeState.PRIMING, List.of());
+            verify(intermediaryApi).updateCompositionState(compositionId, AcTypeState.PRIMED, StateChangeResult.FAILED,
+                    "Composition Defintion deprime failed");
+        }
+    }
+
+    @Test
+    void testRestarted() throws IOException, PfModelException {
+        var listener = mock(AutomationCompositionElementListener.class);
+        var intermediaryApi = mock(ParticipantIntermediaryApi.class);
+        var cacheProvider = mock(CacheProvider.class);
+        try (var threadHandler = new ThreadHandler(listener, intermediaryApi, cacheProvider)) {
+            var messageId = UUID.randomUUID();
+            var compositionId = UUID.randomUUID();
+            var participantRestartAc = new ParticipantRestartAc();
+            participantRestartAc.setAutomationCompositionId(UUID.randomUUID());
+            participantRestartAc.getAcElementList().add(new AcElementRestart());
+            threadHandler.restarted(messageId, compositionId, List.of(new AutomationCompositionElementDefinition()),
+                    AcTypeState.PRIMED, List.of(participantRestartAc));
+            verify(listener, timeout(TIMEOUT)).handleRestartInstance(any(), any(), any(), any(), any());
         }
     }
 }