Updated handling of ack messages 94/123494/3
authorSirisha_Manchikanti <sirisha.manchikanti@est.tech>
Fri, 20 Aug 2021 16:21:11 +0000 (17:21 +0100)
committerSirisha_Manchikanti <sirisha.manchikanti@est.tech>
Wed, 25 Aug 2021 21:26:08 +0000 (22:26 +0100)
Issue-ID: POLICY-3417
Signed-off-by: Sirisha_Manchikanti <sirisha.manchikanti@est.tech>
Change-Id: I5784debf2e17fd1018b3feb7c9e2ae08d5f93d23

20 files changed:
models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopUpdateTest.java
participant/participant-impl/participant-impl-dcae/src/main/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/ControlLoopElementHandler.java
participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/rest/TestListenerUtils.java
participant/participant-impl/participant-impl-kubernetes/src/main/java/org/onap/policy/clamp/controlloop/participant/kubernetes/handler/ControlLoopElementHandler.java
participant/participant-impl/participant-impl-policy/src/main/java/org/onap/policy/clamp/controlloop/participant/policy/main/handler/ControlLoopElementHandler.java
participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/endtoend/ParticipantMessagesTest.java
participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/main/utils/TestListenerUtils.java
participant/participant-impl/participant-impl-simulator/src/main/java/org/onap/policy/clamp/controlloop/participant/simulator/simulation/SimulationProvider.java
participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestListenerUtils.java
participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java
participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java
participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/MessageSender.java
participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java
participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandler.java
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ControlLoopStateChangeAckListener.java [new file with mode: 0644]
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ControlLoopUpdateAckListener.java [new file with mode: 0644]
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ControlLoopUpdatePublisher.java
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ParticipantUpdatePublisher.java
runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/SupervisionMessagesTest.java

index d1b749e..3aafe56 100644 (file)
@@ -30,10 +30,8 @@ import java.util.Map;
 import java.util.UUID;
 import org.junit.jupiter.api.Test;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
-import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
-import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 
index b80fbfb..221635d 100644 (file)
@@ -30,6 +30,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementSt
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType;
 import org.onap.policy.clamp.controlloop.participant.dcae.httpclient.ClampHttpClient;
 import org.onap.policy.clamp.controlloop.participant.dcae.httpclient.ConsulDcaeHttpClient;
 import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.ParticipantDcaeParameters;
@@ -99,14 +100,16 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
                 if (loop != null) {
                     clampClient.undeploy(LOOP);
                     intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState,
-                            ControlLoopState.UNINITIALISED);
+                            ControlLoopState.UNINITIALISED, ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
                 }
                 break;
             case PASSIVE:
-                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.PASSIVE);
+                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.PASSIVE,
+                    ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
                 break;
             case RUNNING:
-                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.RUNNING);
+                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.RUNNING,
+                    ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
                 break;
             default:
                 LOGGER.debug("Unknown orderedstate {}", newState);
@@ -157,7 +160,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
                     String status = ClampHttpClient.getStatusCode(loop);
                     if (MICROSERVICE_INSTALLED_SUCCESSFULLY.equals(status)) {
                         intermediaryApi.updateControlLoopElementState(element.getId(), element.getOrderedState(),
-                                ControlLoopState.PASSIVE);
+                                ControlLoopState.PASSIVE, ParticipantMessageType.CONTROL_LOOP_UPDATE);
                         deployedFlag = true;
                         break;
                     }
