Add support participant restart scenario in ACM intermediary

Issue-ID: POLICY-4745
Change-Id: I8ab71137ef981cb4fdeae4bf9732382b9534b442
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
(cherry picked from commit 51ef04415186a0de3e50339b7fca04fb5ef079c9)
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRestartListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRestartListener.java
new file mode 100644
index 0000000..7fc9c27
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantRestartListener.java
@@ -0,0 +1,44 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2023 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.acm.participant.intermediary.comm;
+
+import org.onap.policy.clamp.acm.participant.intermediary.handler.ParticipantHandler;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRestart;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ParticipantRestartListener extends ParticipantListener<ParticipantRestart> {
+
+    /**
+     * Constructs the object.
+     *
+     * @param participantHandler the handler for managing the state of the participant
+     */
+    public ParticipantRestartListener(ParticipantHandler participantHandler) {
+        super(ParticipantRestart.class, participantHandler, participantHandler::handleParticipantRestart);
+    }
+
+    @Override
+    public String getType() {
+        return ParticipantMessageType.PARTICIPANT_RESTART.name();
+    }
+}
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 71c9d9a..b4735f1 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
@@ -26,9 +26,11 @@
 import java.util.UUID;
 import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher;
 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.AutomationComposition;
 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElementDefinition;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantDeploy;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantUtils;
 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionDeploy;
@@ -334,4 +336,22 @@
     public void deprime(UUID messageId, UUID compositionId) {
         listener.deprime(messageId, compositionId);
     }
+
+    /**
+     * Handles restarted scenario.
+     *
+     * @param messageId the messageId
+     * @param compositionId the compositionId
+     * @param list the list of AutomationCompositionElementDefinition
+     * @param state the state of the composition
+     * @param automationCompositionList list of ParticipantRestartAc
+     */
+    public void restarted(UUID messageId, UUID compositionId, List<AutomationCompositionElementDefinition> list,
+            AcTypeState state, List<ParticipantRestartAc> automationCompositionList) {
+
+        for (var automationcomposition : automationCompositionList) {
+            cacheProvider.initializeAutomationComposition(compositionId, automationcomposition);
+        }
+        listener.restarted(messageId, compositionId, list, state, automationCompositionList);
+    }
 }
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java
index cfd61c4..334d6a8 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionOutHandler.java
@@ -69,11 +69,6 @@
             return;
         }
 
-        if ((deployState != null && lockState != null) || (deployState == null && lockState == null)) {
-            LOGGER.error("state error {} and {} cannot be handled", deployState, lockState);
-            return;
-        }
-
         var automationComposition = cacheProvider.getAutomationComposition(automationCompositionId);
         if (automationComposition == null) {
             LOGGER.error("Cannot update Automation composition element state, Automation composition id {} not present",
@@ -88,6 +83,13 @@
             return;
         }
 
+        if ((element.getRestarting() != null)
+                && ((deployState != null && lockState != null) || (deployState == null && lockState == null))) {
+            LOGGER.error("state error {} and {} cannot be handled", deployState, lockState);
+            return;
+        }
+        element.setRestarting(null);
+
         if (deployState != null) {
             handleDeployState(automationComposition, element, deployState);
         }
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java
index 119cc11..08d5ccd 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProvider.java
@@ -35,6 +35,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.ParticipantDeploy;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType;
 import org.onap.policy.models.base.PfUtils;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
@@ -150,4 +151,32 @@
         automationComposition.setElements(acElementMap);
         automationCompositions.put(automationComposition.getInstanceId(), automationComposition);
     }
+
+    /**
+     * Initialize an AutomationComposition from a ParticipantRestartAc.
+     *
+     * @param compositionId the composition Id
+     * @param participantRestartAc the ParticipantRestartAc
+     */
+    public void initializeAutomationComposition(@NonNull UUID compositionId,
+            ParticipantRestartAc participantRestartAc) {
+        Map<UUID, AutomationCompositionElement> acElementMap = new LinkedHashMap<>();
+        for (var element : participantRestartAc.getAcElementList()) {
+            var acElement = new AutomationCompositionElement();
+            acElement.setId(element.getId());
+            acElement.setParticipantId(getParticipantId());
+            acElement.setDefinition(element.getDefinition());
+            acElement.setDeployState(element.getDeployState());
+            acElement.setLockState(element.getLockState());
+            acElement.setProperties(element.getProperties());
+            acElement.setRestarting(true);
+            acElementMap.put(element.getId(), acElement);
+        }
+
+        var automationComposition = new AutomationComposition();
+        automationComposition.setCompositionId(compositionId);
+        automationComposition.setInstanceId(participantRestartAc.getAutomationCompositionId());
+        automationComposition.setElements(acElementMap);
+        automationCompositions.put(automationComposition.getInstanceId(), automationComposition);
+    }
 }
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java
index 3a3a0cc..c78c7bb 100644
--- a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandler.java
@@ -27,6 +27,7 @@
 import java.util.List;
 import lombok.RequiredArgsConstructor;
 import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher;
