aboutsummaryrefslogtreecommitdiffstats
path: root/participant/participant-intermediary
diff options
context:
space:
mode:
authorliamfallon <liam.fallon@est.tech>2021-05-26 11:02:07 +0100
committerliamfallon <liam.fallon@est.tech>2021-05-26 11:02:11 +0100
commit20c7487f77d0728d270b2bed34c2c798d17cc12d (patch)
treebb20d003255fab584ac64968967fbc6e1f205232 /participant/participant-intermediary
parentf83411a86e2277adae69e780e8511913d61a0f17 (diff)
Transfer tosca-poc onto master
This is the third if three commits, this commit makes the content of the master branch the same as the tosca-poc branch. This commit adds the "src" files for TOSCA control loops to the modules in master. Difference between this commit and the current master: ------------------------------------------------------ diff -qr clamp clamp-master |diff_filter.sh Only in clamp/common: src Only in clamp/models: src Files clamp/participant/participant-impl/participant-impl-dcae/pom.xml and clamp-master/participant/participant-impl/participant-impl-dcae/pom.xml differ Only in clamp/participant/participant-impl/participant-impl-dcae: src Only in clamp/participant/participant-impl/participant-impl-policy: src Only in clamp/participant/participant-impl/participant-impl-simulator: src Files clamp/participant/participant-impl/pom.xml and clamp-master/participant/participant-impl/pom.xml differ Only in clamp/participant/participant-intermediary: src Files clamp/participant/pom.xml and clamp-master/participant/pom.xml differ Files clamp/pom.xml and clamp-master/pom.xml differ Files clamp/runtime/pom.xml and clamp-master/runtime/pom.xml differ Only in clamp: runtime-controlloop Difference between this commit and the current tosca-poc branch: ---------------------------------------------------------------- diff -qr clamp clamp-tp |diff_filter.sh Files clamp/INFO.yaml and clamp-tp/INFO.yaml differ Only in clamp/releases: 6.0.1-container.yaml Only in clamp/releases: 6.0.1.yaml Only in clamp/releases: 6.0.2-container.yaml Only in clamp/releases: 6.0.2.yaml Only in clamp/releases: 6.1.0-container.yaml Only in clamp/releases: 6.1.0.yaml Only in clamp/releases: 6.1.1-container.yaml Only in clamp/releases: 6.1.1.yaml Files clamp/runtime/src/main/resources/META-INF/resources/swagger.html and clamp-tp/runtime/src/main/resources/META-INF/resources/swagger.html differ Issue-ID: POLICY-3215 Change-Id: Ica1aa3fe5d6110df2396ea856703102e800fa770 Signed-off-by: liamfallon <liam.fallon@est.tech>
Diffstat (limited to 'participant/participant-intermediary')
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ControlLoopElementListener.java62
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java139
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryFactory.java38
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java133
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopStateChangeListener.java68
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopUpdateListener.java67
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/MessageSender.java162
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantHealthCheckListener.java69
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStateChangeListener.java68
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStatusPublisher.java63
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java323
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java165
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java235
-rw-r--r--participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantIntermediaryParameters.java58
14 files changed, 1650 insertions, 0 deletions
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ControlLoopElementListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ControlLoopElementListener.java
new file mode 100644
index 000000000..9e5d2c663
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ControlLoopElementListener.java
@@ -0,0 +1,62 @@
+/*-
+ * ============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.participant.intermediary.api;
+
+import java.util.UUID;
+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.models.base.PfModelException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+/**
+ * This interface is implemented by participant implementations to receive updates on control loop elements.
+ */
+public interface ControlLoopElementListener {
+ /**
+ * Handle a control loop element state change.
+ *
+ * @param controlLoopElementId the ID of the control loop element
+ * @param currentState the current state of the control loop element
+ * @param newState the state to which the control loop element is changing to
+ * @throws PfModelException in case of a model exception
+ */
+ public void controlLoopElementStateChange(UUID controlLoopElementId, ControlLoopState currentState,
+ ControlLoopOrderedState newState) throws PfModelException;
+
+ /**
+ * Handle an update on a control loop element.
+ *
+ * @param element the information on the control loop element
+ * @param controlLoopDefinition toscaServiceTemplate
+ * @throws PfModelException from Policy framework
+ */
+ public void controlLoopElementUpdate(ControlLoopElement element,
+ ToscaServiceTemplate controlLoopDefinition) throws PfModelException;
+
+ /**
+ * Handle controlLoopElement statistics.
+ *
+ * @param controlLoopElementId controlLoopElement id
+ * @throws PfModelException in case of a model exception
+ */
+ public void handleStatistics(UUID controlLoopElementId) throws PfModelException;
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java
new file mode 100644
index 000000000..d31ae1082
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryApi.java
@@ -0,0 +1,139 @@
+/*-
+ * ============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.participant.intermediary.api;
+
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics;
+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.ControlLoopOrderedState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
+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.controlloop.concepts.ParticipantState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics;
+import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler;
+import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * This interface is used by participant implementations to use the participant intermediary.
+ */
+public interface ParticipantIntermediaryApi {
+ /**
+ * Initialise the participant intermediary.
+ *
+ * @param parameters the parameters for the intermediary
+ */
+ void init(ParticipantIntermediaryParameters parameters);
+
+ /**
+ * Close the intermediary.
+ */
+ void close();
+
+ /**
+ * Register a listener for control loop elements that are mediated by the intermediary.
+ *
+ * @param controlLoopElementListener The control loop element listener to register
+ */
+ void registerControlLoopElementListener(ControlLoopElementListener controlLoopElementListener);
+
+ /**
+ * Get participants loops from the intermediary API.
+ *
+ * @param name the participant name, null for all
+ * @param version the participant version, null for all
+ * @return the participants
+ */
+ List<Participant> getParticipants(String name, String version);
+
+ /**
+ * Update the state of a participant.
+ *
+ * @param definition the definition of the participant to update the state on
+ * @param state the state of the participant
+ * @return the participant
+ */
+ Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState state);
+
+ /**
+ * Update the statistics of a participant.
+ *
+ * @param participantStatistics the statistics of the participant
+ */
+ void updateParticipantStatistics(ParticipantStatistics participantStatistics);
+
+ /**
+ * Get control loops from the intermediary API.
+ *
+ * @param name the control loop element name, null for all
+ * @param version the control loop element version, null for all
+ * @return the control loop elements
+ */
+ ControlLoops getControlLoops(String name, String version);
+
+ /**
+ * Get control loop elements from the intermediary API.
+ *
+ * @param name the control loop element name, null for all
+ * @param version the control loop element version, null for all
+ * @return the control loop elements
+ */
+ Map<UUID, ControlLoopElement> getControlLoopElements(String name, String version);
+
+ /**
+ * Get control loop element from the intermediary API.
+ *
+ * @param id control loop element ID
+ * @return the control loop element
+ */
+ ControlLoopElement getControlLoopElement(UUID id);
+
+ /**
+ * Update the state of a control loop element.
+ *
+ * @param id the ID of the control loop element to update the state on
+ * @param currentState the state of the control loop element
+ * @param newState the state of the control loop element
+ * @return ControlLoopElement updated control loop element
+ */
+ ControlLoopElement updateControlLoopElementState(UUID id, ControlLoopOrderedState currentState,
+ ControlLoopState newState);
+
+ /**
+ * Update the control loop element statistics.
+ *
+ * @param id the ID of the control loop element to update the state on
+ * @param elementStatistics the updated statistics
+ */
+ void updateControlLoopElementStatistics(UUID id, ClElementStatistics elementStatistics);
+
+ /**
+ * Return participantHandler, This will not be used in real world, but for junits,
+ * if participantHandler is not returned, there is no way to test state change messages
+ * without dmaap simulator.
+ *
+ */
+ ParticipantHandler getParticipantHandler();
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryFactory.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryFactory.java
new file mode 100644
index 000000000..d7cc4b2ed
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ParticipantIntermediaryFactory.java
@@ -0,0 +1,38 @@
+/*-
+ * ============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.participant.intermediary.api;
+
+import org.onap.policy.clamp.controlloop.participant.intermediary.api.impl.ParticipantIntermediaryApiImpl;
+
+/**
+ * Factory class for creating {@link ParticipantIntermediaryApi} instances.
+ */
+public class ParticipantIntermediaryFactory {
+
+ /**
+ * Create an implementation of the {@link ParticipantIntermediaryApi} interface.
+ *
+ * @return the implementation of the API
+ */
+ public ParticipantIntermediaryApi createApiImplementation() {
+ return new ParticipantIntermediaryApiImpl();
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java
new file mode 100644
index 000000000..839088d72
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/impl/ParticipantIntermediaryApiImpl.java
@@ -0,0 +1,133 @@
+/*-
+ * ============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.participant.intermediary.api.impl;
+
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics;
+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.ControlLoopOrderedState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
+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.controlloop.concepts.ParticipantState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics;
+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.IntermediaryActivator;
+import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler;
+import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * This class is api implementation used by participant intermediary.
+ */
+public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryApi {
+
+ // The activator for the participant intermediary
+ private IntermediaryActivator activator;
+
+ @Override
+ public void init(ParticipantIntermediaryParameters parameters) {
+ activator = new IntermediaryActivator(parameters);
+
+ activator.start();
+ }
+
+ @Override
+ public void close() {
+ activator.shutdown();
+ }
+
+ @Override
+ public void registerControlLoopElementListener(ControlLoopElementListener controlLoopElementListener) {
+ activator.getParticipantHandler().getControlLoopHandler()
+ .registerControlLoopElementListener(controlLoopElementListener);
+ }
+
+ @Override
+ public List<Participant> getParticipants(String name, String version) {
+ return List.of(activator.getParticipantHandler().getParticipant(name, version));
+ }
+
+ @Override
+ public Participant updateParticipantState(ToscaConceptIdentifier definition, ParticipantState state) {
+ return activator.getParticipantHandler().updateParticipantState(definition, state);
+ }
+
+ @Override
+ public void updateParticipantStatistics(ParticipantStatistics participantStatistics) {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public ControlLoops getControlLoops(String name, String version) {
+ return activator.getParticipantHandler().getControlLoopHandler().getControlLoops();
+ }
+
+ @Override
+ public Map<UUID, ControlLoopElement> getControlLoopElements(String name, String version) {
+ List<ControlLoop> controlLoops = activator.getParticipantHandler()
+ .getControlLoopHandler().getControlLoops().getControlLoopList();
+
+ for (ControlLoop controlLoop : controlLoops) {
+ if (name.equals(controlLoop.getDefinition().getName())) {
+ return controlLoop.getElements();
+ }
+ }
+ return new LinkedHashMap<>();
+ }
+
+ @Override
+ public ControlLoopElement getControlLoopElement(UUID id) {
+ List<ControlLoop> controlLoops = activator.getParticipantHandler()
+ .getControlLoopHandler().getControlLoops().getControlLoopList();
+
+ for (ControlLoop controlLoop : controlLoops) {
+ ControlLoopElement clElement = controlLoop.getElements().get(id);
+ if (clElement != null) {
+ return clElement;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public ControlLoopElement updateControlLoopElementState(UUID id, ControlLoopOrderedState currentState,
+ ControlLoopState newState) {
+ return activator.getParticipantHandler().getControlLoopHandler()
+ .updateControlLoopElementState(id, currentState, newState);
+ }
+
+ @Override
+ public void updateControlLoopElementStatistics(UUID id, ClElementStatistics elementStatistics) {
+ activator.getParticipantHandler().getControlLoopHandler()
+ .updateControlLoopElementStatistics(id, elementStatistics);
+ }
+
+ @Override
+ public ParticipantHandler getParticipantHandler() {
+ return activator.getParticipantHandler();
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopStateChangeListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopStateChangeListener.java
new file mode 100644
index 000000000..50b8b9cdc
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopStateChangeListener.java
@@ -0,0 +1,68 @@
+/*-
+ * ============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.participant.intermediary.comm;
+
+import java.io.Closeable;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopStateChange;
+import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler;
+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;
+
+/**
+ * Listener for Participant State Change messages sent by CLAMP.
+ */
+public class ControlLoopStateChangeListener extends ScoListener<ParticipantControlLoopStateChange>
+ implements Closeable {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ControlLoopStateChangeListener.class);
+
+ private final ParticipantHandler participantHandler;
+
+ /**
+ * Constructs the object.
+ *
+ * @param participantHandler the handler for managing the state of the participant
+ */
+ public ControlLoopStateChangeListener(final ParticipantHandler participantHandler) {
+ super(ParticipantControlLoopStateChange.class);
+ this.participantHandler = participantHandler;
+ }
+
+ @Override
+ public void onTopicEvent(final CommInfrastructure infra, final String topic, final StandardCoderObject sco,
+ final ParticipantControlLoopStateChange controlLoopStateChangeMsg) {
+ LOGGER.debug("Control Loop State Change received from CLAMP - {}", controlLoopStateChangeMsg);
+
+ if (participantHandler.canHandle(controlLoopStateChangeMsg)) {
+ LOGGER.debug("Message for this participant");
+ participantHandler.getControlLoopHandler().handleControlLoopStateChange(controlLoopStateChangeMsg);
+ } else {
+ LOGGER.debug("Message not for this participant");
+ }
+ }
+
+ @Override
+ public void close() {
+ // No explicit action on this class
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopUpdateListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopUpdateListener.java
new file mode 100644
index 000000000..ab2437c1c
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ControlLoopUpdateListener.java
@@ -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.participant.intermediary.comm;
+
+import java.io.Closeable;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopUpdate;
+import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler;
+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;
+
+/**
+ * Listener for Control Loop Update messages sent by CLAMP.
+ */
+public class ControlLoopUpdateListener extends ScoListener<ParticipantControlLoopUpdate> implements Closeable {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ControlLoopUpdateListener.class);
+
+ private final ParticipantHandler participantHandler;
+
+ /**
+ * Constructs the object.
+ *
+ * @param participantHandler the handler for managing the state of the participant
+ */
+ public ControlLoopUpdateListener(final ParticipantHandler participantHandler) {
+ super(ParticipantControlLoopUpdate.class);
+ this.participantHandler = participantHandler;
+ }
+
+ @Override
+ public void onTopicEvent(final CommInfrastructure infra, final String topic, final StandardCoderObject sco,
+ final ParticipantControlLoopUpdate participantControlLoopUpdateMsg) {
+ LOGGER.debug("Control Loop update received from CLAMP - {}", participantControlLoopUpdateMsg);
+
+ if (participantHandler.canHandle(participantControlLoopUpdateMsg)) {
+ LOGGER.debug("Message for this participant");
+ participantHandler.getControlLoopHandler().handleControlLoopUpdate(participantControlLoopUpdateMsg);
+ } else {
+ LOGGER.debug("Message not for this participant");
+ }
+ }
+
+ @Override
+ public void close() {
+ // No explicit action on this class
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/MessageSender.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/MessageSender.java
new file mode 100644
index 000000000..3128f1eaa
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/MessageSender.java
@@ -0,0 +1,162 @@
+/*-
+ * ============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.participant.intermediary.comm;
+
+import java.io.Closeable;
+import java.time.Instant;
+import java.util.TimerTask;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+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.ControlLoops;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantResponseDetails;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantResponseStatus;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus;
+import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener;
+import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantStatusPublisher;
+import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class sends messages from participants to CLAMP.
+ */
+public class MessageSender extends TimerTask implements Closeable {
+ private static final Logger LOGGER = LoggerFactory.getLogger(MessageSender.class);
+
+ private final ParticipantHandler participantHandler;
+ private final ParticipantStatusPublisher publisher;
+ private ScheduledExecutorService timerPool;
+
+ /**
+ * Constructor, set the publisher.
+ *
+ * @param participantHandler the participant handler to use for gathering information
+ * @param publisher the publisher to use for sending messages
+ * @param interval time interval to send Participant Status periodic messages
+ */
+ public MessageSender(ParticipantHandler participantHandler, ParticipantStatusPublisher publisher,
+ long interval) {
+ this.participantHandler = participantHandler;
+ this.publisher = publisher;
+
+ // Kick off the timer
+ timerPool = makeTimerPool();
+ timerPool.scheduleAtFixedRate(this, 0, interval, TimeUnit.SECONDS);
+ }
+
+ @Override
+ public void run() {
+ LOGGER.debug("Sent heartbeat to CLAMP");
+
+ ParticipantResponseDetails response = new ParticipantResponseDetails();
+
+ response.setResponseTo(null);
+ response.setResponseStatus(ParticipantResponseStatus.PERIODIC);
+ response.setResponseMessage("Periodic response from participant");
+ }
+
+ @Override
+ public void close() {
+ timerPool.shutdown();
+ }
+
+ /**
+ * Send a response message for this participant.
+ *
+ * @param response the details to include in the response message
+ */
+ public void sendResponse(ParticipantResponseDetails response) {
+ sendResponse(null, response);
+ }
+
+ /**
+ * Dispatch a response message for this participant.
+ *
+ * @param controlLoopId the control loop to which this message is a response
+ * @param response the details to include in the response message
+ */
+ public void sendResponse(ToscaConceptIdentifier controlLoopId, ParticipantResponseDetails response) {
+ ParticipantStatus status = new ParticipantStatus();
+
+ // Participant related fields
+ status.setParticipantType(participantHandler.getParticipantType());
+ status.setParticipantId(participantHandler.getParticipantId());
+ status.setState(participantHandler.getState());
+ status.setHealthStatus(participantHandler.getHealthStatus());
+
+ // Control loop related fields
+ ControlLoops controlLoops = participantHandler.getControlLoopHandler().getControlLoops();
+ status.setControlLoopId(controlLoopId);
+ status.setControlLoops(controlLoops);
+ status.setResponse(response);
+
+ ParticipantStatistics participantStatistics = new ParticipantStatistics();
+ participantStatistics.setTimeStamp(Instant.now());
+ participantStatistics.setParticipantId(participantHandler.getParticipantId());
+ participantStatistics.setHealthStatus(participantHandler.getHealthStatus());
+ participantStatistics.setState(participantHandler.getState());
+ status.setParticipantStatistics(participantStatistics);
+
+ for (ControlLoopElementListener clElementListener :
+ participantHandler.getControlLoopHandler().getListeners()) {
+ updateClElementStatistics(controlLoops, clElementListener);
+ }
+
+ status.setControlLoops(controlLoops);
+
+ publisher.send(status);
+ }
+
+ /**
+ * Update ControlLoopElement statistics. The control loop elements listening will be
+ * notified to retrieve statistics from respective controlloop elements, and controlloopelements
+ * data on the handler will be updated.
+ *
+ * @param controlLoops the control loops
+ * @param clElementListener control loop element listener
+ */
+ public void updateClElementStatistics(ControlLoops controlLoops, ControlLoopElementListener clElementListener) {
+ for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
+ for (ControlLoopElement element : controlLoop.getElements().values()) {
+ try {
+ clElementListener.handleStatistics(element.getId());
+ } catch (PfModelException e) {
+ LOGGER.debug("Getting statistics for Control loop element failed");
+ }
+ }
+ }
+ }
+
+ /**
+ * Makes a new timer pool.
+ *
+ * @return a new timer pool
+ */
+ protected ScheduledExecutorService makeTimerPool() {
+ return Executors.newScheduledThreadPool(1);
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantHealthCheckListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantHealthCheckListener.java
new file mode 100644
index 000000000..e0e6be329
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantHealthCheckListener.java
@@ -0,0 +1,69 @@
+/*-
+ * ============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.participant.intermediary.comm;
+
+import java.io.Closeable;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantHealthCheck;
+import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler;
+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;
+
+/**
+ * Listener for Participant health status messages sent by CLAMP.
+ */
+public class ParticipantHealthCheckListener extends ScoListener<ParticipantHealthCheck> implements Closeable {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantHealthCheckListener.class);
+
+ private final ParticipantHandler participantHandler;
+
+ /**
+ * Constructs the object.
+ *
+ * @param participantHandler the handler for managing the state and health of the participant
+ */
+ public ParticipantHealthCheckListener(final ParticipantHandler participantHandler) {
+ super(ParticipantHealthCheck.class);
+ this.participantHandler = participantHandler;
+ }
+
+ @Override
+ public void onTopicEvent(final CommInfrastructure infra, final String topic, final StandardCoderObject sco,
+ final ParticipantHealthCheck participantHealthCheckMsg) {
+ LOGGER.debug("Participant Health Check message received from CLAMP - {}", participantHealthCheckMsg);
+
+
+ if (participantHandler.canHandle(participantHealthCheckMsg)) {
+ LOGGER.debug("Message for this participant");
+ participantHandler.handleParticipantHealthCheck(participantHealthCheckMsg);
+ } else {
+ LOGGER.debug("Message not for this participant");
+ }
+
+ }
+
+ @Override
+ public void close() {
+ // No explicit action on this class
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStateChangeListener.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStateChangeListener.java
new file mode 100644
index 000000000..c1a8b5b4a
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStateChangeListener.java
@@ -0,0 +1,68 @@
+/*-
+ * ============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.participant.intermediary.comm;
+
+import java.io.Closeable;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStateChange;
+import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler;
+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;
+
+/**
+ * Listener for Participant State Change messages sent by CLAMP.
+ *
+ */
+public class ParticipantStateChangeListener extends ScoListener<ParticipantStateChange> implements Closeable {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantStateChangeListener.class);
+
+ private final ParticipantHandler participantHandler;
+
+ /**
+ * Constructs the object.
+ *
+ * @param participantHandler the handler for managing the state of the participant
+ */
+ public ParticipantStateChangeListener(final ParticipantHandler participantHandler) {
+ super(ParticipantStateChange.class);
+ this.participantHandler = participantHandler;
+ }
+
+ @Override
+ public void onTopicEvent(final CommInfrastructure infra, final String topic, final StandardCoderObject sco,
+ final ParticipantStateChange participantStateChangeMsg) {
+ LOGGER.debug("Participant State Change received from CLAMP - {}", participantStateChangeMsg);
+
+ if (participantHandler.canHandle(participantStateChangeMsg)) {
+ LOGGER.debug("Message for this participant");
+ participantHandler.handleParticipantStateChange(participantStateChangeMsg);
+ } else {
+ LOGGER.debug("Message not for this participant");
+ }
+ }
+
+ @Override
+ public void close() {
+ // No explicit action on this class
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStatusPublisher.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStatusPublisher.java
new file mode 100644
index 000000000..bc53b4e9d
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/comm/ParticipantStatusPublisher.java
@@ -0,0 +1,63 @@
+/*-
+ * ============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.participant.intermediary.comm;
+
+import java.io.Closeable;
+import java.util.List;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus;
+import org.onap.policy.common.endpoints.event.comm.TopicSink;
+import org.onap.policy.common.endpoints.event.comm.client.TopicSinkClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class is used to send Participant Status messages to clamp using TopicSinkClient.
+ *
+ */
+public class ParticipantStatusPublisher implements Closeable {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantStatusPublisher.class);
+
+ private final TopicSinkClient topicSinkClient;
+
+ /**
+ * Constructor for instantiating ParticipantStatusPublisher.
+ *
+ * @param topicSinks the topic sinks
+ */
+ public ParticipantStatusPublisher(List<TopicSink> topicSinks) {
+ this.topicSinkClient = new TopicSinkClient(topicSinks.get(0));
+ }
+
+ /**
+ * Method to send Participant Status message to clamp on demand.
+ *
+ * @param participantStatus the Participant Status
+ */
+ public void send(final ParticipantStatus participantStatus) {
+ topicSinkClient.send(participantStatus);
+ LOGGER.debug("Sent Participant Status message to CLAMP - {}", participantStatus);
+ }
+
+ @Override
+ public void close() {
+ // No explicit action on this class
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java
new file mode 100644
index 000000000..cc2a66b58
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ControlLoopHandler.java
@@ -0,0 +1,323 @@
+/*-
+ * ============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.participant.intermediary.handler;
+
+import java.io.Closeable;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import lombok.Getter;
+import org.apache.commons.collections4.CollectionUtils;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatistics;
+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.ControlLoopOrderedState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopStateChange;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopUpdate;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantResponseDetails;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantResponseStatus;
+import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoopElementListener;
+import org.onap.policy.clamp.controlloop.participant.intermediary.comm.MessageSender;
+import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/*
+ * This class is responsible for managing the state of all control loops in the participant.
+ */
+public class ControlLoopHandler implements Closeable {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ControlLoopHandler.class);
+
+ private ToscaConceptIdentifier participantType = null;
+ private ToscaConceptIdentifier participantId = null;
+ private MessageSender messageSender = null;
+
+ private final Map<ToscaConceptIdentifier, ControlLoop> controlLoopMap = new LinkedHashMap<>();
+
+ private final Map<UUID, ControlLoopElement> elementsOnThisParticipant = new LinkedHashMap<>();
+
+ @Getter
+ private List<ControlLoopElementListener> listeners = new ArrayList<>();
+
+ public ControlLoopHandler() {}
+
+ /**
+ * Constructor, set the participant ID and messageSender.
+ *
+ * @param parameters the parameters of the participant
+ * @param messageSender the messageSender for sending responses to messages
+ */
+ public ControlLoopHandler(ParticipantIntermediaryParameters parameters, MessageSender messageSender) {
+ this.participantType = parameters.getParticipantType();
+ this.participantId = parameters.getParticipantId();
+ this.messageSender = messageSender;
+ }
+
+ @Override
+ public void close() {
+ // No explicit action on this class
+ }
+
+ public void registerControlLoopElementListener(ControlLoopElementListener listener) {
+ listeners.add(listener);
+ }
+
+ /**
+ * Handle a control loop element state change message.
+ *
+ * @param id controlloop element id
+ * @param orderedState the current state
+ * @param newState the ordered state
+ * @return controlLoopElement the updated controlloop element
+ */
+ public ControlLoopElement updateControlLoopElementState(UUID id, ControlLoopOrderedState orderedState,
+ ControlLoopState newState) {
+
+ if (id == null) {
+ return null;
+ }
+
+ ControlLoopElement clElement = elementsOnThisParticipant.get(id);
+ if (clElement != null) {
+ clElement.setOrderedState(orderedState);
+ clElement.setState(newState);
+ LOGGER.debug("Control loop element {} state changed to {}", id, newState);
+ ParticipantResponseDetails response = new ParticipantResponseDetails();
+ response.setResponseStatus(ParticipantResponseStatus.SUCCESS);
+ response.setResponseMessage("ControlLoopElement state changed to {} " + newState);
+ messageSender.sendResponse(response);
+ return clElement;
+ }
+
+ return null;
+ }
+
+ /**
+ * Handle a control loop element statistics.
+ *
+ * @param id controlloop element id
+ * @param elementStatistics control loop element Statistics
+ */
+ public void updateControlLoopElementStatistics(UUID id, ClElementStatistics elementStatistics) {
+ ControlLoopElement clElement = elementsOnThisParticipant.get(id);
+ if (clElement != null) {
+ elementStatistics.setParticipantId(participantId);
+ elementStatistics.setId(id);
+ clElement.setClElementStatistics(elementStatistics);
+ }
+ }
+
+ /**
+ * Handle a control loop state change message.
+ *
+ * @param stateChangeMsg the state change message
+ */
+ public void handleControlLoopStateChange(ParticipantControlLoopStateChange stateChangeMsg) {
+ if (stateChangeMsg.getControlLoopId() == null) {
+ return;
+ }
+
+ ControlLoop controlLoop = controlLoopMap.get(stateChangeMsg.getControlLoopId());
+
+ if (controlLoop == null) {
+ LOGGER.debug("Control loop {} does not use this participant", stateChangeMsg.getControlLoopId());
+ return;
+ }
+
+ ParticipantResponseDetails response = new ParticipantResponseDetails(stateChangeMsg);
+ handleState(controlLoop, response, stateChangeMsg.getOrderedState());
+ messageSender.sendResponse(response);
+ }
+
+ /**
+ * 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 ParticipantResponseDetails response,
+ ControlLoopOrderedState orderedState) {
+ switch (orderedState) {
+ case UNINITIALISED:
+ handleUninitialisedState(controlLoop, orderedState, response);
+ break;
+ case PASSIVE:
+ handlePassiveState(controlLoop, orderedState, response);
+ break;
+ case RUNNING:
+ handleRunningState(controlLoop, orderedState, response);
+ break;
+ default:
+ LOGGER.debug("StateChange message has no state, state is null {}", controlLoop.getDefinition());
+ break;
+ }
+ }
+
+ /**
+ * Handle a control loop update message.
+ *
+ * @param updateMsg the update message
+ */
+ public void handleControlLoopUpdate(ParticipantControlLoopUpdate updateMsg) {
+
+ if (!updateMsg.appliesTo(participantType, participantId)) {
+ return;
+ }
+
+ ControlLoop controlLoop = controlLoopMap.get(updateMsg.getControlLoopId());
+
+ ParticipantResponseDetails response = new ParticipantResponseDetails(updateMsg);
+
+ // TODO: Updates to existing ControlLoops are not supported yet (Addition/Removal of ControlLoop
+ // elements to existing ControlLoop has to be supported).
+ if (controlLoop != null) {
+ response.setResponseStatus(ParticipantResponseStatus.FAIL);
+ response.setResponseMessage("Control loop " + updateMsg.getControlLoopId()
+ + " already defined on participant " + participantId);
+
+ messageSender.sendResponse(response);
+ return;
+ }
+
+ controlLoop = updateMsg.getControlLoop();
+ controlLoop.getElements().values().removeIf(element -> !participantType.equals(element.getParticipantType()));
+
+ controlLoopMap.put(updateMsg.getControlLoopId(), controlLoop);
+ for (ControlLoopElement element : updateMsg.getControlLoop().getElements().values()) {
+ element.setState(element.getOrderedState().asState());
+ element.setParticipantId(participantId);
+ elementsOnThisParticipant.put(element.getId(), element);
+ }
+
+ for (ControlLoopElementListener clElementListener : listeners) {
+ try {
+ for (ControlLoopElement element : updateMsg.getControlLoop().getElements().values()) {
+ clElementListener.controlLoopElementUpdate(element, updateMsg.getControlLoopDefinition());
+ }
+ } catch (PfModelException e) {
+ LOGGER.debug("Control loop element update failed {}", updateMsg.getControlLoopId());
+ }
+ }
+
+ response.setResponseStatus(ParticipantResponseStatus.SUCCESS);
+ response.setResponseMessage(
+ "Control loop " + updateMsg.getControlLoopId() + " defined on participant " + participantId);
+
+ messageSender.sendResponse(response);
+ }
+
+ /**
+ * Method to handle when the new state from participant is UNINITIALISED state.
+ *
+ * @param controlLoop participant response
+ * @param orderedState orderedState
+ * @param response participant response
+ */
+ private void handleUninitialisedState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
+ final ParticipantResponseDetails response) {
+ handleStateChange(controlLoop, orderedState, ControlLoopState.UNINITIALISED, response);
+ controlLoopMap.remove(controlLoop.getKey().asIdentifier());
+
+ for (ControlLoopElementListener clElementListener : listeners) {
+ try {
+ for (ControlLoopElement element : controlLoop.getElements().values()) {
+ clElementListener.controlLoopElementStateChange(element.getId(), element.getState(),
+ orderedState);
+ }
+ } catch (PfModelException e) {
+ LOGGER.debug("Control loop element update failed {}", controlLoop.getDefinition());
+ }
+ }
+ }
+
+ /**
+ * Method to handle when the new state from participant is PASSIVE state.
+ *
+ * @param controlLoop participant response
+ * @param orderedState orderedState
+ * @param response participant response
+ */
+ private void handlePassiveState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
+ final ParticipantResponseDetails response) {
+ handleStateChange(controlLoop, orderedState, ControlLoopState.PASSIVE, response);
+ }
+
+ /**
+ * Method to handle when the new state from participant is RUNNING state.
+ *
+ * @param controlLoop participant response
+ * @param orderedState orderedState
+ * @param response participant response
+ */
+ private void handleRunningState(final ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
+ final ParticipantResponseDetails response) {
+ handleStateChange(controlLoop, orderedState, ControlLoopState.RUNNING, response);
+ }
+
+ /**
+ * Method to update the state of control loop elements.
+ *
+ * @param controlLoop participant status in memory
+ * @param orderedState orderedState
+ * @param state new state of the control loop elements
+ */
+ private void handleStateChange(ControlLoop controlLoop, final ControlLoopOrderedState orderedState,
+ ControlLoopState newState, ParticipantResponseDetails response) {
+
+ if (orderedState.equals(controlLoop.getOrderedState())) {
+ response.setResponseStatus(ParticipantResponseStatus.SUCCESS);
+ response.setResponseMessage("Control loop is already in state " + orderedState);
+ return;
+ }
+
+ if (!CollectionUtils.isEmpty(controlLoop.getElements().values())) {
+ controlLoop.getElements().values().forEach(element -> {
+ element.setState(newState);
+ element.setOrderedState(orderedState);
+ }
+ );
+ }
+
+ response.setResponseStatus(ParticipantResponseStatus.SUCCESS);
+ response.setResponseMessage("ControlLoop state changed from " + controlLoop.getOrderedState()
+ + " to " + orderedState);
+ controlLoop.setOrderedState(orderedState);
+ }
+
+
+ /**
+ * Get control loops as a {@link ConrolLoops} class.
+ *
+ * @return the control loops
+ */
+ public ControlLoops getControlLoops() {
+ ControlLoops controlLoops = new ControlLoops();
+ controlLoops.setControlLoopList(new ArrayList<>(controlLoopMap.values()));
+ return controlLoops;
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java
new file mode 100644
index 000000000..be2fa1a30
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/IntermediaryActivator.java
@@ -0,0 +1,165 @@
+/*-
+ * ============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.participant.intermediary.handler;
+
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+import javax.ws.rs.core.Response.Status;
+import lombok.Getter;
+import lombok.experimental.Delegate;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopStateChange;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantControlLoopUpdate;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantHealthCheck;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageType;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStateChange;
+import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ControlLoopStateChangeListener;
+import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ControlLoopUpdateListener;
+import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantHealthCheckListener;
+import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantStateChangeListener;
+import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantStatusPublisher;
+import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters;
+import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
+import org.onap.policy.common.endpoints.event.comm.TopicSink;
+import org.onap.policy.common.endpoints.event.comm.TopicSource;
+import org.onap.policy.common.endpoints.listeners.MessageTypeDispatcher;
+import org.onap.policy.common.endpoints.listeners.ScoListener;
+import org.onap.policy.common.utils.services.ServiceManagerContainer;
+
+/**
+ * This class activates the Participant Intermediary together with all its handlers.
+ */
+public class IntermediaryActivator extends ServiceManagerContainer {
+ // Name of the message type for messages on topics
+ private static final String[] MSG_TYPE_NAMES = {"messageType"};
+
+ @Getter
+ private final ParticipantIntermediaryParameters parameters;
+
+ // Topics from which the participant receives and to which the participant sends messages
+ private List<TopicSink> topicSinks;
+ private List<TopicSource> topicSources;
+
+ // The participant handler for this intermediary
+ final AtomicReference<ParticipantHandler> participantHandler = new AtomicReference<>();
+
+ /**
+ * Listens for messages on the topic, decodes them into a message, and then dispatches them.
+ */
+ private final MessageTypeDispatcher msgDispatcher;
+
+ /**
+ * Instantiate the activator for participant.
+ *
+ * @param parameters the parameters for the participant intermediary
+ */
+ public IntermediaryActivator(final ParticipantIntermediaryParameters parameters) {
+ this.parameters = parameters;
+
+ topicSinks =
+ TopicEndpointManager.getManager().addTopicSinks(parameters.getClampControlLoopTopics().getTopicSinks());
+
+ topicSources = TopicEndpointManager.getManager()
+ .addTopicSources(parameters.getClampControlLoopTopics().getTopicSources());
+
+ try {
+ this.msgDispatcher = new MessageTypeDispatcher(MSG_TYPE_NAMES);
+ } catch (final RuntimeException e) {
+ throw new ControlLoopRuntimeException(Status.INTERNAL_SERVER_ERROR,
+ "topic message dispatcher failed to start", e);
+ }
+
+ // @formatter:off
+ final AtomicReference<ParticipantStatusPublisher> statusPublisher = new AtomicReference<>();
+ final AtomicReference<ParticipantStateChangeListener> participantStateChangeListener = new AtomicReference<>();
+ final AtomicReference<ParticipantHealthCheckListener> participantHealthCheckListener = new AtomicReference<>();
+ final AtomicReference<ControlLoopStateChangeListener> controlLoopStateChangeListener = new AtomicReference<>();
+ final AtomicReference<ControlLoopUpdateListener> controlLoopUpdateListener = new AtomicReference<>();
+
+ addAction("Topic endpoint management",
+ () -> TopicEndpointManager.getManager().start(),
+ () -> TopicEndpointManager.getManager().shutdown());
+
+ addAction("Participant Status Publisher",
+ () -> statusPublisher.set(new ParticipantStatusPublisher(topicSinks)),
+ () -> statusPublisher.get().close());
+
+ addAction("Participant Handler",
+ () -> participantHandler.set(new ParticipantHandler(parameters, statusPublisher.get())),
+ () -> participantHandler.get().close());
+
+ addAction("Participant State Change Listener",
+ () -> participantStateChangeListener.set(new ParticipantStateChangeListener(participantHandler.get())),
+ () -> participantStateChangeListener.get().close());
+
+ addAction("Participant Health Check Listener",
+ () -> participantHealthCheckListener.set(new ParticipantHealthCheckListener(participantHandler.get())),
+ () -> participantHealthCheckListener.get().close());
+
+ addAction("Control Loop State Change Listener",
+ () -> controlLoopStateChangeListener.set(new ControlLoopStateChangeListener(participantHandler.get())),
+ () -> controlLoopStateChangeListener.get().close());
+
+ addAction("Control Loop Update Listener",
+ () -> controlLoopUpdateListener.set(new ControlLoopUpdateListener(participantHandler.get())),
+ () -> controlLoopUpdateListener.get().close());
+
+ addAction("Topic Message Dispatcher", this::registerMsgDispatcher, this::unregisterMsgDispatcher);
+ // @formatter:on
+ }
+
+ /**
+ * Registers the dispatcher with the topic source(s).
+ */
+ private void registerMsgDispatcher() {
+ msgDispatcher.register(ParticipantMessageType.PARTICIPANT_STATE_CHANGE.name(),
+ (ScoListener<ParticipantStateChange>) new ParticipantStateChangeListener(
+ participantHandler.get()));
+ msgDispatcher.register(ParticipantMessageType.PARTICIPANT_HEALTH_CHECK.name(),
+ (ScoListener<ParticipantHealthCheck>) new ParticipantHealthCheckListener(
+ participantHandler.get()));
+ msgDispatcher.register(ParticipantMessageType.PARTICIPANT_CONTROL_LOOP_STATE_CHANGE.name(),
+ (ScoListener<ParticipantControlLoopStateChange>) new ControlLoopStateChangeListener(
+ participantHandler.get()));
+ msgDispatcher.register(ParticipantMessageType.PARTICIPANT_CONTROL_LOOP_UPDATE.name(),
+ (ScoListener<ParticipantControlLoopUpdate>) new ControlLoopUpdateListener(
+ participantHandler.get()));
+ for (final TopicSource source : topicSources) {
+ source.register(msgDispatcher);
+ }
+ }
+
+ /**
+ * Unregisters the dispatcher from the topic source(s).
+ */
+ private void unregisterMsgDispatcher() {
+ for (final TopicSource source : topicSources) {
+ source.unregister(msgDispatcher);
+ }
+ }
+
+ /**
+ * Return the participant handler.
+ */
+ public ParticipantHandler getParticipantHandler() {
+ return participantHandler.get();
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java
new file mode 100644
index 000000000..980ab6ec1
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/handler/ParticipantHandler.java
@@ -0,0 +1,235 @@
+/*-
+ * ============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.participant.intermediary.handler;
+
+import java.io.Closeable;
+import java.util.Objects;
+import lombok.Getter;
+import lombok.Setter;
+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.messages.dmaap.participant.ParticipantHealthCheck;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessage;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantResponseDetails;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantResponseStatus;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStateChange;
+import org.onap.policy.clamp.controlloop.participant.intermediary.comm.MessageSender;
+import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantStatusPublisher;
+import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantIntermediaryParameters;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class is responsible for managing the state of a participant.
+ */
+@Getter
+public class ParticipantHandler implements Closeable {
+ private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantHandler.class);
+
+ private final ToscaConceptIdentifier participantType;
+ private final ToscaConceptIdentifier participantId;
+ private final MessageSender sender;
+ private final ControlLoopHandler controlLoopHandler;
+ private final ParticipantStatistics participantStatistics;
+
+ @Setter
+ private ParticipantState state = ParticipantState.UNKNOWN;
+
+ @Setter
+ private ParticipantHealthStatus healthStatus = ParticipantHealthStatus.UNKNOWN;
+
+ /**
+ * Constructor, set the participant ID and sender.
+ *
+ * @param parameters the parameters of the participant
+ * @param publisher the publisher for sending responses to messages
+ */
+ public ParticipantHandler(ParticipantIntermediaryParameters parameters, ParticipantStatusPublisher publisher) {
+ this.participantType = parameters.getParticipantType();
+ this.participantId = parameters.getParticipantId();
+ this.sender = new MessageSender(this, publisher, parameters.getReportingTimeInterval());
+ this.controlLoopHandler = new ControlLoopHandler(parameters, sender);
+ this.participantStatistics = new ParticipantStatistics();
+ }
+
+ @Override
+ public void close() {
+ sender.close();
+ controlLoopHandler.close();
+ }
+
+ /**
+ * Method which handles a participant state change event from clamp.
+ *
+ * @param stateChangeMsg participant state change message
+ */
+ public void handleParticipantStateChange(final ParticipantStateChange stateChangeMsg) {
+
+ if (!stateChangeMsg.appliesTo(participantType, participantId)) {
+ return;
+ }
+
+ ParticipantResponseDetails response = new ParticipantResponseDetails(stateChangeMsg);
+
+ switch (stateChangeMsg.getState()) {
+ case PASSIVE:
+ handlePassiveState(response);
+ break;
+ case ACTIVE:
+ handleActiveState(response);
+ break;
+ case SAFE:
+ handleSafeState(response);
+ break;
+ case TEST:
+ handleTestState(response);
+ break;
+ case TERMINATED:
+ handleTerminatedState(response);
+ break;
+ default:
+ LOGGER.debug("StateChange message has no state, state is null {}", stateChangeMsg.getParticipantId());
+ response.setResponseStatus(ParticipantResponseStatus.FAIL);
+ response.setResponseMessage("StateChange message has invalid state for participantId "
+ + stateChangeMsg.getParticipantId());
+ break;
+ }
+
+ sender.sendResponse(response);
+ }
+
+
+ /**
+ * Method which handles a participant health check event from clamp.
+ *
+ * @param healthCheckMsg participant health check message
+ */
+ public void handleParticipantHealthCheck(final ParticipantHealthCheck healthCheckMsg) {
+ ParticipantResponseDetails response = new ParticipantResponseDetails(healthCheckMsg);
+ response.setResponseStatus(ParticipantResponseStatus.SUCCESS);
+ response.setResponseMessage(healthStatus.toString());
+
+ sender.sendResponse(response);
+ }
+
+ /**
+ * Method to handle when the new state from participant is active.
+ *
+ * @param response participant response
+ */
+ private void handleActiveState(final ParticipantResponseDetails response) {
+ handleStateChange(ParticipantState.ACTIVE, response);
+ }
+
+ /**
+ * Method to handle when the new state from participant is passive.
+ *
+ * @param response participant response
+ */
+ private void handlePassiveState(final ParticipantResponseDetails response) {
+ handleStateChange(ParticipantState.PASSIVE, response);
+ }
+
+ /**
+ * Method to handle when the new state from participant is safe.
+ *
+ * @param response participant response
+ */
+ private void handleSafeState(final ParticipantResponseDetails response) {
+ handleStateChange(ParticipantState.SAFE, response);
+ }
+
+ /**
+ * Method to handle when the new state from participant is TEST.
+ *
+ * @param response participant response
+ */
+ private void handleTestState(final ParticipantResponseDetails response) {
+ handleStateChange(ParticipantState.TEST, response);
+ }
+
+ /**
+ * Method to handle when the new state from participant is Terminated.
+ *
+ * @param response participant response
+ */
+ private void handleTerminatedState(final ParticipantResponseDetails response) {
+ handleStateChange(ParticipantState.TERMINATED, response);
+ }
+
+ private void handleStateChange(ParticipantState newParticipantState, ParticipantResponseDetails response) {
+ if (state.equals(newParticipantState)) {
+ response.setResponseStatus(ParticipantResponseStatus.SUCCESS);
+ response.setResponseMessage("Participant already in state " + newParticipantState);
+ } else {
+ response.setResponseStatus(ParticipantResponseStatus.SUCCESS);
+ response.setResponseMessage("Participant state changed from " + state + " to " + newParticipantState);
+ state = newParticipantState;
+ }
+ }
+
+ /**
+ * Method to update participant state.
+ *
+ * @param definition participant definition
+ * @param participantState participant state
+ */
+ public Participant updateParticipantState(ToscaConceptIdentifier definition,
+ ParticipantState participantState) {
+ if (!Objects.equals(definition, participantId)) {
+ LOGGER.debug("No participant with this ID {}", definition.getName());
+ return null;
+ }
+ ParticipantResponseDetails response = new ParticipantResponseDetails();
+ handleStateChange(participantState, response);
+ sender.sendResponse(response);
+ return getParticipant(definition.getName(), definition.getVersion());
+ }
+
+ /**
+ * Get participants as a {@link Participant} class.
+ *
+ * @return the participant
+ */
+ public Participant getParticipant(String name, String version) {
+ if (participantId.getName().equals(name)) {
+ Participant participant = new Participant();
+ participant.setDefinition(participantId);
+ participant.setParticipantState(state);
+ participant.setHealthStatus(healthStatus);
+ return participant;
+ }
+ return null;
+ }
+
+ /**
+ * Check if a participant message applies to this participant handler.
+ *
+ * @param partipantMsg the message to check
+ * @return true if it applies, false otherwise
+ */
+ public boolean canHandle(ParticipantMessage partipantMsg) {
+ return partipantMsg.appliesTo(participantType, participantId);
+ }
+}
diff --git a/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantIntermediaryParameters.java b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantIntermediaryParameters.java
new file mode 100644
index 000000000..8e3440e42
--- /dev/null
+++ b/participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/parameters/ParticipantIntermediaryParameters.java
@@ -0,0 +1,58 @@
+/*-
+ * ============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.participant.intermediary.parameters;
+
+import lombok.Getter;
+import org.onap.policy.common.endpoints.parameters.TopicParameterGroup;
+import org.onap.policy.common.parameters.ParameterGroupImpl;
+import org.onap.policy.common.parameters.annotations.NotBlank;
+import org.onap.policy.common.parameters.annotations.NotNull;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * Class to hold all parameters needed for participant component.
+ */
+@NotNull
+@NotBlank
+@Getter
+public class ParticipantIntermediaryParameters extends ParameterGroupImpl {
+ // The ID and description of this participant
+ private ToscaConceptIdentifier participantId;
+ private String description;
+
+ // The participant type of this participant
+ private ToscaConceptIdentifier participantType;
+
+ // The time interval for periodic reporting of status to the CLAMP control loop server
+ private long reportingTimeInterval;
+
+ // DMaaP topics for communicating with the CLAMP control loop server
+ private TopicParameterGroup clampControlLoopTopics;
+
+ /**
+ * Create the participant parameter group.
+ *
+ * @param instanceId instance id of the event.
+ */
+ public ParticipantIntermediaryParameters(final String instanceId) {
+ super(instanceId);
+ }
+}