@@ -165,7 +168,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
                 if (!deployedFlag) {
                     LOGGER.warn("DCAE is not deployed properly, ClElement state will be UNINITIALISED2PASSIVE");
                     intermediaryApi.updateControlLoopElementState(element.getId(), element.getOrderedState(),
-                            ControlLoopState.UNINITIALISED2PASSIVE);
+                            ControlLoopState.UNINITIALISED2PASSIVE, ParticipantMessageType.CONTROL_LOOP_UPDATE);
                 }
             }
         } catch (PfModelException e) {
index c6dd927..febdf6b 100644 (file)
@@ -51,7 +51,7 @@ public class TestListenerUtils {
     private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
     private static final Coder CODER = new StandardCoder();
     private static final String TOSCA_TEMPLATE_YAML = "examples/controlloop/PMSubscriptionHandling.yaml";
-    private static final String CONTROL_LOOP_ELEMENT = "ControlLoopElement";
+    private static final String CONTROL_LOOP_ELEMENT = "org.onap.policy.clamp.controlloop.ControlLoopElement";
 
     /**
      * Method to create a controlLoop from a yaml file.
index 8aa74f3..24a0755 100644 (file)
@@ -33,6 +33,7 @@ import lombok.Setter;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType;
 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener;
 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi;
 import org.onap.policy.clamp.controlloop.participant.kubernetes.exception.ServiceException;
@@ -96,7 +97,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
                     try {
                         chartService.uninstallChart(chart);
                         intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState,
-                            ControlLoopState.UNINITIALISED);
+                            ControlLoopState.UNINITIALISED, ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
                         chartMap.remove(controlLoopElementId);
                         podStatusMap.remove(chart.getReleaseName());
                     } catch (ServiceException se) {
@@ -105,10 +106,12 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
                 }
                 break;
             case PASSIVE:
-                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.PASSIVE);
+                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.PASSIVE,
+                    ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
                 break;
             case RUNNING:
-                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.RUNNING);
+                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.RUNNING,
+                    ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
                 break;
             default:
                 LOGGER.warn("cannot transition from state {} to state {}", currentState, newState);
index 0e19ea3..b17ae43 100644 (file)
@@ -32,6 +32,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementSt
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType;
 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener;
 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi;
 import org.onap.policy.clamp.controlloop.participant.policy.client.PolicyApiHttpClient;
@@ -89,10 +90,12 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
                 }
                 break;
             case PASSIVE:
-                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.PASSIVE);
+                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.PASSIVE,
+                    ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
                 break;
             case RUNNING:
-                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.RUNNING);
+                intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.RUNNING,
+                    ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
                 break;
             default:
                 LOGGER.debug("Unknown orderedstate {}", newState);
@@ -111,7 +114,8 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
             apiHttpClient.deletePolicyType(policyType.getKey(), policyType.getValue());
         }
         policyTypeMap.clear();
-        intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.UNINITIALISED);
+        intermediaryApi.updateControlLoopElementState(controlLoopElementId, newState, ControlLoopState.UNINITIALISED,
+            ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
     }
 
     /**
@@ -125,7 +129,7 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
     public void controlLoopElementUpdate(ControlLoopElement element, ToscaNodeTemplate clElementDefinition)
             throws PfModelException {
         intermediaryApi.updateControlLoopElementState(element.getId(), element.getOrderedState(),
-                ControlLoopState.PASSIVE);
+                ControlLoopState.PASSIVE, ParticipantMessageType.CONTROL_LOOP_UPDATE);
         ToscaServiceTemplate controlLoopDefinition = intermediaryApi.getToscaServiceTemplate();
         if (controlLoopDefinition.getToscaTopologyTemplate() != null) {
             if (controlLoopDefinition.getPolicyTypes() != null) {
index df9a4b2..699df25 100644 (file)
@@ -161,21 +161,7 @@ class ParticipantMessagesTest {
 
     @Test
     void testParticipantStatusHeartbeat() throws Exception {
-        final ParticipantStatus heartbeat = new ParticipantStatus();
-        heartbeat.setParticipantId(getParticipantId());
-        ControlLoopInfo clInfo = getControlLoopInfo(getControlLoopId());
-        clInfo.setControlLoopId(getControlLoopId());
-        heartbeat.setControlLoopInfoList(List.of(clInfo));
-
-        ControlLoopElementDefinition clDefinition = getClElementDefinition();
-        List<ControlLoopElementDefinition> controlLoopElementDefinitionList =
-            List.of(clDefinition);
-        ParticipantDefinition participantDefinition = new ParticipantDefinition();
-        participantDefinition.setParticipantId(getParticipantId());
-        participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
-        List<ParticipantDefinition> participantDefinitionUpdates = List.of(participantDefinition);
-        heartbeat.setParticipantDefinitionUpdates(participantDefinitionUpdates);
-
+        final ParticipantStatus heartbeat = participantHandler.makeHeartbeat(true);
         synchronized (lockit) {
             ParticipantMessagePublisher publisher =
                     new ParticipantMessagePublisher(Collections.singletonList(Mockito.mock(TopicSink.class)));
index 5984cf1..4c87e08 100644 (file)
@@ -59,7 +59,7 @@ public class TestListenerUtils {
     private static final Coder CODER = new StandardCoder();
     static CommonTestData commonTestData = new CommonTestData();
     private static final Logger LOGGER = LoggerFactory.getLogger(TestListenerUtils.class);
-    private static final String CONTROL_LOOP_ELEMENT = "ControlLoopElement";
+    private static final String CONTROL_LOOP_ELEMENT = "org.onap.policy.clamp.controlloop.ControlLoopElement";
 
     private TestListenerUtils() {}
 
index 49338c2..a7d2116 100644 (file)
@@ -27,6 +27,7 @@ import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType;
 import org.onap.policy.clamp.controlloop.models.messages.rest.TypedSimpleResponse;
 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi;
 import org.springframework.stereotype.Service;
@@ -79,7 +80,7 @@ public class SimulationProvider {
     public TypedSimpleResponse<ControlLoopElement> updateControlLoopElement(ControlLoopElement element) {
         TypedSimpleResponse<ControlLoopElement> response = new TypedSimpleResponse<>();
         response.setResponse(intermediaryApi.updateControlLoopElementState(element.getId(), element.getOrderedState(),
-                element.getState()));
+                element.getState(), ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE));
         return response;
     }
 
index 2b8de6a..83ef68e 100644 (file)
@@ -59,7 +59,7 @@ public class TestListenerUtils {
     private static final Coder CODER = new StandardCoder();
     static CommonTestData commonTestData = new CommonTestData();
     private static final Logger LOGGER = LoggerFactory.getLogger(TestListenerUtils.class);
-    private static final String CONTROL_LOOP_ELEMENT = "ControlLoopElement";
+    private static final String CONTROL_LOOP_ELEMENT = "org.onap.policy.clamp.controlloop.ControlLoopElement";
 
     private TestListenerUtils() {}
 
index aa2027a..ed0aea4 100644 (file)
@@ -31,6 +31,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
 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.messages.dmaap.participant.ParticipantMessageType;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 
@@ -123,7 +124,7 @@ public interface ParticipantIntermediaryApi {
      * @return ControlLoopElement updated control loop element
      */
     ControlLoopElement updateControlLoopElementState(UUID id, ControlLoopOrderedState currentState,
-            ControlLoopState newState);
+            ControlLoopState newState, ParticipantMessageType messageType);
 
     /**
      * Update the control loop element statistics.
index a2a4c34..ded102f 100644 (file)
@@ -33,6 +33,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
 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.messages.dmaap.participant.ParticipantMessageType;
 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener;
 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi;
 import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler;
@@ -127,8 +128,9 @@ public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryAp
 
     @Override
     public ControlLoopElement updateControlLoopElementState(UUID id, ControlLoopOrderedState currentState,
-            ControlLoopState newState) {
-        return participantHandler.getControlLoopHandler().updateControlLoopElementState(id, currentState, newState);
+            ControlLoopState newState, ParticipantMessageType messageType) {
+        return participantHandler.getControlLoopHandler().updateControlLoopElementState(id, currentState, newState,
+            messageType);
     }
 
     @Override
index 990c3df..680acd2 100644 (file)
@@ -146,7 +146,7 @@ public class MessageSender extends TimerTask implements Closeable {
      * Dispatch a heartbeat for this participant.
      */
     public void sendHeartbeat() {
-        publisher.sendHeartbeat(participantHandler.makeHeartbeat());
+        publisher.sendHeartbeat(participantHandler.makeHeartbeat(false));
     }
 
     /**
index daf9ebe..fbe940c 100644 (file)
@@ -63,6 +63,7 @@ public class ControlLoopHandler {
     private ToscaConceptIdentifier participantId = null;
     private MessageSender messageSender = null;
 
+    @Getter
     private final Map<ToscaConceptIdentifier, ControlLoop> controlLoopMap = new LinkedHashMap<>();
 
     @Getter
@@ -96,7 +97,7 @@ public class ControlLoopHandler {
      * @return controlLoopElement the updated controlloop element
      */
     public ControlLoopElement updateControlLoopElementState(UUID id, ControlLoopOrderedState orderedState,
-            ControlLoopState newState) {
+            ControlLoopState newState, ParticipantMessageType messageType) {
 
         if (id == null) {
             LOGGER.warn("Cannot update Control loop element state, id is null");
@@ -145,37 +146,38 @@ public class ControlLoopHandler {
         }
 
         var controlLoop = controlLoopMap.get(stateChangeMsg.getControlLoopId());
+        var controlLoopAck = new ControlLoopAck(ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
 
         if (controlLoop == null) {
+            controlLoopAck.setMessage("Control loop " + stateChangeMsg.getControlLoopId()
+                + " does not use this participant " + participantId);
+            controlLoopAck.setResult(false);
+            controlLoopAck.setResponseTo(stateChangeMsg.getMessageId());
+            controlLoopAck.setControlLoopId(stateChangeMsg.getControlLoopId());
+            messageSender.sendAckResponse(controlLoopAck);
             LOGGER.debug("Control loop {} does not use this participant", stateChangeMsg.getControlLoopId());
             return;
         }
 
-        var controlLoopStateChangeAck = new ControlLoopAck(ParticipantMessageType.CONTROLLOOP_STATECHANGE_ACK);
-        controlLoopStateChangeAck.setResponseTo(stateChangeMsg.getMessageId());
-        controlLoopStateChangeAck.setControlLoopId(stateChangeMsg.getControlLoopId());
-        handleState(controlLoop, controlLoopStateChangeAck, stateChangeMsg.getOrderedState());
-        messageSender.sendAckResponse(controlLoopStateChangeAck);
+        handleState(controlLoop, stateChangeMsg.getOrderedState());
     }
 
     /**
      * Method to handle state changes.
      *
      * @param controlLoop participant response
-     * @param response participant response
      * @param orderedState controlloop ordered state
      */
-    private void handleState(final ControlLoop controlLoop, final ControlLoopAck response,
-            ControlLoopOrderedState orderedState) {
+    private void handleState(final ControlLoop controlLoop, ControlLoopOrderedState orderedState) {
         switch (orderedState) {
             case UNINITIALISED:
-                handleUninitialisedState(controlLoop, orderedState, response);
+                handleUninitialisedState(controlLoop, orderedState);
                 break;
             case PASSIVE:
-                handlePassiveState(controlLoop, orderedState, response);
+                handlePassiveState(controlLoop, orderedState);
                 break;
             case RUNNING:
-                handleRunningState(controlLoop, orderedState, response);
+                handleRunningState(controlLoop, orderedState);
                 break;
             default:
                 LOGGER.debug("StateChange message has no state, state is null {}", controlLoop.getDefinition());
@@ -202,11 +204,11 @@ public class ControlLoopHandler {
         // TODO: Updates to existing ControlLoops are not supported yet (Addition/Removal of ControlLoop
         // elements to existing ControlLoop has to be supported).
         if (controlLoop != null) {
-            controlLoopUpdateAck.setResponseTo(updateMsg.getMessageId());
-            controlLoopUpdateAck.setControlLoopId(updateMsg.getControlLoopId());
             controlLoopUpdateAck.setMessage("Control loop " + updateMsg.getControlLoopId()
                 + " already defined on participant " + participantId);
             controlLoopUpdateAck.setResult(false);
+            controlLoopUpdateAck.setResponseTo(updateMsg.getMessageId());
+            controlLoopUpdateAck.setControlLoopId(updateMsg.getControlLoopId());
             messageSender.sendAckResponse(controlLoopUpdateAck);
             return;
         }
@@ -230,13 +232,6 @@ public class ControlLoopHandler {
         controlLoop.setDefinition(updateMsg.getControlLoopId());
         controlLoop.setElements(clElementMap);
         controlLoopMap.put(updateMsg.getControlLoopId(), controlLoop);
-
-        controlLoopUpdateAck.setResponseTo(updateMsg.getMessageId());
-        controlLoopUpdateAck.setControlLoopId(updateMsg.getControlLoopId());
-        controlLoopUpdateAck.setMessage("Control loop " + updateMsg.getControlLoopId()
-                + " defined on participant " + participantId);
-        controlLoopUpdateAck.setResult(true);
-        messageSender.sendAckResponse(controlLoopUpdateAck);
     }
 
     private ToscaNodeTemplate getClElementNodeTemplate(List<ControlLoopElementDefinition> clElementDefinitions,
@@ -275,11 +270,9 @@ public class ControlLoopHandler {
      *
      * @param controlLoop participant response
      * @param orderedState orderedState
-     * @param response participant response
      */
-    private void handleUninitialisedState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
-            final ControlLoopAck response) {
-        handleStateChange(controlLoop, orderedState, ControlLoopState.UNINITIALISED, response);
+    private void handleUninitialisedState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState) {
+        handleStateChange(controlLoop, orderedState, ControlLoopState.UNINITIALISED);
         controlLoopMap.remove(controlLoop.getKey().asIdentifier());
 
         for (ControlLoopElementListener clElementListener : listeners) {
@@ -298,11 +291,9 @@ public class ControlLoopHandler {
      *
      * @param controlLoop participant response
      * @param orderedState orderedState
-     * @param response participant response
      */
-    private void handlePassiveState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
-            final ControlLoopAck response) {
-        handleStateChange(controlLoop, orderedState, ControlLoopState.PASSIVE, response);
+    private void handlePassiveState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState) {
+        handleStateChange(controlLoop, orderedState, ControlLoopState.PASSIVE);
     }
 
     /**
@@ -310,11 +301,9 @@ public class ControlLoopHandler {
      *
      * @param controlLoop participant response
      * @param orderedState orderedState
-     * @param response participant response
      */
-    private void handleRunningState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
-            final ControlLoopAck response) {
-        handleStateChange(controlLoop, orderedState, ControlLoopState.RUNNING, response);
+    private void handleRunningState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState) {
+        handleStateChange(controlLoop, orderedState, ControlLoopState.RUNNING);
     }
 
     /**
@@ -323,14 +312,16 @@ public class ControlLoopHandler {
      * @param controlLoop participant status in memory
      * @param orderedState orderedState the new ordered state the participant should have
      * @param newState new state of the control loop elements
-     * @param response the response to the state change request
      */
     private void handleStateChange(ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
-            ControlLoopState newState, ControlLoopAck response) {
+            ControlLoopState newState) {
 
         if (orderedState.equals(controlLoop.getOrderedState())) {
-            response.setMessage("Control loop is already in state " + orderedState);
-            response.setResult(false);
+            var controlLoopAck = new ControlLoopAck(ParticipantMessageType.CONTROL_LOOP_STATE_CHANGE);
+            controlLoopAck.setMessage("Control loop is already in state" + orderedState);
+            controlLoopAck.setResult(false);
+            controlLoopAck.setControlLoopId(controlLoop.getDefinition());
+            messageSender.sendAckResponse(controlLoopAck);
             return;
         }
 
@@ -341,8 +332,6 @@ public class ControlLoopHandler {
             });
         }
 
-        response.setMessage("ControlLoop state changed from " + controlLoop.getOrderedState() + " to " + orderedState);
-        response.setResult(true);
         controlLoop.setOrderedState(orderedState);
     }
 
index f887f65..1947fda 100644 (file)
@@ -26,11 +26,16 @@ import java.io.Closeable;
 import java.time.Instant;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Objects;
 import java.util.UUID;
 import lombok.Getter;
 import lombok.Setter;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopInfo;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopStatistics;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantHealthStatus;
@@ -112,7 +117,7 @@ public class ParticipantHandler implements Closeable {
      * @param participantStatusReqMsg participant participantStatusReq message
      */
     public void handleParticipantStatusReq(final ParticipantStatusReq participantStatusReqMsg) {
-        sender.sendParticipantStatus(makeHeartbeat());
+        sender.sendParticipantStatus(makeHeartbeat(true));
     }
 
     /**
@@ -247,10 +252,17 @@ public class ParticipantHandler implements Closeable {
         }
 
         toscaServiceTemplate = participantUpdateMsg.getToscaServiceTemplate();
-        for (ParticipantDefinition participantDefinition : participantUpdateMsg.getParticipantDefinitionUpdates()) {
-            if (participantDefinition.getParticipantId().equals(participantType)) {
-                clElementDefsOnThisParticipant = participantDefinition.getControlLoopElementDefinitionList();
+        if (toscaServiceTemplate != null) {
+            // This message is to commission the controlloop
+            for (ParticipantDefinition participantDefinition : participantUpdateMsg.getParticipantDefinitionUpdates()) {
+                if (participantDefinition.getParticipantId().equals(participantType)) {
+                    clElementDefsOnThisParticipant = participantDefinition.getControlLoopElementDefinitionList();
+                    break;
+                }
             }
+        } else {
+            // This message is to decommision the controlloop
+            clElementDefsOnThisParticipant.clear();
         }
         sendParticipantUpdateAck(participantUpdateMsg.getMessageId());
     }
@@ -272,7 +284,7 @@ public class ParticipantHandler implements Closeable {
     /**
      * Method to send heartbeat to controlloop runtime.
      */
-    public ParticipantStatus makeHeartbeat() {
+    public ParticipantStatus makeHeartbeat(boolean responseToParticipantStatusReq) {
         this.participantStatistics.setState(state);
         this.participantStatistics.setHealthStatus(healthStatus);
         this.participantStatistics.setTimeStamp(Instant.now());
@@ -283,6 +295,35 @@ public class ParticipantHandler implements Closeable {
         heartbeat.setParticipantType(participantType);
         heartbeat.setHealthStatus(healthStatus);
         heartbeat.setState(state);
+        heartbeat.setControlLoopInfoList(getControlLoopInfoList());
+
+        if (responseToParticipantStatusReq) {
+            List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
+            ParticipantDefinition participantDefinition = new ParticipantDefinition();
+            participantDefinition.setParticipantId(participantId);
+            participantDefinition.setControlLoopElementDefinitionList(clElementDefsOnThisParticipant);
+            participantDefinitionUpdates.add(participantDefinition);
+            heartbeat.setParticipantDefinitionUpdates(participantDefinitionUpdates);
+        }
+
         return heartbeat;
     }
+
+    private List<ControlLoopInfo> getControlLoopInfoList() {
+        List<ControlLoopInfo> controlLoopInfoList = new ArrayList<>();
+        for (Map.Entry<ToscaConceptIdentifier, ControlLoop> entry :
+                controlLoopHandler.getControlLoopMap().entrySet()) {
+            ControlLoopInfo clInfo = new ControlLoopInfo();
+            clInfo.setControlLoopId(entry.getKey());
+            ControlLoopStatistics clStatitistics = new ControlLoopStatistics();
+            clStatitistics.setControlLoopId(entry.getKey());
+            ClElementStatisticsList clElementStatisticsList = new ClElementStatisticsList();
+            clElementStatisticsList.setClElementStatistics(
+                entry.getValue().getControlLoopElementStatisticsList(entry.getValue()));
+            clStatitistics.setClElementStatisticsList(clElementStatisticsList);
+            clInfo.setControlLoopStatistics(clStatitistics);
+            clInfo.setState(entry.getValue().getState());
+        }
+        return controlLoopInfoList;
+    }
 }
index 7cc5d7f..561d4fd 100644 (file)
@@ -31,6 +31,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
 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.ParticipantRegister;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus;
@@ -189,6 +190,26 @@ public class SupervisionHandler {
             participantUpdateMessage.getParticipantType(), false);
     }
 
+    /**
+     * Handle a ControlLoop update acknowledge message from a participant.
+     *
+     * @param controlLoopAckMessage the ControlLoopAck message received from a participant
+     */
+    @MessageIntercept
+    public void handleControlLoopUpdateAckMessage(ControlLoopAck controlLoopAckMessage) {
+        LOGGER.debug("ControlLoop Update Ack message received {}", controlLoopAckMessage);
+    }
+
+    /**
+     * Handle a ControlLoop statechange acknowledge message from a participant.
+     *
+     * @param controlLoopAckMessage the ControlLoopAck message received from a participant
+     */
+    @MessageIntercept
+    public void handleControlLoopStateChangeAckMessage(ControlLoopAck controlLoopAckMessage) {
+        LOGGER.debug("ControlLoop StateChange Ack message received {}", controlLoopAckMessage);
+    }
+
     /**
      * Supervise a control loop, performing whatever actions need to be performed on the control loop.
      *
diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ControlLoopStateChangeAckListener.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ControlLoopStateChangeAckListener.java
new file mode 100644 (file)
index 0000000..dd08b7a
--- /dev/null
@@ -0,0 +1,67 @@
+/*-
+ * ============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.comm;
+
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType;
+import org.onap.policy.clamp.controlloop.runtime.config.messaging.Listener;
+import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
+import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
+import org.onap.policy.common.endpoints.listeners.ScoListener;
+import org.onap.policy.common.utils.coder.StandardCoderObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * Listener for ControlLoopStateChangeAck messages sent by participants.
+ */
+@Component
+public class ControlLoopStateChangeAckListener extends ScoListener<ControlLoopAck> implements Listener {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ControlLoopStateChangeAckListener.class);
+
+    private final SupervisionHandler supervisionHandler;
+
+    /**
+     * Constructs the object.
+     */
+    public ControlLoopStateChangeAckListener(SupervisionHandler supervisionHandler) {
+        super(ControlLoopAck.class);
+        this.supervisionHandler = supervisionHandler;
+    }
+
+    @Override
+    public void onTopicEvent(final CommInfrastructure infra, final String topic, final StandardCoderObject sco,
+            final ControlLoopAck controlLoopStateChangeAckMessage) {
+        LOGGER.debug("ControlLoopStateChangeAck received from participant - {}", controlLoopStateChangeAckMessage);
+        supervisionHandler.handleControlLoopStateChangeAckMessage(controlLoopStateChangeAckMessage);
+    }
+
+    @Override
+    public ScoListener<ControlLoopAck> getScoListener() {
+        return this;
+    }
+
+    @Override
+    public String getType() {
+        return ParticipantMessageType.CONTROLLOOP_STATECHANGE_ACK.name();
+    }
+}
diff --git a/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ControlLoopUpdateAckListener.java b/runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/comm/ControlLoopUpdateAckListener.java
new file mode 100644 (file)
index 0000000..2f14dc8
--- /dev/null
@@ -0,0 +1,67 @@
+/*-
+ * ============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.comm;
+
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType;
+import org.onap.policy.clamp.controlloop.runtime.config.messaging.Listener;
+import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
+import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
+import org.onap.policy.common.endpoints.listeners.ScoListener;
+import org.onap.policy.common.utils.coder.StandardCoderObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+
+/**
+ * Listener for ControlLoopUpdateAck messages sent by participants.
+ */
+@Component
+public class ControlLoopUpdateAckListener extends ScoListener<ControlLoopAck> implements Listener {
+    private static final Logger LOGGER = LoggerFactory.getLogger(ControlLoopUpdateAckListener.class);
+
+    private final SupervisionHandler supervisionHandler;
+
+    /**
+     * Constructs the object.
+     */
+    public ControlLoopUpdateAckListener(SupervisionHandler supervisionHandler) {
+        super(ControlLoopAck.class);
+        this.supervisionHandler = supervisionHandler;
+    }
+
+    @Override
+    public void onTopicEvent(final CommInfrastructure infra, final String topic, final StandardCoderObject sco,
+            final ControlLoopAck controlLoopUpdateAckMessage) {
+        LOGGER.debug("ControlLoopUpdateAck message received from participant - {}", controlLoopUpdateAckMessage);
+        supervisionHandler.handleControlLoopUpdateAckMessage(controlLoopUpdateAckMessage);
+    }
+
+    @Override
+    public ScoListener<ControlLoopAck> getScoListener() {
+        return this;
+    }
+
+    @Override
+    public String getType() {
+        return ParticipantMessageType.CONTROLLOOP_UPDATE_ACK.name();
+    }
+}
index be9a2a2..35219bb 100644 (file)
@@ -22,17 +22,13 @@ package org.onap.policy.clamp.controlloop.runtime.supervision.comm;
 
 import java.time.Instant;
 import java.util.ArrayList;
-import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.UUID;
 import lombok.AllArgsConstructor;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
-import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
index d5dc4a6..d239f38 100644 (file)
@@ -49,9 +49,9 @@ import org.springframework.stereotype.Component;
 public class ParticipantUpdatePublisher extends AbstractParticipantPublisher<ParticipantUpdate> {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantUpdatePublisher.class);
-    private static final String CONTROL_LOOP_ELEMENT = "ControlLoopElement";
-    private final PolicyModelsProvider modelsProvider;
+    private static final String CONTROL_LOOP_ELEMENT = "org.onap.policy.clamp.controlloop.ControlLoopElement";
     private static final Coder CODER = new StandardCoder();
+    private final PolicyModelsProvider modelsProvider;
 
     /**
      * Send ParticipantUpdate to Participant.
@@ -60,7 +60,7 @@ public class ParticipantUpdatePublisher extends AbstractParticipantPublisher<Par
      * @param participantType the participant Type
      */
     public void send(ToscaConceptIdentifier participantId, ToscaConceptIdentifier participantType,
-                     boolean commissionFlag) {
+            boolean commissionFlag) {
         var message = new ParticipantUpdate();
         message.setParticipantId(participantId);
         message.setParticipantType(participantType);
index 73ec4e4..f1a2728 100644 (file)
@@ -77,7 +77,7 @@ class SupervisionMessagesTest extends CommonRestController {
     private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
     private static final String TOSCA_TEMPLATE_YAML =
             "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
-    private static final String CONTROL_LOOP_ELEMENT = "ControlLoopElement";
+    private static final String CONTROL_LOOP_ELEMENT = "org.onap.policy.clamp.controlloop.ControlLoopElement";
     private static final Coder CODER = new StandardCoder();
 
     /**