+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.AutomationCompositionInfo;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
@@ -40,6 +41,7 @@
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantPrime;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegister;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegisterAck;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRestart;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatusReq;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.PropertiesUpdate;
@@ -197,6 +199,27 @@
     }
 
     /**
+     * Handle a ParticipantRestart message.
+     *
+     * @param participantRestartMsg the participantRestart message
+     */
+    @Timed(value = "listener.participant_restart", description = "PARTICIPANT_RESTART messages received")
+    public void handleParticipantRestart(ParticipantRestart participantRestartMsg) {
+        LOGGER.debug("ParticipantRestart message received for participantId {}",
+                participantRestartMsg.getParticipantId());
+        List<AutomationCompositionElementDefinition> list = new ArrayList<>();
+        for (var participantDefinition : participantRestartMsg.getParticipantDefinitionUpdates()) {
+            list.addAll(participantDefinition.getAutomationCompositionElementDefinitionList());
+        }
+        if (!AcTypeState.COMMISSIONED.equals(participantRestartMsg.getState())) {
+            cacheProvider.addElementDefinition(participantRestartMsg.getCompositionId(), list);
+        }
+        automationCompositionHandler.restarted(participantRestartMsg.getMessageId(),
+                participantRestartMsg.getCompositionId(), list, participantRestartMsg.getState(),
+                participantRestartMsg.getAutomationcompositionList());
+    }
+
+    /**
      * Dispatch a heartbeat for this participant.
      */
     public void sendHeartbeat() {
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 b5866d7..65ad131 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
@@ -37,6 +37,7 @@
 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;
 import org.slf4j.Logger;
@@ -260,6 +261,19 @@
         }
     }
 
