Register participant in ParticipantRegister message 02/124602/2
authorFrancescoFioraEst <francesco.fiora@est.tech>
Wed, 29 Sep 2021 13:11:40 +0000 (14:11 +0100)
committerFrancescoFioraEst <francesco.fiora@est.tech>
Mon, 4 Oct 2021 10:50:19 +0000 (11:50 +0100)
Issue-ID: POLICY-3688
Change-Id: I7ac14dace8e936ac4329b55866bfbf8b7c45da63
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java
runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandlerTest.java [new file with mode: 0644]

index 2029263..a031cfa 100644 (file)
@@ -41,6 +41,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessage;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck;
@@ -145,7 +146,11 @@ public class SupervisionHandler {
      */
     public void handleParticipantMessage(ParticipantRegister participantRegisterMessage) {
         LOGGER.debug("Participant Register received {}", participantRegisterMessage);
-
+        try {
+            checkParticipant(participantRegisterMessage, ParticipantState.UNKNOWN, ParticipantHealthStatus.UNKNOWN);
+        } catch (PfModelException | ControlLoopException svExc) {
+            LOGGER.warn("error saving participant {}", participantRegisterMessage.getParticipantId(), svExc);
+        }
         participantRegisterAckPublisher.send(participantRegisterMessage.getMessageId(),
                 participantRegisterMessage.getParticipantId(), participantRegisterMessage.getParticipantType());
     }
@@ -160,8 +165,8 @@ public class SupervisionHandler {
         LOGGER.debug("Participant Deregister received {}", participantDeregisterMessage);
         try {
             var participantList =
-                participantProvider.getParticipants(participantDeregisterMessage.getParticipantId().getName(),
-                    participantDeregisterMessage.getParticipantId().getVersion());
+                    participantProvider.getParticipants(participantDeregisterMessage.getParticipantId().getName(),
+                            participantDeregisterMessage.getParticipantId().getVersion());
 
             if (participantList != null) {
                 for (Participant participant : participantList) {
@@ -171,7 +176,8 @@ public class SupervisionHandler {
                 participantProvider.updateParticipants(participantList);
             }
         } catch (PfModelException pfme) {
-            LOGGER.warn("Model exception occured {}", participantDeregisterMessage.getParticipantId());
+            LOGGER.warn("Model exception occured with participant id {}",
+                    participantDeregisterMessage.getParticipantId());
         }
 
         participantDeregisterAckPublisher.send(participantDeregisterMessage.getMessageId());
@@ -187,8 +193,8 @@ public class SupervisionHandler {
         LOGGER.debug("Participant Update Ack received {}", participantUpdateAckMessage);
         try {
             var participantList =
-                participantProvider.getParticipants(participantUpdateAckMessage.getParticipantId().getName(),
-                    participantUpdateAckMessage.getParticipantId().getVersion());
+                    participantProvider.getParticipants(participantUpdateAckMessage.getParticipantId().getName(),
+                            participantUpdateAckMessage.getParticipantId().getVersion());
 
             if (participantList != null) {
                 for (Participant participant : participantList) {
@@ -199,7 +205,8 @@ public class SupervisionHandler {
                 LOGGER.warn("Participant not found in database {}", participantUpdateAckMessage.getParticipantId());
             }
         } catch (PfModelException pfme) {
-            LOGGER.warn("Model exception occured {}", participantUpdateAckMessage.getParticipantId());
+            LOGGER.warn("Model exception occured with participant id {}",
+                    participantUpdateAckMessage.getParticipantId());
         }
     }
 
@@ -248,9 +255,8 @@ public class SupervisionHandler {
             try {
                 var controlLoop = controlLoopProvider.getControlLoop(controlLoopAckMessage.getControlLoopId());
                 if (controlLoop != null) {
-                    var updated = updateState(controlLoop, controlLoopAckMessage
-                                    .getControlLoopResultMap().entrySet())
-                                    || setPrimed(controlLoop);
+                    var updated = updateState(controlLoop, controlLoopAckMessage.getControlLoopResultMap().entrySet());
+                    updated |= setPrimed(controlLoop);
                     if (updated) {
                         controlLoopProvider.updateControlLoop(controlLoop);
                     }
@@ -258,13 +264,13 @@ public class SupervisionHandler {
                     LOGGER.warn("ControlLoop not found in database {}", controlLoopAckMessage.getControlLoopId());
                 }
             } catch (PfModelException pfme) {
-                LOGGER.warn("Model exception occured {}", controlLoopAckMessage.getControlLoopId());
+                LOGGER.warn("Model exception occured with ControlLoop Id {}", controlLoopAckMessage.getControlLoopId());
             }
         }
     }
 
-    private boolean updateState(ControlLoop controlLoop, Set<Map.Entry<UUID, ControlLoopElementAck>>
-            controlLoopResultSet) {
+    private boolean updateState(ControlLoop controlLoop,
+            Set<Map.Entry<UUID, ControlLoopElementAck>> controlLoopResultSet) {
         var updated = false;
         for (var clElementAck : controlLoopResultSet) {
             var element = controlLoop.getElements().get(clElementAck.getKey());
@@ -281,8 +287,9 @@ public class SupervisionHandler {
         if (clElements != null) {
             Boolean primedFlag = true;
             var checkOpt = controlLoop.getElements().values().stream()
-                            .filter(clElement -> (!clElement.getState().equals(ControlLoopState.PASSIVE)
-                                    || !clElement.getState().equals(ControlLoopState.RUNNING))).findAny();
+                    .filter(clElement -> (!clElement.getState().equals(ControlLoopState.PASSIVE)
+                            || !clElement.getState().equals(ControlLoopState.RUNNING)))
+                    .findAny();
             if (checkOpt.isEmpty()) {
                 primedFlag = false;
             }
@@ -351,8 +358,7 @@ public class SupervisionHandler {
         }
     }
 
-    private void superviseControlLoopPassivation(ControlLoop controlLoop)
-            throws ControlLoopException {
+    private void superviseControlLoopPassivation(ControlLoop controlLoop) throws ControlLoopException {
         switch (controlLoop.getState()) {
             case PASSIVE:
                 exceptionOccured(Response.Status.NOT_ACCEPTABLE,
@@ -405,34 +411,39 @@ public class SupervisionHandler {
         }
     }
 
-    private void superviseParticipant(ParticipantStatus participantStatusMessage)
-            throws PfModelException, ControlLoopException {
-        if (participantStatusMessage.getParticipantId() == null) {
+    private void checkParticipant(ParticipantMessage participantMessage, ParticipantState participantState,
+            ParticipantHealthStatus healthStatus) throws ControlLoopException, PfModelException {
+        if (participantMessage.getParticipantId() == null) {
             exceptionOccured(Response.Status.NOT_FOUND, "Participant ID on PARTICIPANT_STATUS message is null");
         }
-
-        List<Participant> participantList =
-                participantProvider.getParticipants(participantStatusMessage.getParticipantId().getName(),
-                        participantStatusMessage.getParticipantId().getVersion());
+        List<Participant> participantList = participantProvider.getParticipants(
+                participantMessage.getParticipantId().getName(), participantMessage.getParticipantId().getVersion());
 
         if (CollectionUtils.isEmpty(participantList)) {
             var participant = new Participant();
-            participant.setName(participantStatusMessage.getParticipantId().getName());
-            participant.setVersion(participantStatusMessage.getParticipantId().getVersion());
-            participant.setDefinition(participantStatusMessage.getParticipantId());
-            participant.setParticipantType(participantStatusMessage.getParticipantType());
-            participant.setParticipantState(participantStatusMessage.getState());
-            participant.setHealthStatus(participantStatusMessage.getHealthStatus());
+            participant.setName(participantMessage.getParticipantId().getName());
+            participant.setVersion(participantMessage.getParticipantId().getVersion());
+            participant.setDefinition(participantMessage.getParticipantId());
+            participant.setParticipantType(participantMessage.getParticipantType());
+            participant.setParticipantState(participantState);
+            participant.setHealthStatus(healthStatus);
 
             participantList.add(participant);
             participantProvider.createParticipants(participantList);
         } else {
             for (Participant participant : participantList) {
-                participant.setParticipantState(participantStatusMessage.getState());
-                participant.setHealthStatus(participantStatusMessage.getHealthStatus());
+                participant.setParticipantState(participantState);
+                participant.setHealthStatus(healthStatus);
             }
             participantProvider.updateParticipants(participantList);
         }
+    }
+
+    private void superviseParticipant(ParticipantStatus participantStatusMessage)
+            throws PfModelException, ControlLoopException {
+
+        checkParticipant(participantStatusMessage, participantStatusMessage.getState(),
+                participantStatusMessage.getHealthStatus());
 
         monitoringProvider.createParticipantStatistics(List.of(participantStatusMessage.getParticipantStatistics()));
     }
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandlerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandlerTest.java
new file mode 100644 (file)
index 0000000..25ce611
--- /dev/null
@@ -0,0 +1,270 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 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.controlloop.runtime.supervision;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.anyMap;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantHealthStatus;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics;
+import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
+import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck;
+import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
+import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopStateChangePublisher;
+import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ControlLoopUpdatePublisher;
+import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantDeregisterAckPublisher;
+import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantRegisterAckPublisher;
+import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+class SupervisionHandlerTest {
+    private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
+    private static final ToscaConceptIdentifier identifier = new ToscaConceptIdentifier("PMSHInstance0Crud", "1.0.1");
+    private static final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("ParticipantId", "1.0.0");
+    private static final ToscaConceptIdentifier participantType =
+            new ToscaConceptIdentifier("ParticipantType", "1.0.0");
+
+    @Test
+    void testTriggerControlLoopSupervisionEmpty() throws ControlLoopException, PfModelException, CoderException {
+        var handler = createSupervisionHandler(mock(ControlLoopProvider.class), mock(ParticipantProvider.class),
+                mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+                mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
+                mock(ParticipantUpdatePublisher.class));
+
+        assertThatThrownBy(() -> handler.triggerControlLoopSupervision(List.of()))
+                .hasMessageMatching("The list of control loops for supervision is empty");
+    }
+
+    @Test
+    void testTriggerControlLoopSupervision() throws ControlLoopException, PfModelException, CoderException {
+        var controlLoopProvider = mock(ControlLoopProvider.class);
+        var controlLoopUpdatePublisher = mock(ControlLoopUpdatePublisher.class);
+        var handler = createSupervisionHandler(controlLoopProvider, mock(ParticipantProvider.class),
+                mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+                mock(ParticipantDeregisterAckPublisher.class), controlLoopUpdatePublisher,
+                mock(ParticipantUpdatePublisher.class));
+
+        handler.triggerControlLoopSupervision(List.of(identifier));
+
+        verify(controlLoopUpdatePublisher).send(any(ControlLoop.class));
+        verify(controlLoopProvider).updateControlLoop(any(ControlLoop.class));
+    }
+
+    @Test
+    void testHandleControlLoopStateChangeAckMessage() throws PfModelException, CoderException {
+        var controlLoopProvider = mock(ControlLoopProvider.class);
+        var handler = createSupervisionHandler(controlLoopProvider, mock(ParticipantProvider.class),
+                mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+                mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
+                mock(ParticipantUpdatePublisher.class));
+        var controlLoopAckMessage = new ControlLoopAck(ParticipantMessageType.CONTROLLOOP_STATECHANGE_ACK);
+        controlLoopAckMessage.setControlLoopResultMap(Map.of());
+        controlLoopAckMessage.setControlLoopId(identifier);
+
+        handler.handleControlLoopStateChangeAckMessage(controlLoopAckMessage);
+
+        verify(controlLoopProvider).updateControlLoop(any(ControlLoop.class));
+    }
+
+    @Test
+    void testHandleControlLoopUpdateAckMessage() throws PfModelException, CoderException {
+        var controlLoopAckMessage = new ControlLoopAck(ParticipantMessageType.CONTROLLOOP_UPDATE_ACK);
+        controlLoopAckMessage.setParticipantId(participantId);
+        controlLoopAckMessage.setParticipantType(participantType);
+        controlLoopAckMessage.setControlLoopResultMap(Map.of());
+        controlLoopAckMessage.setControlLoopId(identifier);
+        var controlLoopProvider = mock(ControlLoopProvider.class);
+        var handler = createSupervisionHandler(controlLoopProvider, mock(ParticipantProvider.class),
+                mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+                mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
+                mock(ParticipantUpdatePublisher.class));
+
+        handler.handleControlLoopUpdateAckMessage(controlLoopAckMessage);
+
+        verify(controlLoopProvider).updateControlLoop(any(ControlLoop.class));
+    }
+
+    @Test
+    void testHandleParticipantDeregister() throws PfModelException, CoderException {
+        var participant = new Participant();
+        participant.setName(participantId.getName());
+        participant.setVersion(participantId.getVersion());
+        participant.setParticipantType(participantType);
+
+        var participantProvider = mock(ParticipantProvider.class);
+        when(participantProvider.getParticipants(eq(participantId.getName()), eq(participantId.getVersion())))
+                .thenReturn(List.of(participant));
+
+        var participantDeregisterMessage = new ParticipantDeregister();
+        participantDeregisterMessage.setMessageId(UUID.randomUUID());
+        participantDeregisterMessage.setParticipantId(participantId);
+        participantDeregisterMessage.setParticipantType(participantType);
+        var participantDeregisterAckPublisher = mock(ParticipantDeregisterAckPublisher.class);
+        var handler = createSupervisionHandler(mock(ControlLoopProvider.class), participantProvider,
+                mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+                participantDeregisterAckPublisher, mock(ControlLoopUpdatePublisher.class),
+                mock(ParticipantUpdatePublisher.class));
+
+        handler.handleParticipantMessage(participantDeregisterMessage);
+
+        verify(participantProvider).updateParticipants(anyList());
+        verify(participantDeregisterAckPublisher).send(eq(participantDeregisterMessage.getMessageId()));
+    }
+
+    @Test
+    void testHandleParticipantRegister() throws PfModelException, CoderException {
+        var participant = new Participant();
+        participant.setName(participantId.getName());
+        participant.setVersion(participantId.getVersion());
+        participant.setParticipantType(participantType);
+
+        var participantRegisterMessage = new ParticipantRegister();
+        participantRegisterMessage.setMessageId(UUID.randomUUID());
+        participantRegisterMessage.setParticipantId(participantId);
+        participantRegisterMessage.setParticipantType(participantType);
+        var participantProvider = mock(ParticipantProvider.class);
+        var participantRegisterAckPublisher = mock(ParticipantRegisterAckPublisher.class);
+        var handler = createSupervisionHandler(mock(ControlLoopProvider.class), participantProvider,
+                mock(MonitoringProvider.class), participantRegisterAckPublisher,
+                mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
+                mock(ParticipantUpdatePublisher.class));
+
+        handler.handleParticipantMessage(participantRegisterMessage);
+
+        verify(participantProvider).createParticipants(anyList());
+        verify(participantRegisterAckPublisher).send(eq(participantRegisterMessage.getMessageId()), eq(participantId),
+                eq(participantType));
+    }
+
+    @Test
+    void testParticipantUpdateAck() throws PfModelException, CoderException {
+        var participant = new Participant();
+        participant.setName(participantId.getName());
+        participant.setVersion(participantId.getVersion());
+        participant.setParticipantType(participantType);
+
+        var participantProvider = mock(ParticipantProvider.class);
+        when(participantProvider.getParticipants(eq(participantId.getName()), eq(participantId.getVersion())))
+                .thenReturn(List.of(participant));
+
+        var participantUpdateAckMessage = new ParticipantUpdateAck();
+        participantUpdateAckMessage.setParticipantId(participantId);
+        participantUpdateAckMessage.setParticipantType(participantType);
+        participantUpdateAckMessage.setState(ParticipantState.PASSIVE);
+        var handler = createSupervisionHandler(mock(ControlLoopProvider.class), participantProvider,
+                mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+                mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
+                mock(ParticipantUpdatePublisher.class));
+
+        handler.handleParticipantMessage(participantUpdateAckMessage);
+
+        verify(participantProvider).updateParticipants(anyList());
+    }
+
+    @Test
+    void testHandleParticipantStatus() throws PfModelException, CoderException {
+        var participantStatusMessage = new ParticipantStatus();
+        participantStatusMessage.setParticipantId(participantId);
+        participantStatusMessage.setParticipantType(participantType);
+        participantStatusMessage.setState(ParticipantState.PASSIVE);
+        participantStatusMessage.setHealthStatus(ParticipantHealthStatus.HEALTHY);
+        participantStatusMessage.setParticipantStatistics(new ParticipantStatistics());
+
+        var participantProvider = mock(ParticipantProvider.class);
+        var monitoringProvider = mock(MonitoringProvider.class);
+        var handler = createSupervisionHandler(mock(ControlLoopProvider.class), participantProvider, monitoringProvider,
+                mock(ParticipantRegisterAckPublisher.class), mock(ParticipantDeregisterAckPublisher.class),
+                mock(ControlLoopUpdatePublisher.class), mock(ParticipantUpdatePublisher.class));
+        handler.handleParticipantMessage(participantStatusMessage);
+
+        verify(participantProvider).createParticipants(anyList());
+        verify(monitoringProvider).createParticipantStatistics(anyList());
+    }
+
+    @Test
+    void testHandleSendCommissionMessage() throws PfModelException, CoderException {
+        var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
+        var handler = createSupervisionHandler(mock(ControlLoopProvider.class), mock(ParticipantProvider.class),
+                mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+                mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
+                participantUpdatePublisher);
+        handler.handleSendCommissionMessage(Map.of());
+
+        verify(participantUpdatePublisher).send(anyMap(), eq(true));
+    }
+
+    @Test
+    void testHandleSendDeCommissionMessage() throws PfModelException, CoderException {
+        var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
+        var handler = createSupervisionHandler(mock(ControlLoopProvider.class), mock(ParticipantProvider.class),
+                mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+                mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
+                participantUpdatePublisher);
+        handler.handleSendDeCommissionMessage();
+
+        verify(participantUpdatePublisher).send(anyMap(), eq(false));
+    }
+
+    private SupervisionHandler createSupervisionHandler(ControlLoopProvider controlLoopProvider,
+            ParticipantProvider participantProvider, MonitoringProvider monitoringProvider,
+            ParticipantRegisterAckPublisher participantRegisterAckPublisher,
+            ParticipantDeregisterAckPublisher participantDeregisterAckPublisher,
+            ControlLoopUpdatePublisher controlLoopUpdatePublisher,
+            ParticipantUpdatePublisher participantUpdatePublisher) throws PfModelException, CoderException {
+        var controlLoopsCreate = InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud");
+
+        var controlLoop = controlLoopsCreate.getControlLoopList().get(0);
+        controlLoop.setOrderedState(ControlLoopOrderedState.PASSIVE);
+
+        var controlLoopStateChangePublisher = mock(ControlLoopStateChangePublisher.class);
+
+        when(controlLoopProvider.getControlLoop(eq(identifier))).thenReturn(controlLoop);
+
+        return new SupervisionHandler(controlLoopProvider, participantProvider, monitoringProvider,
+                controlLoopUpdatePublisher, controlLoopStateChangePublisher, participantRegisterAckPublisher,
+                participantDeregisterAckPublisher, participantUpdatePublisher);
+
+    }
+}