+    /**
+     * Handles restarted scenario.
+     *
+     * @param messageId the messageId
+     * @param compositionId the compositionId
+     * @param list the list of AutomationCompositionElementDefinition
+     * @param state the state of the composition
+     * @param automationCompositionList list of ParticipantRestartAc
+     */
+    public void restarted(UUID messageId, UUID compositionId, List<AutomationCompositionElementDefinition> list,
+            AcTypeState state, List<ParticipantRestartAc> automationCompositionList) {
+        // TODO
+    }
 
     /**
      * Closes this stream and releases any system resources associated
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 4213e97..fcd8650 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,13 +20,18 @@
 
 package org.onap.policy.clamp.acm.participant.intermediary.api.impl;
 
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import java.util.Map;
 import java.util.UUID;
 import org.junit.jupiter.api.Test;
 import org.onap.policy.clamp.acm.participant.intermediary.handler.AutomationCompositionOutHandler;
+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.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.clamp.models.acm.concepts.StateChangeResult;
@@ -41,7 +46,8 @@
     @Test
     void mockParticipantIntermediaryApiImplTest() throws CoderException {
         var automationComposiitonHandler = mock(AutomationCompositionOutHandler.class);
-        var apiImpl = new ParticipantIntermediaryApiImpl(automationComposiitonHandler, null);
+        var cacheProvider = mock(CacheProvider.class);
+        var apiImpl = new ParticipantIntermediaryApiImpl(automationComposiitonHandler, cacheProvider);
 
         var uuid = UUID.randomUUID();
         var automationCompositionId = UUID.randomUUID();
@@ -58,5 +64,14 @@
                 StateChangeResult.NO_ERROR, "");
         verify(automationComposiitonHandler).updateAutomationCompositionElementState(automationCompositionId, uuid,
                 DeployState.DEPLOYED, null, StateChangeResult.NO_ERROR, "");
+
+        var map = Map.of(uuid, new AutomationComposition());
+        when(cacheProvider.getAutomationCompositions()).thenReturn(map);
+        var result = apiImpl.getAutomationCompositions();
+        assertEquals(map, result);
+
+        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/comm/ParticipantCommTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantCommTest.java
index 1dbf0b1..db6a3a5 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantCommTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/comm/ParticipantCommTest.java
@@ -38,21 +38,27 @@
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantPrimeAck;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegister;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegisterAck;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatusReq;
 import org.onap.policy.common.endpoints.event.comm.TopicSink;
 import org.onap.policy.common.utils.coder.CoderException;
 
 class ParticipantCommTest {
 
     @Test
-    void participantReqTest() throws CoderException {
+    void participantListenerTest() throws CoderException {
         var participantHandler = mock(ParticipantHandler.class);
 
         var participantRegisterAckListener = new ParticipantRegisterAckListener(participantHandler);
+        participantRegisterAckListener.onTopicEvent(null, null, null, new ParticipantRegisterAck());
         assertEquals(ParticipantMessageType.PARTICIPANT_REGISTER_ACK.name(), participantRegisterAckListener.getType());
+        assertEquals(participantRegisterAckListener, participantRegisterAckListener.getScoListener());
 
         var participantStatusReqListener = new ParticipantStatusReqListener(participantHandler);
+        participantStatusReqListener.onTopicEvent(null, null, null, new ParticipantStatusReq());
         assertEquals(ParticipantMessageType.PARTICIPANT_STATUS_REQ.name(), participantStatusReqListener.getType());
+        assertEquals(participantStatusReqListener, participantStatusReqListener.getScoListener());
 
         var participantDeregisterAckListener = new ParticipantDeregisterAckListener(participantHandler);
         assertEquals(ParticipantMessageType.PARTICIPANT_DEREGISTER_ACK.name(),
@@ -71,6 +77,10 @@
         var automationCompositionStateChangeListener = new AutomationCompositionStateChangeListener(participantHandler);
         assertEquals(ParticipantMessageType.AUTOMATION_COMPOSITION_STATE_CHANGE.name(),
                 automationCompositionStateChangeListener.getType());
+
+        var participantRestartListener = new ParticipantRestartListener(participantHandler);
+        assertEquals(ParticipantMessageType.PARTICIPANT_RESTART.name(),
+                participantRestartListener.getType());
     }
 
     @Test
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java
index dd49ee3..6509491 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/AutomationCompositionHandlerTest.java
@@ -35,6 +35,7 @@
 import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher;
 import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData;
 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.ParticipantDeploy;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionDeploy;
@@ -220,4 +221,22 @@
         ach.deprime(messageId, compositionId);
         verify(listener).deprime(messageId, compositionId);
     }
+
+    @Test
+    void restartedTest() {
+        var listener = mock(ThreadHandler.class);
+        var cacheProvider = mock(CacheProvider.class);
+        var ach = new AutomationCompositionHandler(cacheProvider, mock(ParticipantMessagePublisher.class),
+                listener);
+
+        var compositionId = UUID.randomUUID();
+        var messageId = UUID.randomUUID();
+        var list = List.of(new AutomationCompositionElementDefinition());
+        var state = AcTypeState.PRIMED;
+        var participantRestartAc = CommonTestData.createParticipantRestartAc();
+        var automationCompositionList = List.of(participantRestartAc);
+        ach.restarted(messageId, compositionId, list, state, automationCompositionList);
+        verify(cacheProvider).initializeAutomationComposition(compositionId, participantRestartAc);
+        verify(listener).restarted(messageId, compositionId, list, state, automationCompositionList);
+    }
 }
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java
index bbce423..f207dc5 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/CacheProviderTest.java
@@ -75,6 +75,9 @@
                 .isInstanceOf(NullPointerException.class);
 
         assertThatThrownBy(() -> cacheProvider.removeElementDefinition(null)).isInstanceOf(NullPointerException.class);
+
+        assertThatThrownBy(() -> cacheProvider.initializeAutomationComposition(null, null))
+                .isInstanceOf(NullPointerException.class);
     }
 
     @Test
@@ -125,4 +128,17 @@
         cacheProvider.removeElementDefinition(compositionId);
         assertThat(cacheProvider.getAcElementsDefinitions()).isEmpty();
     }
+
+    @Test
+    void testInitializeAutomationComposition() {
+        var parameter = CommonTestData.getParticipantParameters();
+        var cacheProvider = new CacheProvider(parameter);
+
+        var participantRestartAc = CommonTestData.createParticipantRestartAc();
+        var compositionId = UUID.randomUUID();
+        cacheProvider.initializeAutomationComposition(compositionId, participantRestartAc);
+        var result = cacheProvider.getAutomationComposition(participantRestartAc.getAutomationCompositionId());
+        assertEquals(compositionId, result.getCompositionId());
+        assertEquals(participantRestartAc.getAutomationCompositionId(), result.getInstanceId());
+    }
 }
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java
index 237cab2..68cffe3 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/handler/ParticipantHandlerTest.java
@@ -33,6 +33,7 @@
 import org.junit.jupiter.api.Test;
 import org.onap.policy.clamp.acm.participant.intermediary.comm.ParticipantMessagePublisher;
 import org.onap.policy.clamp.acm.participant.intermediary.main.parameters.CommonTestData;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantDefinition;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionDeploy;
@@ -45,6 +46,7 @@
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantPrime;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegister;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegisterAck;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRestart;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatusReq;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.PropertiesUpdate;
@@ -175,6 +177,24 @@
     }
 
     @Test
+    void handleParticipantRestartTest() {
+        var participantRestartMsg = new ParticipantRestart();
+        participantRestartMsg.setState(AcTypeState.PRIMED);
+        participantRestartMsg.setCompositionId(UUID.randomUUID());
+        participantRestartMsg.getParticipantDefinitionUpdates().add(new ParticipantDefinition());
+
+        var cacheProvider = mock(CacheProvider.class);
+        var publisher = mock(ParticipantMessagePublisher.class);
+        var acHandler = mock(AutomationCompositionHandler.class);
+        var participantHandler = new ParticipantHandler(acHandler, mock(AutomationCompositionOutHandler.class),
+                publisher, cacheProvider);
+
+        participantHandler.handleParticipantRestart(participantRestartMsg);
+        verify(cacheProvider).addElementDefinition(any(), any());
+        verify(acHandler).restarted(any(), any(), any(), any(), any());
+    }
+
+    @Test
     void handleParticipantDeprimeTest() {
         var cacheProvider = mock(CacheProvider.class);
         when(cacheProvider.getParticipantId()).thenReturn(CommonTestData.getParticipantId());
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 767a916..55d84c5 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
@@ -26,6 +26,7 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
@@ -46,115 +47,123 @@
     private static final int TIMEOUT = 400;
 
     @Test
-    void test() throws PfModelException {
+    void test() throws PfModelException, IOException {
         var listener = mock(AutomationCompositionElementListener.class);
         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
-        var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class));
+        try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
 
-        var compositionId = UUID.randomUUID();
-        var list = List.of(new AutomationCompositionElementDefinition());
-        var messageId = UUID.randomUUID();
-        threadHandler.prime(messageId, compositionId, list);
-        verify(listener, timeout(TIMEOUT)).prime(compositionId, list);
+            var compositionId = UUID.randomUUID();
+            var list = List.of(new AutomationCompositionElementDefinition());
+            var messageId = UUID.randomUUID();
+            threadHandler.prime(messageId, compositionId, list);
+            verify(listener, timeout(TIMEOUT)).prime(compositionId, list);
 
-        clearInvocations(listener);
-        var element = new AcElementDeploy();
-        var elementId = UUID.randomUUID();
-        element.setId(elementId);
-        Map<String, Object> properties = Map.of("key", "value");
-        var instanceId = UUID.randomUUID();
-        threadHandler.deploy(messageId, instanceId, element, properties);
-        verify(listener, timeout(TIMEOUT)).deploy(instanceId, element, properties);
+            clearInvocations(listener);
+            var element = new AcElementDeploy();
+            var elementId = UUID.randomUUID();
+            element.setId(elementId);
+            Map<String, Object> properties = Map.of("key", "value");
+            var instanceId = UUID.randomUUID();
+            threadHandler.deploy(messageId, instanceId, element, properties);
+            verify(listener, timeout(TIMEOUT)).deploy(instanceId, element, properties);
 
-        clearInvocations(listener);
-        threadHandler.update(messageId, instanceId, element, properties);
-        verify(listener, timeout(TIMEOUT)).update(instanceId, element, properties);
+            clearInvocations(listener);
+            threadHandler.update(messageId, instanceId, element, properties);
+            verify(listener, timeout(TIMEOUT)).update(instanceId, element, properties);
 
-        clearInvocations(listener);
-        threadHandler.lock(messageId, instanceId, elementId);
-        verify(listener, timeout(TIMEOUT)).lock(instanceId, elementId);
+            clearInvocations(listener);
+            threadHandler.lock(messageId, instanceId, elementId);
+            verify(listener, timeout(TIMEOUT)).lock(instanceId, elementId);
 
-        clearInvocations(listener);
-        threadHandler.unlock(messageId, instanceId, elementId);
-        verify(listener, timeout(TIMEOUT)).unlock(instanceId, elementId);
+            clearInvocations(listener);
+            threadHandler.unlock(messageId, instanceId, elementId);
+            verify(listener, timeout(TIMEOUT)).unlock(instanceId, elementId);
 
-        clearInvocations(listener);
-        threadHandler.undeploy(messageId, instanceId, elementId);
-        verify(listener, timeout(TIMEOUT)).undeploy(instanceId, elementId);
+            clearInvocations(listener);
+            threadHandler.undeploy(messageId, instanceId, elementId);
+            verify(listener, timeout(TIMEOUT)).undeploy(instanceId, elementId);
 
-        clearInvocations(listener);
-        threadHandler.delete(messageId, instanceId, elementId);
-        verify(listener, timeout(TIMEOUT)).delete(instanceId, elementId);
+            clearInvocations(listener);
+            threadHandler.delete(messageId, instanceId, elementId);
+            verify(listener, timeout(TIMEOUT)).delete(instanceId, elementId);
 
-        clearInvocations(listener);
-        threadHandler.deprime(messageId, compositionId);
-        verify(listener, timeout(TIMEOUT)).deprime(compositionId);
+            clearInvocations(listener);
+            threadHandler.deprime(messageId, compositionId);
+            verify(listener, timeout(TIMEOUT)).deprime(compositionId);
+        }
     }
 
     @Test
-    void testException() throws PfModelException {
+    void testException() throws PfModelException, IOException {
         var listener = mock(AutomationCompositionElementListener.class);
         var intermediaryApi = mock(ParticipantIntermediaryApi.class);
-        var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class));
+        try (var threadHandler = new ThreadHandler(listener, intermediaryApi, mock(CacheProvider.class))) {
 
-        var compositionId = UUID.randomUUID();
-        var list = List.of(new AutomationCompositionElementDefinition());
-        doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).prime(compositionId, list);
-        var messageId = UUID.randomUUID();
-        threadHandler.prime(messageId, compositionId, list);
-        verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.COMMISSIONED,
-                StateChangeResult.FAILED, "Composition Defintion prime failed");
+            var compositionId = UUID.randomUUID();
+            var list = List.of(new AutomationCompositionElementDefinition());
+            doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).prime(compositionId,
+                    list);
+            var messageId = UUID.randomUUID();
+            threadHandler.prime(messageId, compositionId, list);
+            verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.COMMISSIONED,
+                    StateChangeResult.FAILED, "Composition Defintion prime failed");
 
-        clearInvocations(intermediaryApi);
-        var element = new AcElementDeploy();
-        var elementId = UUID.randomUUID();
-        element.setId(elementId);
-        Map<String, Object> properties = Map.of("key", "value");
-        var instanceId = UUID.randomUUID();
-        doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).deploy(instanceId, element,
-                properties);
-        threadHandler.deploy(messageId, instanceId, element, properties);
-        verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
-                DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Automation composition element deploy failed");
+            clearInvocations(intermediaryApi);
+            var element = new AcElementDeploy();
+            var elementId = UUID.randomUUID();
+            element.setId(elementId);
+            Map<String, Object> properties = Map.of("key", "value");
+            var instanceId = UUID.randomUUID();
+            doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).deploy(instanceId,
+                    element, properties);
+            threadHandler.deploy(messageId, instanceId, element, properties);
+            verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
+                    DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
+                    "Automation composition element deploy failed");
 
-        clearInvocations(listener);
-        doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).update(instanceId, element,
-                properties);
-        threadHandler.update(messageId, instanceId, element, properties);
-        verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
-                DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Automation composition element update failed");
+            clearInvocations(listener);
+            doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).update(instanceId,
+                    element, properties);
+            threadHandler.update(messageId, instanceId, element, properties);
+            verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
+                    DeployState.DEPLOYED, null, StateChangeResult.FAILED,
+                    "Automation composition element update failed");
 
-        clearInvocations(listener);
-        doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).lock(instanceId, elementId);
-        threadHandler.lock(messageId, instanceId, elementId);
-        verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, null,
-                LockState.UNLOCKED, StateChangeResult.FAILED, "Automation composition element lock failed");
+            clearInvocations(listener);
+            doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).lock(instanceId,
+                    elementId);
+            threadHandler.lock(messageId, instanceId, elementId);
+            verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
+                    null, LockState.UNLOCKED, StateChangeResult.FAILED, "Automation composition element lock failed");
 
-        clearInvocations(listener);
-        doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).unlock(instanceId,
-                elementId);
-        threadHandler.unlock(messageId, instanceId, elementId);
-        verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId, null,
-                LockState.LOCKED, StateChangeResult.FAILED, "Automation composition element unlock failed");
+            clearInvocations(listener);
+            doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).unlock(instanceId,
+                    elementId);
+            threadHandler.unlock(messageId, instanceId, elementId);
+            verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
+                    null, LockState.LOCKED, StateChangeResult.FAILED, "Automation composition element unlock failed");
 
-        clearInvocations(listener);
-        doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).undeploy(instanceId,
-                elementId);
-        threadHandler.undeploy(messageId, instanceId, elementId);
-        verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
-                DeployState.DEPLOYED, null, StateChangeResult.FAILED, "Automation composition element undeploy failed");
+            clearInvocations(listener);
+            doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).undeploy(instanceId,
+                    elementId);
+            threadHandler.undeploy(messageId, instanceId, elementId);
+            verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
+                    DeployState.DEPLOYED, null, StateChangeResult.FAILED,
+                    "Automation composition element undeploy failed");
 
-        clearInvocations(listener);
-        doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).delete(instanceId,
-                elementId);
-        threadHandler.delete(messageId, instanceId, elementId);
-        verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
-                DeployState.UNDEPLOYED, null, StateChangeResult.FAILED, "Automation composition element delete failed");
+            clearInvocations(listener);
+            doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).delete(instanceId,
+                    elementId);
+            threadHandler.delete(messageId, instanceId, elementId);
+            verify(intermediaryApi, timeout(TIMEOUT)).updateAutomationCompositionElementState(instanceId, elementId,
+                    DeployState.UNDEPLOYED, null, StateChangeResult.FAILED,
+                    "Automation composition element delete failed");
 
-        clearInvocations(listener);
-        doThrow(new PfModelException(Status.INTERNAL_SERVER_ERROR, "Error")).when(listener).deprime(compositionId);
-        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).deprime(compositionId);
+            threadHandler.deprime(messageId, compositionId);
+            verify(intermediaryApi, timeout(TIMEOUT)).updateCompositionState(compositionId, AcTypeState.PRIMED,
+                    StateChangeResult.FAILED, "Composition Defintion deprime failed");
+        }
     }
 }
diff --git a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java
index cc2bd70..acff103 100644
--- a/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java
+++ b/participant/participant-intermediary/src/test/java/org/onap/policy/clamp/acm/participant/intermediary/main/parameters/CommonTestData.java
@@ -29,8 +29,12 @@
 import java.util.UUID;
 import org.onap.policy.clamp.acm.participant.intermediary.handler.DummyParticipantParameters;
 import org.onap.policy.clamp.acm.participant.intermediary.parameters.ParticipantIntermediaryParameters;
+import org.onap.policy.clamp.models.acm.concepts.AcElementRestart;
 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.concepts.LockState;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantRestartAc;
 import org.onap.policy.clamp.models.acm.concepts.ParticipantSupportedElementType;
 import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionStateChange;
 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
@@ -215,4 +219,21 @@
         stateChange.setTimestamp(Instant.ofEpochMilli(3000));
         return stateChange;
     }
+
+    /**
+     * Create a ParticipantRestartAc.
+     *
+     * @return a ParticipantRestartAc
+     */
+    public static ParticipantRestartAc createParticipantRestartAc() {
+        var participantRestartAc = new ParticipantRestartAc();
+        participantRestartAc.setAutomationCompositionId(AC_ID_0);
+        var acElementRestart = new AcElementRestart();
+        acElementRestart.setDefinition(getDefinition());
+        acElementRestart.setDeployState(DeployState.DEPLOYED);
+        acElementRestart.setLockState(LockState.LOCKED);
+        acElementRestart.setId(UUID.randomUUID());
+        participantRestartAc.getAcElementList().add(acElementRestart);
+        return participantRestartAc;
+    }
 }