Updated ControlLoop component messages 58/123258/6
authorSirisha_Manchikanti <sirisha.manchikanti@est.tech>
Tue, 10 Aug 2021 20:51:48 +0000 (21:51 +0100)
committerSirisha_Manchikanti <sirisha.manchikanti@est.tech>
Wed, 18 Aug 2021 13:58:42 +0000 (14:58 +0100)
Updated controlloop messages (ParticipantUpdate, ControlLoopUpdate,
ParticipantStatus) according to the following Wiki and added
implementation for the corresponding updates in runtime-controlloop and
participant components
https://wiki.onap.org/display/DW/The+CLAMP+Control+Loop+Participant+Protocol

Issue-ID: POLICY-3417
Signed-off-by: Sirisha_Manchikanti <sirisha.manchikanti@est.tech>
Change-Id: I80d96a7553a89ca47de2aa35e09df5a5c792acfa

46 files changed:
common/src/test/resources/examples/controlloop/PMSubscriptionHandling.yaml
models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoopElementDefinition.java
models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoopInfo.java
models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoops.java
models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ParticipantDefinition.java [new file with mode: 0644]
models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ParticipantUpdates.java [new file with mode: 0644]
models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopAck.java
models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopUpdate.java
models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantDeregister.java
models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantRegisterAck.java
models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantStatus.java
models/src/main/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantUpdate.java
models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ControlLoopUpdateTest.java
models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantStatusTest.java
models/src/test/java/org/onap/policy/clamp/controlloop/models/messages/dmaap/participant/ParticipantUpdateTest.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/endtoend/ParticipantDcaeTest.java
participant/participant-impl/participant-impl-dcae/src/test/java/org/onap/policy/clamp/controlloop/participant/dcae/main/handler/ControlLoopElementHandlerTest.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-dcae/src/test/resources/parameters/TestCLParams.json
participant/participant-impl/participant-impl-dcae/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml
participant/participant-impl/participant-impl-http/src/main/java/org/onap/policy/clamp/controlloop/participant/http/main/handler/ControlLoopElementHandler.java
participant/participant-impl/participant-impl-http/src/test/java/handler/ClElementHandlerTest.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-kubernetes/src/test/java/org.onap.policy.clamp.controlloop.participant.kubernetes/handler/ControlLoopElementHandlerTest.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/endtoend/ParticipantPolicyTest.java [deleted file]
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-policy/src/test/resources/parameters/TestCLParams.yaml
participant/participant-impl/participant-impl-policy/src/test/resources/utils/servicetemplates/pm_control_loop_tosca.yaml
participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/endtoend/ParticipantSimulatorTest.java
participant/participant-impl/participant-impl-simulator/src/test/java/org/onap/policy/clamp/controlloop/participant/simulator/main/rest/TestListenerUtils.java
participant/participant-impl/participant-impl-simulator/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml
participant/participant-intermediary/src/main/java/org/onap/policy/clamp/controlloop/participant/intermediary/api/ControlLoopElementListener.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/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/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
runtime-controlloop/src/test/resources/rest/controlloops/ControlLoops.json
runtime-controlloop/src/test/resources/rest/servicetemplates/PMSHMultipleCLTosca.yaml
runtime-controlloop/src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml

index 5c6883b..5628b0a 100644 (file)
@@ -661,7 +661,7 @@ topology_template:
       description: Control loop element for CDS for Performance Management Subscription Handling
       properties:
         provider: Ericsson
-        participant_Id:
+        participant_id:
           name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant
           version: 3.2.1
         cds_blueprint_id:
index 7daf897..b9f4d69 100644 (file)
@@ -22,28 +22,28 @@ package org.onap.policy.clamp.controlloop.models.controlloop.concepts;
 
 import java.util.LinkedHashMap;
 import java.util.Map;
-import java.util.UUID;
 import java.util.function.UnaryOperator;
 import lombok.Data;
+import lombok.Getter;
 import lombok.NoArgsConstructor;
-import lombok.NonNull;
 import lombok.ToString;
 import org.onap.policy.models.base.PfUtils;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 
 /**
  * Class to represent a control loop element definition instance.
  */
+@Getter
 @NoArgsConstructor
 @Data
 @ToString
 public class ControlLoopElementDefinition {
 
-    @NonNull
-    private UUID id = UUID.randomUUID();
+    private ToscaConceptIdentifier clElementDefinitionId;
 
     // The definition of the Control Loop Element in TOSCA
-    private ToscaServiceTemplate controlLoopElementToscaServiceTemplate;
+    private ToscaNodeTemplate controlLoopElementToscaNodeTemplate;
 
     // A map indexed by the property name. Each map entry is the serialized value of the property,
     // which can be deserialized into an instance of the type of the property.
@@ -55,9 +55,9 @@ public class ControlLoopElementDefinition {
      * @param clElementDefinition the controlloop element definition to copy from
      */
     public ControlLoopElementDefinition(final ControlLoopElementDefinition clElementDefinition) {
-        this.id = clElementDefinition.id;
-        this.controlLoopElementToscaServiceTemplate =
-                new ToscaServiceTemplate(clElementDefinition.controlLoopElementToscaServiceTemplate);
+        this.clElementDefinitionId = clElementDefinition.clElementDefinitionId;
+        this.controlLoopElementToscaNodeTemplate =
+                new ToscaNodeTemplate(clElementDefinition.controlLoopElementToscaNodeTemplate);
         this.commonPropertiesMap = PfUtils.mapMap(clElementDefinition.commonPropertiesMap, UnaryOperator.identity());
     }
 }
index bdf8941..0c33606 100644 (file)
@@ -23,6 +23,7 @@ package org.onap.policy.clamp.controlloop.models.controlloop.concepts;
 import lombok.Data;
 import lombok.NoArgsConstructor;
 import lombok.ToString;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 
 /**
  * Class to represent a control loop info instance.
@@ -32,6 +33,8 @@ import lombok.ToString;
 @ToString
 public class ControlLoopInfo {
 
+    private ToscaConceptIdentifier controlLoopId;
+
     private ControlLoopState state = ControlLoopState.UNINITIALISED;
 
     private ControlLoopStatistics controlLoopStatistics;
@@ -42,6 +45,7 @@ public class ControlLoopInfo {
      * @param otherElement the other element to copy from
      */
     public ControlLoopInfo(final ControlLoopInfo otherElement) {
+        this.controlLoopId = otherElement.controlLoopId;
         this.state = otherElement.state;
         this.controlLoopStatistics = otherElement.controlLoopStatistics;
     }
index 8edcc3c..691ce95 100644 (file)
@@ -37,7 +37,7 @@ public class ControlLoops {
     private List<ControlLoop> controlLoopList;
 
     /**
-     * Copy contructor, does a deep copy.
+     * Copy constructor, does a deep copy.
      *
      * @param otherControlLoops the other element to copy from
      */
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ParticipantDefinition.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ParticipantDefinition.java
new file mode 100644 (file)
index 0000000..bf93c07
--- /dev/null
@@ -0,0 +1,56 @@
+/*-
+ * ============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.models.controlloop.concepts;
+
+import java.util.ArrayList;
+import java.util.List;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import org.onap.policy.models.base.PfUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * Class to represent a participant definition update instance.
+ */
+@Getter
+@NoArgsConstructor
+@Data
+@ToString
+public class ParticipantDefinition {
+
+    private ToscaConceptIdentifier participantId;
+
+    // List of ControlLoopElementDefinition values for a particular participant
+    private List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>();
+
+    /**
+     * Copy constructor, does a deep copy but as all fields here are immutable, it's just a regular copy.
+     *
+     * @param participantDefinition the participant definition to copy from
+     */
+    public ParticipantDefinition(final ParticipantDefinition participantDefinition) {
+        this.participantId = participantDefinition.participantId;
+        this.controlLoopElementDefinitionList = PfUtils.mapList(
+            participantDefinition.controlLoopElementDefinitionList, ControlLoopElementDefinition::new);
+    }
+}
diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ParticipantUpdates.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ParticipantUpdates.java
new file mode 100644 (file)
index 0000000..ea851b8
--- /dev/null
@@ -0,0 +1,56 @@
+/*-
+ * ============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.models.controlloop.concepts;
+
+import java.util.ArrayList;
+import java.util.List;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+import lombok.ToString;
+import org.onap.policy.models.base.PfUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * Class to represent a participant definition update instance.
+ */
+@Getter
+@NoArgsConstructor
+@Data
+@ToString
+public class ParticipantUpdates {
+
+    private ToscaConceptIdentifier participantId;
+
+    // List of ControlLoopElement values for a particular participant
+    private List<ControlLoopElement> controlLoopElementList = new ArrayList<>();
+
+    /**
+     * Copy constructor, does a deep copy but as all fields here are immutable, it's just a regular copy.
+     *
+     * @param participantUpdates the participant with updates to copy from
+     */
+    public ParticipantUpdates(final ParticipantUpdates participantUpdates) {
+        this.participantId = participantUpdates.participantId;
+        this.controlLoopElementList = PfUtils.mapList(
+            participantUpdates.controlLoopElementList, ControlLoopElement::new);
+    }
+}
index 3411a03..55ba7fa 100644 (file)
@@ -41,19 +41,6 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 @ToString(callSuper = true)
 public class ControlLoopAck extends ParticipantAckMessage {
 
-    /**
-     * Participant ID, or {@code null} for messages from participants.
-     */
-    private ToscaConceptIdentifier participantId;
-
-    /**
-     * Participant Type, or {@code null} for messages from participants.
-     */
-    private ToscaConceptIdentifier participantType;
-
-    /**
-     * Control loop ID, or {@code null} for messages to participants.
-     */
     private ToscaConceptIdentifier controlLoopId;
 
     // A map with ControlLoopElementID as its key, and a pair of result and message as value per
@@ -75,8 +62,6 @@ public class ControlLoopAck extends ParticipantAckMessage {
      */
     public ControlLoopAck(final ControlLoopAck source) {
         super(source);
-        this.participantId = source.participantId;
-        this.participantType = source.participantType;
         this.controlLoopId = source.controlLoopId;
         this.controlLoopResultMap = PfUtils.mapMap(source.controlLoopResultMap, UnaryOperator.identity());
     }
index 865264f..42b9712 100644 (file)
 
 package org.onap.policy.clamp.controlloop.models.messages.dmaap.participant;
 
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.UUID;
+import java.util.ArrayList;
+import java.util.List;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;
-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.ParticipantUpdates;
 import org.onap.policy.models.base.PfUtils;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 
 /**
  * Class to represent the CONTROL_LOOP_UPDATE message that the control loop runtime sends to a participant.
@@ -41,12 +38,8 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 @ToString(callSuper = true)
 public class ControlLoopUpdate extends ParticipantMessage {
 
-    // The control loop
-    private ControlLoop controlLoop;
-
-    // A map with Participant ID as its key, and a map of ControlLoopElements as value.
-    private Map<ToscaConceptIdentifier, Map<UUID, ControlLoopElement>>
-            participantUpdateMap = new LinkedHashMap<>();
+    // A list of ParticipantUpdates instances which carries details of an updated participant.
+    private List<ParticipantUpdates> participantUpdatesList = new ArrayList<>();
 
     /**
      * Constructor for instantiating ControlLoopUpdate class with message name.
@@ -64,8 +57,7 @@ public class ControlLoopUpdate extends ParticipantMessage {
     public ControlLoopUpdate(ControlLoopUpdate source) {
         super(source);
 
-        this.controlLoop = source.controlLoop;
-        this.participantUpdateMap = PfUtils.mapMap(source.participantUpdateMap,
-                clElementMap -> PfUtils.mapMap(clElementMap, ControlLoopElement::new));
+        this.participantUpdatesList = PfUtils.mapList(source.participantUpdatesList,
+            ParticipantUpdates::new);
     }
 }
index e8759b3..7705e3d 100644 (file)
@@ -23,10 +23,6 @@ package org.onap.policy.clamp.controlloop.models.messages.dmaap.participant;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;
-import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
-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;
 
 /**
  * Class to represent the PARTICIPANT_DEREGISTER message that all the participants send to control loop runtime.
index 3d55c36..28d51be 100644 (file)
@@ -23,10 +23,6 @@ package org.onap.policy.clamp.controlloop.models.messages.dmaap.participant;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;
-import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
-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;
 
 /**
  * Class to represent the PARTICIPANT_REGISTER_ACK message that control loop runtime sends to registered participant.
index a8b268b..8600b4b 100644 (file)
 
 package org.onap.policy.clamp.controlloop.models.messages.dmaap.participant;
 
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.UUID;
+import java.util.ArrayList;
+import java.util.List;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;
-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.ParticipantDefinition;
 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;
@@ -45,16 +44,13 @@ public class ParticipantStatus extends ParticipantMessage {
     private ParticipantState state;
     private ParticipantHealthStatus healthStatus;
 
-    // Participant statistics
     private ParticipantStatistics participantStatistics;
 
-    // A map with Participant ID as its key, and a map of ControlLoopElements as value.
-    // Returned in response to ParticipantStatusReq only
-    private Map<String, Map<UUID, ControlLoopElementDefinition>>
-            participantDefinitionUpdateMap = new LinkedHashMap<>();
+    // A list of ParticipantDefinition updates, returned in response to ParticipantStatusReq only
+    private List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
 
-    // Map of ControlLoopInfo types indexed by ControlLoopId, one entry for each control loop
-    private Map<String, ControlLoopInfo> controlLoopInfoMap;
+    // List of ControlLoopInfo types with ControlLoopId, its state and statistics
+    private List<ControlLoopInfo> controlLoopInfoList = new ArrayList<>();
 
     /**
      * Constructor for instantiating ParticipantStatus class with message name.
@@ -75,9 +71,8 @@ public class ParticipantStatus extends ParticipantMessage {
         this.state = source.state;
         this.healthStatus = source.healthStatus;
         this.participantStatistics = (source.participantStatistics == null ? null : new ParticipantStatistics());
-        this.participantDefinitionUpdateMap = PfUtils.mapMap(source.participantDefinitionUpdateMap,
-                clElementDefinitionMap -> PfUtils.mapMap(clElementDefinitionMap,
-                        ControlLoopElementDefinition::new));
-        this.controlLoopInfoMap = PfUtils.mapMap(source.controlLoopInfoMap, ControlLoopInfo::new);
+        this.participantDefinitionUpdates = PfUtils.mapList(source.participantDefinitionUpdates,
+            ParticipantDefinition::new);
+        this.controlLoopInfoList = PfUtils.mapList(source.controlLoopInfoList, ControlLoopInfo::new);
     }
 }
index 2733de4..5c1b679 100644 (file)
 
 package org.onap.policy.clamp.controlloop.models.messages.dmaap.participant;
 
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.UUID;
+import java.util.ArrayList;
+import java.util.List;
 import lombok.Getter;
 import lombok.Setter;
 import lombok.ToString;
-import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
 import org.onap.policy.models.base.PfUtils;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 
 /**
  * Class to represent the PARTICIPANT_UPDATE message that the control loop runtime sends to a participant.
- * CLAMP Runtime sends Control Loop Element Definitions and Common Parameter Values to Participants.
+ * ControlLoop Runtime sends Control Loop Element Definitions and Common Parameter Values to Participants.
  */
 @Getter
 @Setter
 @ToString(callSuper = true)
 public class ParticipantUpdate extends ParticipantMessage {
 
-    // A map with Participant ID as its key, and a map of ControlLoopElements as value.
-    private Map<String, Map<UUID, ControlLoopElementDefinition>>
-            participantDefinitionUpdateMap = new LinkedHashMap<>();
+    // A list of updates to ParticipantDefinitions
+    private List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
+
+    private ToscaServiceTemplate toscaServiceTemplate = new ToscaServiceTemplate();
 
     /**
      * Constructor for instantiating ParticipantUpdate class with message name.
@@ -58,8 +59,8 @@ public class ParticipantUpdate extends ParticipantMessage {
     public ParticipantUpdate(ParticipantUpdate source) {
         super(source);
 
-        this.participantDefinitionUpdateMap = PfUtils.mapMap(source.participantDefinitionUpdateMap,
-                clElementDefinitionMap -> PfUtils.mapMap(clElementDefinitionMap,
-                        ControlLoopElementDefinition::new));
+        this.participantDefinitionUpdates = PfUtils.mapList(source.participantDefinitionUpdates,
+            ParticipantDefinition::new);
+        this.toscaServiceTemplate = source.toscaServiceTemplate;
     }
 }
index 0ac4f53..d1b749e 100644 (file)
@@ -25,13 +25,16 @@ import static org.junit.Assert.assertEquals;
 import static org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageUtils.removeVariableFields;
 
 import java.time.Instant;
+import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import org.junit.jupiter.api.Test;
-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.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;
 
 /**
@@ -59,19 +62,13 @@ class ControlLoopUpdateTest {
         clElement.setParticipantId(id);
         clElement.setParticipantType(id);
 
-        ControlLoop controlLoop = new ControlLoop();
-        controlLoop.setName("controlLoop");
-        Map<UUID, ControlLoopElement> elements = Map.of(clElement.getId(), clElement);
-        controlLoop.setElements(elements);
-        orig.setControlLoop(controlLoop);
-
         Map<String, String> commonPropertiesMap = Map.of("Prop1", "PropValue");
         clElement.setCommonPropertiesMap(commonPropertiesMap);
 
-        Map<UUID, ControlLoopElement> controlLoopElementMap = Map.of(UUID.randomUUID(), clElement);
-        Map<ToscaConceptIdentifier, Map<UUID, ControlLoopElement>>
-            participantUpdateMap = Map.of(id, controlLoopElementMap);
-        orig.setParticipantUpdateMap(participantUpdateMap);
+        ParticipantUpdates participantUpdates = new ParticipantUpdates();
+        participantUpdates.setParticipantId(id);
+        participantUpdates.setControlLoopElementList(List.of(clElement));
+        orig.setParticipantUpdatesList(List.of(participantUpdates));
 
         ControlLoopUpdate other = new ControlLoopUpdate(orig);
 
index 14252cd..7c16387 100644 (file)
@@ -36,11 +36,12 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopInfo;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopStatistics;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantHealthStatus;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 
 class ParticipantStatusTest {
 
@@ -65,13 +66,13 @@ class ParticipantStatusTest {
         orig.setTimestamp(Instant.ofEpochMilli(3000));
 
         ControlLoopInfo clInfo = getControlLoopInfo(id);
-        orig.setControlLoopInfoMap(Map.of(id.toString(), clInfo));
+        orig.setControlLoopInfoList(List.of(clInfo));
 
-        ControlLoopElementDefinition clDefinition = getClElementDefinition();
-        Map<UUID, ControlLoopElementDefinition> clElementDefinitionMap = Map.of(UUID.randomUUID(), clDefinition);
-        Map<String, Map<UUID, ControlLoopElementDefinition>>
-            participantDefinitionUpdateMap = Map.of(id.toString(), clElementDefinitionMap);
-        orig.setParticipantDefinitionUpdateMap(participantDefinitionUpdateMap);
+        ParticipantDefinition participantDefinitionUpdate = new ParticipantDefinition();
+        participantDefinitionUpdate.setParticipantId(id);
+        ControlLoopElementDefinition clDefinition = getClElementDefinition(id);
+        participantDefinitionUpdate.setControlLoopElementDefinitionList(List.of(clDefinition));
+        orig.setParticipantDefinitionUpdates(List.of(participantDefinitionUpdate));
 
         assertEquals(removeVariableFields(orig.toString()),
                 removeVariableFields(new ParticipantStatus(orig).toString()));
@@ -82,6 +83,7 @@ class ParticipantStatusTest {
     private ControlLoopInfo getControlLoopInfo(ToscaConceptIdentifier id) {
         ControlLoopInfo clInfo = new ControlLoopInfo();
         clInfo.setState(ControlLoopState.PASSIVE2RUNNING);
+        clInfo.setControlLoopId(id);
 
         ControlLoopStatistics clStatistics = new ControlLoopStatistics();
         clStatistics.setControlLoopId(id);
@@ -103,16 +105,16 @@ class ParticipantStatusTest {
         return clInfo;
     }
 
-    private ControlLoopElementDefinition getClElementDefinition() {
-        ToscaServiceTemplate toscaServiceTemplate = new ToscaServiceTemplate();
-        toscaServiceTemplate.setName("serviceTemplate");
-        toscaServiceTemplate.setDerivedFrom("parentServiceTemplate");
-        toscaServiceTemplate.setDescription("Description of serviceTemplate");
-        toscaServiceTemplate.setVersion("1.2.3");
+    private ControlLoopElementDefinition getClElementDefinition(ToscaConceptIdentifier id) {
+        ToscaNodeTemplate toscaNodeTemplate = new ToscaNodeTemplate();
+        toscaNodeTemplate.setName("nodeTemplate");
+        toscaNodeTemplate.setDerivedFrom("parentNodeTemplate");
+        toscaNodeTemplate.setDescription("Description of nodeTemplate");
+        toscaNodeTemplate.setVersion("1.2.3");
 
         ControlLoopElementDefinition clDefinition = new ControlLoopElementDefinition();
-        clDefinition.setId(UUID.randomUUID());
-        clDefinition.setControlLoopElementToscaServiceTemplate(toscaServiceTemplate);
+        clDefinition.setClElementDefinitionId(id);
+        clDefinition.setControlLoopElementToscaNodeTemplate(toscaNodeTemplate);
         Map<String, String> commonPropertiesMap = Map.of("Prop1", "PropValue");
         clDefinition.setCommonPropertiesMap(commonPropertiesMap);
         return clDefinition;
index 6ccdd20..06141de 100644 (file)
@@ -26,12 +26,15 @@ import static org.onap.policy.clamp.controlloop.models.messages.dmaap.participan
 import static org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantMessageUtils.removeVariableFields;
 
 import java.time.Instant;
+import java.util.List;
 import java.util.Map;
 import java.util.UUID;
 import org.junit.jupiter.api.Test;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 
 /**
@@ -44,9 +47,7 @@ class ParticipantUpdateTest {
 
         ParticipantUpdate orig = new ParticipantUpdate();
         // verify with all values
-        ToscaConceptIdentifier id = new ToscaConceptIdentifier();
-        id.setName("id");
-        id.setVersion("1.2.3");
+        ToscaConceptIdentifier id = new ToscaConceptIdentifier("id", "1.2.3");
         orig.setControlLoopId(id);
         orig.setParticipantId(id);
         orig.setParticipantType(id);
@@ -59,17 +60,17 @@ class ParticipantUpdateTest {
         toscaServiceTemplate.setDescription("Description of serviceTemplate");
         toscaServiceTemplate.setVersion("1.2.3");
 
-        ControlLoopElementDefinition clDefinition = new ControlLoopElementDefinition();
-        clDefinition.setId(UUID.randomUUID());
-        clDefinition.setControlLoopElementToscaServiceTemplate(toscaServiceTemplate);
-        Map<String, String> commonPropertiesMap = Map.of("Prop1", "PropValue");
-        clDefinition.setCommonPropertiesMap(commonPropertiesMap);
+        ToscaNodeTemplate toscaNodeTemplate = new ToscaNodeTemplate();
+        toscaNodeTemplate.setName("nodeTemplate");
+        toscaNodeTemplate.setDerivedFrom("parentNodeTemplate");
+        toscaNodeTemplate.setDescription("Description of nodeTemplate");
+        toscaNodeTemplate.setVersion("1.2.3");
 
-        Map<UUID, ControlLoopElementDefinition> clElementDefinitionMap = Map.of(UUID.randomUUID(), clDefinition);
-
-        Map<String, Map<UUID, ControlLoopElementDefinition>> participantDefinitionUpdateMap =
-                Map.of(id.toString(), clElementDefinitionMap);
-        orig.setParticipantDefinitionUpdateMap(participantDefinitionUpdateMap);
+        ParticipantDefinition participantDefinitionUpdate = new ParticipantDefinition();
+        participantDefinitionUpdate.setParticipantId(id);
+        ControlLoopElementDefinition clDefinition = getClElementDefinition(id);
+        participantDefinitionUpdate.setControlLoopElementDefinitionList(List.of(clDefinition));
+        orig.setParticipantDefinitionUpdates(List.of(participantDefinitionUpdate));
 
         ParticipantUpdate other = new ParticipantUpdate(orig);
 
@@ -77,4 +78,19 @@ class ParticipantUpdateTest {
 
         assertSerializable(orig, ParticipantUpdate.class);
     }
+
+    private ControlLoopElementDefinition getClElementDefinition(ToscaConceptIdentifier id) {
+        ToscaNodeTemplate toscaNodeTemplate = new ToscaNodeTemplate();
+        toscaNodeTemplate.setName("nodeTemplate");
+        toscaNodeTemplate.setDerivedFrom("parentNodeTemplate");
+        toscaNodeTemplate.setDescription("Description of nodeTemplate");
+        toscaNodeTemplate.setVersion("1.2.3");
+
+        ControlLoopElementDefinition clDefinition = new ControlLoopElementDefinition();
+        clDefinition.setClElementDefinitionId(id);
+        clDefinition.setControlLoopElementToscaNodeTemplate(toscaNodeTemplate);
+        Map<String, String> commonPropertiesMap = Map.of("Prop1", "PropValue");
+        clDefinition.setCommonPropertiesMap(commonPropertiesMap);
+        return clDefinition;
+    }
 }
index 5a0ddab..08ebd19 100644 (file)
@@ -36,7 +36,7 @@ import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoo
 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi;
 import org.onap.policy.common.utils.resources.ResourceUtils;
 import org.onap.policy.models.base.PfModelException;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -136,11 +136,11 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
      * Callback method to handle an update on a control loop element.
      *
      * @param element the information on the control loop element
-     * @param controlLoopDefinition toscaServiceTemplate
+     * @param nodeTemplate toscaNodeTemplate
      * @throws PfModelException in case of an exception
      */
     @Override
-    public void controlLoopElementUpdate(ControlLoopElement element, ToscaServiceTemplate controlLoopDefinition)
+    public void controlLoopElementUpdate(ControlLoopElement element, ToscaNodeTemplate nodeTemplate)
             throws PfModelException {
         try {
             Loop loop = getStatus();
index a3fcfdd..6e7f287 100644 (file)
@@ -34,10 +34,12 @@ import org.mockserver.integration.ClientAndServer;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
 import org.onap.policy.clamp.controlloop.participant.dcae.main.parameters.CommonTestData;
 import org.onap.policy.clamp.controlloop.participant.dcae.main.rest.TestListenerUtils;
 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.ParticipantUpdateListener;
 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.utils.coder.CoderException;
@@ -54,6 +56,7 @@ class ParticipantDcaeTest {
 
     private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
     private static final String TOPIC = "my-topic";
+    private static final Object lockit = new Object();
 
     private static final String LOOP = "pmsh_loop";
     private static final String BLUEPRINT_DEPLOYED = "BLUEPRINT_DEPLOYED";
@@ -68,7 +71,7 @@ class ParticipantDcaeTest {
      * start Servers.
      */
     @BeforeAll
-    public static void startServers() {
+    public void startServers() {
 
         // Clamp
         mockClampServer = ClientAndServer.startClientAndServer(8443);
@@ -88,6 +91,12 @@ class ParticipantDcaeTest {
 
         mockConsulServer.when(request().withMethod("PUT").withPath("/v1/kv/dcae-pmsh:policy"))
                 .respond(response().withStatusCode(200));
+        ParticipantUpdate participantUpdateMsg = TestListenerUtils.createParticipantUpdateMsg();
+
+        synchronized (lockit) {
+            ParticipantUpdateListener participantUpdateListener = new ParticipantUpdateListener(participantHandler);
+            participantUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantUpdateMsg);
+        }
     }
 
     /**
@@ -126,7 +135,6 @@ class ParticipantDcaeTest {
     void testControlLoopUpdateListener_ParticipantIdNoMatch() throws CoderException {
         ControlLoopUpdate controlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg();
         controlLoopUpdateMsg.getParticipantId().setName("DummyName");
-        controlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE);
 
         ControlLoopUpdateListener clUpdateListener = new ControlLoopUpdateListener(participantHandler);
         clUpdateListener.onTopicEvent(INFRA, TOPIC, null, controlLoopUpdateMsg);
@@ -139,7 +147,6 @@ class ParticipantDcaeTest {
     @Test
     void testControlLoopUpdateListenerPassive() throws CoderException {
         ControlLoopUpdate controlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg();
-        controlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE);
 
         ControlLoopUpdateListener clUpdateListener = new ControlLoopUpdateListener(participantHandler);
         clUpdateListener.onTopicEvent(INFRA, TOPIC, null, controlLoopUpdateMsg);
@@ -152,7 +159,6 @@ class ParticipantDcaeTest {
     @Test
     void testControlLoopUpdateListenerUninitialised() throws CoderException {
         ControlLoopUpdate controlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg();
-        controlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.UNINITIALISED);
 
         ControlLoopUpdateListener clUpdateListener = new ControlLoopUpdateListener(participantHandler);
         clUpdateListener.onTopicEvent(INFRA, TOPIC, null, controlLoopUpdateMsg);
@@ -165,7 +171,6 @@ class ParticipantDcaeTest {
     @Test
     void testControlLoopUpdateListenerString() throws CoderException {
         ControlLoopUpdate controlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg();
-        controlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.UNINITIALISED);
 
         assertThat(controlLoopUpdateMsg.toString()).contains("state=UNINITIALISED");
         ControlLoopUpdate copyControlLoopUpdateMsg =
index 40f2f5f..8a7f403 100644 (file)
@@ -31,21 +31,28 @@ import static org.mockito.Mockito.when;
 
 import java.util.UUID;
 import org.json.JSONException;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
 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.ParticipantUpdate;
 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.CommonTestData;
+import org.onap.policy.clamp.controlloop.participant.dcae.main.rest.TestListenerUtils;
 import org.onap.policy.clamp.controlloop.participant.dcae.model.Loop;
 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi;
+import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantUpdateListener;
+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.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
 /**
@@ -61,8 +68,27 @@ class ControlLoopElementHandlerTest {
     private static final String MICROSERVICE_INSTALLED_SUCCESSFULLY = "MICROSERVICE_INSTALLED_SUCCESSFULLY";
 
     public static final Coder CODER = new StandardCoder();
+    private static final Object lockit = new Object();
+    private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
+    private static final String TOPIC = "my-topic";
     private CommonTestData commonTestData = new CommonTestData();
 
+    @Autowired
+    private ParticipantHandler participantHandler;
+
+    /**
+     * Initial ParticipantUpdate message.
+     */
+    @BeforeAll
+    public void sendParticipantUpdate() {
+        ParticipantUpdate participantUpdateMsg = TestListenerUtils.createParticipantUpdateMsg();
+
+        synchronized (lockit) {
+            ParticipantUpdateListener participantUpdateListener = new ParticipantUpdateListener(participantHandler);
+            participantUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantUpdateMsg);
+        }
+    }
+
     @Test
     void test_ControlLoopElementStateChange() {
         ClampHttpClient clampClient = spy(mock(ClampHttpClient.class));
@@ -109,7 +135,9 @@ class ControlLoopElementHandlerTest {
         element.setOrderedState(ControlLoopOrderedState.PASSIVE);
 
         final ToscaServiceTemplate controlLoopDefinition = new ToscaServiceTemplate();
-        controlLoopElementHandler.controlLoopElementUpdate(element, controlLoopDefinition);
+        controlLoopElementHandler.controlLoopElementUpdate(element,
+            controlLoopDefinition.getToscaTopologyTemplate().getNodeTemplates()
+            .get("org.onap.domain.pmsh.PMSH_DCAEMicroservice"));
 
         verify(clampClient).create(eq(LOOP), eq(TEMPLATE));
         verify(consulClient).deploy(any(String.class), any(String.class));
@@ -139,7 +167,9 @@ class ControlLoopElementHandlerTest {
         element.setOrderedState(ControlLoopOrderedState.PASSIVE);
 
         ToscaServiceTemplate controlLoopDefinition = new ToscaServiceTemplate();
-        controlLoopElementHandler.controlLoopElementUpdate(element, controlLoopDefinition);
+        controlLoopElementHandler.controlLoopElementUpdate(element,
+                controlLoopDefinition.getToscaTopologyTemplate().getNodeTemplates()
+                .get("org.onap.domain.pmsh.PMSH_DCAEMicroservice"));
 
         verify(clampClient, times(0)).create(eq(LOOP), eq(TEMPLATE));
         verify(consulClient).deploy(any(String.class), any(String.class));
index 136d0e5..c6dd927 100644 (file)
@@ -22,16 +22,21 @@ package org.onap.policy.clamp.controlloop.participant.dcae.main.rest;
 
 import java.io.File;
 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 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.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.ParticipantState;
+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.ControlLoopStateChange;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
@@ -46,6 +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";
 
     /**
      * Method to create a controlLoop from a yaml file.
@@ -119,46 +125,158 @@ public class TestListenerUtils {
      */
     public static ControlLoopUpdate createControlLoopUpdateMsg() {
         final ControlLoopUpdate clUpdateMsg = new ControlLoopUpdate();
-        ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier();
-        controlLoopId.setName("PMSHInstance0");
-        controlLoopId.setVersion("1.0.0");
-
-        ToscaConceptIdentifier participantId = new ToscaConceptIdentifier();
-        participantId.setName("DCAEParticipant0");
-        participantId.setVersion("1.0.0");
+        ToscaConceptIdentifier controlLoopId =
+            new ToscaConceptIdentifier("PMSHInstance0", "1.0.0");
+        ToscaConceptIdentifier participantId =
+            new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0");
 
         clUpdateMsg.setControlLoopId(controlLoopId);
         clUpdateMsg.setParticipantId(participantId);
+        clUpdateMsg.setMessageId(UUID.randomUUID());
+        clUpdateMsg.setTimestamp(Instant.now());
 
-        ControlLoop controlLoop = new ControlLoop();
         Map<UUID, ControlLoopElement> elements = new LinkedHashMap<>();
         ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
         Map<String, ToscaNodeTemplate> nodeTemplatesMap =
                 toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : nodeTemplatesMap.entrySet()) {
-            ControlLoopElement clElement = new ControlLoopElement();
-            clElement.setId(UUID.randomUUID());
+            if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
+                ControlLoopElement clElement = new ControlLoopElement();
+                clElement.setId(UUID.randomUUID());
+                ToscaConceptIdentifier clParticipantId;
+                try {
+                    clParticipantId = CODER.decode(
+                            toscaInputEntry.getValue().getProperties().get("participant_id").toString(),
+                            ToscaConceptIdentifier.class);
+                } catch (CoderException e) {
+                    throw new RuntimeException("cannot get ParticipantId from toscaNodeTemplate", e);
+                }
 
-            ToscaConceptIdentifier clElementParticipantId = new ToscaConceptIdentifier();
-            clElementParticipantId.setName(toscaInputEntry.getKey());
-            clElementParticipantId.setVersion(toscaInputEntry.getValue().getVersion());
-            clElement.setParticipantId(clElementParticipantId);
+                clElement.setParticipantId(clParticipantId);
+                clElement.setParticipantType(clParticipantId);
 
-            clElement.setDefinition(clElementParticipantId);
-            clElement.setState(ControlLoopState.UNINITIALISED);
-            clElement.setDescription(toscaInputEntry.getValue().getDescription());
-            clElement.setOrderedState(ControlLoopOrderedState.UNINITIALISED);
-            elements.put(clElement.getId(), clElement);
+                clElement.setDefinition(new ToscaConceptIdentifier(toscaInputEntry.getKey(),
+                    toscaInputEntry.getValue().getVersion()));
+                clElement.setState(ControlLoopState.UNINITIALISED);
+                clElement.setDescription(toscaInputEntry.getValue().getDescription());
+                clElement.setOrderedState(ControlLoopOrderedState.PASSIVE);
+                elements.put(clElement.getId(), clElement);
+            }
         }
-        controlLoop.setElements(elements);
-        controlLoop.setName("PMSHInstance0");
-        controlLoop.setVersion("1.0.0");
-        controlLoop.setDefinition(controlLoopId);
-        clUpdateMsg.setControlLoop(controlLoop);
 
+        List<ParticipantUpdates> participantUpdates = new ArrayList<>();
+        for (ControlLoopElement element : elements.values()) {
+            prepareParticipantUpdateForControlLoop(element, participantUpdates);
+        }
+        clUpdateMsg.setParticipantUpdatesList(participantUpdates);
         return clUpdateMsg;
     }
 
+    private static void prepareParticipantUpdateForControlLoop(ControlLoopElement clElement,
+        List<ParticipantUpdates> participantUpdates) {
+        if (participantUpdates.isEmpty()) {
+            participantUpdates.add(getControlLoopElementList(clElement));
+        } else {
+            boolean participantExists = false;
+            for (ParticipantUpdates participantUpdate : participantUpdates) {
+                if (participantUpdate.getParticipantId().equals(clElement.getParticipantId())) {
+                    participantUpdate.getControlLoopElementList().add(clElement);
+                    participantExists = true;
+                }
+            }
+            if (!participantExists) {
+                participantUpdates.add(getControlLoopElementList(clElement));
+            }
+        }
+    }
+
+    private static ParticipantUpdates getControlLoopElementList(ControlLoopElement clElement) {
+        ParticipantUpdates participantUpdate = new ParticipantUpdates();
+        List<ControlLoopElement> controlLoopElementList = new ArrayList<>();
+        participantUpdate.setParticipantId(clElement.getParticipantId());
+        controlLoopElementList.add(clElement);
+        participantUpdate.setControlLoopElementList(controlLoopElementList);
+        return participantUpdate;
+    }
+
+    /**
+     * Method to create participantUpdateMsg.
+     *
+     * @return ParticipantUpdate message
+     */
+    public static ParticipantUpdate createParticipantUpdateMsg() {
+        final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate();
+        ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0");
+        ToscaConceptIdentifier participantType = new ToscaConceptIdentifier(
+                "org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1");
+
+        participantUpdateMsg.setParticipantId(participantId);
+        participantUpdateMsg.setTimestamp(Instant.now());
+        participantUpdateMsg.setParticipantType(participantType);
+        participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000));
+        participantUpdateMsg.setMessageId(UUID.randomUUID());
+
+        ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
+
+        List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
+        for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry :
+            toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
+            if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
+                ToscaConceptIdentifier clParticipantId;
+                try {
+                    clParticipantId = CODER.decode(
+                            toscaInputEntry.getValue().getProperties().get("participant_id").toString(),
+                            ToscaConceptIdentifier.class);
+                } catch (CoderException e) {
+                    throw new RuntimeException("cannot get ParticipantId from toscaNodeTemplate", e);
+                }
+                prepareParticipantDefinitionUpdate(clParticipantId, toscaInputEntry.getKey(),
+                    toscaInputEntry.getValue(), participantDefinitionUpdates);
+            }
+        }
+
+        participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates);
+        participantUpdateMsg.setToscaServiceTemplate(toscaServiceTemplate);
+        return participantUpdateMsg;
+    }
+
+    private static void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantId, String entryKey,
+        ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) {
+
+        var clDefinition = new ControlLoopElementDefinition();
+        clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(
+            entryKey, entryValue.getVersion()));
+        clDefinition.setControlLoopElementToscaNodeTemplate(entryValue);
+        List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>();
+
+        if (participantDefinitionUpdates.isEmpty()) {
+            participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
+                controlLoopElementDefinitionList));
+        } else {
+            boolean participantExists = false;
+            for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) {
+                if (participantDefinitionUpdate.getParticipantId().equals(clParticipantId)) {
+                    participantDefinitionUpdate.getControlLoopElementDefinitionList().add(clDefinition);
+                    participantExists = true;
+                }
+            }
+            if (!participantExists) {
+                participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
+                    controlLoopElementDefinitionList));
+            }
+        }
+    }
+
+    private static ParticipantDefinition getParticipantDefinition(ControlLoopElementDefinition clDefinition,
+        ToscaConceptIdentifier clParticipantId,
+        List<ControlLoopElementDefinition> controlLoopElementDefinitionList) {
+        ParticipantDefinition participantDefinition = new ParticipantDefinition();
+        participantDefinition.setParticipantId(clParticipantId);
+        controlLoopElementDefinitionList.add(clDefinition);
+        participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
+        return participantDefinition;
+    }
+
     /**
      * Method to create a deep copy of ControlLoopUpdateMsg.
      *
index a425862..5785360 100644 (file)
@@ -136,7 +136,7 @@ topology_template:
       description: Control loop element for CDS for Performance Management Subscription Handling
       properties:
         provider: Ericsson
-        participant_Id:
+        participant_id:
           name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant
           version: 3.2.1
         cds_blueprint_id:
index 01f825f..8615bdb 100644 (file)
 tosca_definitions_version: tosca_simple_yaml_1_3
-capability_types:
-  org.onap.EventProducer:
+data_types:
+  onap.datatypes.ToscaConceptIdentifier:
+    derived_from: tosca.datatypes.Root
     properties:
-      carrier_protocol_type:
+      name:
         type: string
         required: true
-        constraints:
-        - valid_values:
-          - DMAAP_message_router
-          - SOMETHING_ELSE
-          - REST
-      data_format:
+      version:
         type: string
         required: true
-        constraints:
-        - valid_values:
-          - JSON
-          - YAML
-          - JMS
-      event_format:
-        type: string
-        required: true
-      event_format_version:
-        type: string
-        required: false
-      config_keys:
-        type: list
-        required: false
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - all valid values should be added here
-            - if not specified, events of any config key may be generated
-            - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out,
-              etc.'
-    version: 0.0.1
-    derived_from: tosca.capabilities.Root
-  org.onap.EventConsumer:
-    properties:
-      responding_capability:
-        type: string
-        required: false
-      carrier_protocol_type:
-        type: string
-        required: true
-        constraints:
-        - valid_values:
-          - DMAAP_message_router
-          - SOMETHING_ELSE
-          - REST
-      data_format:
-        type: string
-        required: true
-        constraints:
-        - valid_values:
-          - JSON
-          - YAML
-          - JMS
-          - all valid values should be added here
-      event_format:
-        type: string
-        description: 'examples for event_format: Ves_specification, LinkUp, VnfConfigured,
-          etc.'
-        required: true
-      event_format_version:
-        type: string
-        description: 'examples for event_format_version: 5.28.4, 7.30.1, etc.'
-        required: false
-      config_keys:
-        type: list
-        required: false
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - all valid values should be added here
-            - if not specified, events of any config key may be generated
-            - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out,
-              etc.'
-    version: 0.0.1
-    derived_from: tosca.capabilities.Root
 node_types:
-  org.onap.DynamicConfig:
+  org.onap.policy.clamp.controlloop.Participant:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
     properties:
-      application_name:
-        type: string
-        description: Value used to tie the config to an application ? should we be
-          using a relationship here instead?
-        required: true
-      application_version:
-        type: string
-        required: true
-      application_provider:
+      provider:
         type: string
-        required: false
-      data_types:
-        type: object
-        required: false
-      schema:
-        type: object
-        required: false
-    version: 0.0.1
-    derived_from: tosca.nodes.Root
-  org.onap.APP:
+        requred: false
+  org.onap.policy.clamp.controlloop.ControlLoopElement:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
     properties:
-      application_name:
-        type: string
-        description: Human readable name for the application Product
-        required: false
       provider:
         type: string
-        description: Provider of the application and of the descriptor
-        required: true
-      application_version:
-        type: string
-        description: Software version of the application
-        required: true
-      blueprint_id:
-        type: string
-        description: A reference to the app blueprint
-        required: false
-      monitoring_policy:
-        type: string
-        description: A reference to the monitoring policy
-        required: false
-    requirements:
-    - receive:
-        capability: org.onap.EventProducer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        version: 0.0.0
-    - send:
-        capability: org.onap.EventConsumer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        version: 0.0.0
-    version: 0.0.1
-    derived_from: tosca.nodes.Root
-  org.onap.EventRelay:
+        requred: false
+      participant_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+  org.onap.policy.clamp.controlloop.ControlLoop:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
     properties:
-      event_format:
-        type: string
-        description: 'examples for event_format: Ves_specification, etc.'
-        required: true
-      event_format_version:
+      provider:
         type: string
-        description: 'examples for event_format_version: 5.28.4, 7.30.1, etc.'
-        required: true
-      config_keys:
+        requred: false
+      elements:
         type: list
-        required: false
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - all valid values should be added here
-            - if not specified, events of any config key is relayed
-            - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out,
-              etc.'
-      supported_carrier_protocols:
-        type: map
-        description: 'A map describing supported carrier protocols and translations.
-          The tuples define what protocol combinations are supported on the producer
-          and consumer side: e.g. { REST: REST, DMAAP: REST, DMAAP: DMAAP}'
-        required: true
-        key_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - DMAAP_message_router
-            - SOMETHING_ELSE
-            - REST
-            - all valid values should be added here
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - DMAAP_message_router
-            - SOMETHING_ELSE
-            - REST
-            - all valid values should be added here
-      supported_data_formats:
-        type: map
-        description: 'Is a map describing supported data formats and translation.
-          The tuples define what protocol combinations are supported on the producer
-          and consumer side: e.g. { JSON: JSON, JMS: JSON, YAML:YAML }'
         required: true
-        key_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - JSON
-            - JMS
-            - YAML
-            - etc
-            - all valid values should be added here
         entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - JSON
-            - JMS
-            - YAML
-            - etc
-            - all valid values should be added here
-    requirements:
-    - receive:
-        capability: org.onap.EventProducer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        version: 0.0.0
-    - send:
-        capability: org.onap.EventConsumer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        version: 0.0.0
-    version: 0.0.1
-    derived_from: tosca.nodes.Root
-relationship_types:
-  org.onap.PropagateEvent:
+          type: onap.datatypes.ToscaConceptIdentifier
+  org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
     properties:
-      config_keys:
-        type: list
-        description: The relationship type used on requirements to org.onap.EventProducer
-          and org.onap.EventConsumer capabilities. Filters events by specific config_keys
-          to be transferred by this relationship. That is, any event with a specific
-          config_key found in the list is transferred. If list is not defined or is
-          empty, events with all config_keys are transferred.
-        required: false
-        entry_schema:
-          type: string
-    version: 0.0.1
-    derived_from: tosca.relationships.Root
+      dcae_blueprint_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+  org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
+    properties:
+      policy_type_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+  org.onap.policy.clamp.controlloop.CDSControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
+    properties:
+      cds_blueprint_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
 topology_template:
-  inputs:
-    pm_subscription_topic:
-      type: string
-    pm_subscription_response_topic:
-      type: string
-    pm_subscription_handler_blueprint_id:
-      type: string
-    pm_subscription_operational_policy_id:
-      type: string
-    pm_subscription_cds_blueprint_id:
-      type: string
-    enable_tls:
-      type: string
   node_templates:
-    org.onap.PM_Subscription_Handler:
-      type: org.onap.APP
+    org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant:
+      version: 2.3.4
+      type: org.onap.policy.clamp.controlloop.Participant
+      type_version: 1.0.1
+      description: Participant for DCAE microservices
+      properties:
+        provider: ONAP
+    org.onap.policy.controlloop.PolicyControlLoopParticipant:
+      version: 2.3.1
+      type: org.onap.policy.clamp.controlloop.Participant
+      type_version: 1.0.1
+      description: Participant for DCAE microservices
+      properties:
+        provider: ONAP
+    org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant:
+      version: 2.2.1
+      type: org.onap.policy.clamp.controlloop.Participant
+      type_version: 1.0.1
+      description: Participant for DCAE microservices
+      properties:
+        provider: ONAP
+    org.onap.domain.pmsh.PMSH_DCAEMicroservice:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the DCAE microservice for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription Handler
         provider: Ericsson
-        application_version: 1.0.0
-        artifact_id:
-          get_input: pm_subscription_handler_blueprint_id
-          description: Is this a reference to the DCAE Cloudify Blueprint that is
-            already stored(or will be stored before CL configuration & instatiation)
-            in DCAE Inventory?
-        artifact_config:
-          enable_tls:
-            get_input: enable_tls
-          pmsh_publish_topic_name:
-            get_input: pm_subscription_topic
-      capabilities:
-        pm-subscription-event-publisher:
-          properties:
-            carrier_protocol_type: DMAAP_message_router
-            data_format: JSON
-            event_format: pm-subscription-event-format
-            event_format_version: 1.0.0
-          attributes:
-            type: org.onap.EventProducer
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          version: 0.0.0
-        pm-subscription-event-receiver:
-          properties:
-            carrier_protocol_type: DMAAP_message_router
-            data_format: JSON
-            event_format: pm-subscription-event-response-format
-            event_format_version: 1.0.0
-            relationships:
-            - type: tosca.relationships.DependsOn
-            - description: any ideas on a better realtionship ? or is it better to
-                just use the root realtionship ?
-            - target: org.onap.PM_Monitoring_Policy
-          attributes:
-            type: org.onap.EventConsumer
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          version: 0.0.0
-      version: 0.0.0
-    org.onap.PM_Monitoring_Policy:
-      type: org.onap.DynamicConfig
+        participant_id:
+          name: org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant
+          version: 2.3.4
+        dcae_blueprint_id:
+          name: org.onap.dcae.blueprints.PMSHBlueprint
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the monitoring policy for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription Handler
-        application_version: 1.0.0
         provider: Ericsson
-        data_types:
-          measurementType:
-            type: string
-          DN:
-            type: string
-          nfFilter:
-            properties:
-              nfNames:
-                type: list
-                entry_schema: string
-              modelInvariantIDs:
-                type: list
-                entry_schema:
-                  type: string
-              modelVersionIDs:
-                type: list
-                entry_schema:
-                  type: string
-          measurementGroup:
-            properties:
-              masurementTypes:
-                type: list
-                entry_schema:
-                  type: measurementType
-              managedObjectDNsBasic:
-                type: list
-                entry_schema:
-                  type: DN
-        schema:
-          subscription:
-            subscriptionName:
-              type: string
-              required: true
-            administrativeState:
-              type: string
-              required: true
-            filebasedGP:
-              type: integer
-              required: true
-            fileLocation:
-              type: string
-              required: true
-            nfFilter:
-              type: nfFilter
-            measurementGroups:
-              type: list
-              entry_schema:
-                type: measurementGroup
-      version: 0.0.0
-      description: Should I be showing a dependency between PM Subscription Handler
-        and the PM Monitoring Policy
-    org.onap.PM_Policy:
-      type: org.onap.APP
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.3.1
+        policy_type_id:
+          name: onap.policies.monitoring.pm-subscription-handler
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the operational policy for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription Operational Policy
         provider: Ericsson
-        application_version: 1.0.0
-        artifact_id:
-          get_input: pm_subscription_operational_policy_id
-        artifact_config: NOT_DEFINED
-      requirements:
-      - receive_0:
-          capability: pm-subscription-event-publisher
-          node: org.onap.PM_Subscription_Handler
-          relationship: NOT_DEFINED
-          properties:
-            config_keys:
-            - topic_name:
-                get_input: pm_subscription_topic
-          version: 0.0.0
-      - send_0:
-          capability: cds-rest-receive
-          node: org.onap.CDS
-          version: 0.0.0
-      - receive_1:
-          capability: cds-rest-response
-          node: org.onap.CDS
-          version: 0.0.0
-      - send_1:
-          capability: pm-subscription-event-receiver
-          node: org.onap.PM_Subscription_Handler
-          relationship: NOT_DEFINED
-          properties:
-            config_keys:
-            - topic_name:
-                get_input: pm_subscription_response_topic
-          version: 0.0.0
-      capabilities:
-        pm-subscription-response-event-publisher:
-          properties:
-            type: org.onap.EventProducer
-            carrier_protocol_type: DMAAP_message_router
-            data_format: JSON
-            event_format: pm-subscription-event-response-format
-            event_format_version: 1.0.0
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          version: 0.0.0
-      version: 0.0.0
-    org.onap.PM_CDS_Blueprint:
-      type: org.onap.APP
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.3.1
+        policy_type_id:
+          name: onap.policies.operational.pm-subscription-handler
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.ControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for CDS for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription CDS Blueprint
         provider: Ericsson
-        application_version: 1.0.0
-        artifact_id:
-          get_input: pm_subscription_cds_blueprint_id
-      capabilities:
-        cds-rest-receive:
-          properties:
-            type: org.onap.EventConsumer
-            protocol_type: REST
-            data_format: JSON
-            event_format: cds_action_format
-            event_format_version: 1.0.0
-            responding_capability: cds-rest-response
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          version: 0.0.0
-        cds-rest-response:
-          properties:
-            type: org.onap.EventProducer
-            protocol_type: REST
-            data_format: JSON
-            event_format: cds_action_response_format
-            event_format_version: 1.0.0
-          occurrences:
-          - 0.0
-          version: 0.0.0
-      version: 0.0.0
-    org.onap.controlloop0:
-      type: org.onap.APP
+        participant_id:
+          name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant
+          version: 3.2.1
+        cds_blueprint_id:
+          name: org.onap.ccsdk.cds.PMSHCdsBlueprint
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSHControlLoopDefinition:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.ControlLoop
+      type_version: 1.0.0
+      description: Control loop for Performance Management Subscription Handling
       properties:
-        application_name: Test Control Loop
         provider: Ericsson
-        application_version: 1.0.0
-        status: NOT_DEPLOYED
-      version: 0.0.0
-version: 0.0.0
+        elements:
+          - name: org.onap.domain.pmsh.PMSH_DCAEMicroservice
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement
+            version: 1.2.3
index 67948a9..f18885f 100644 (file)
@@ -32,7 +32,6 @@ import java.util.concurrent.Executors;
 import javax.validation.ConstraintViolation;
 import javax.validation.Validation;
 import javax.validation.ValidationException;
-import lombok.Getter;
 import lombok.Setter;
 import org.apache.commons.lang3.tuple.Pair;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
@@ -48,7 +47,6 @@ import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -99,29 +97,22 @@ public class ControlLoopElementHandler implements ControlLoopElementListener, Cl
      * Callback method to handle an update on a control loop element.
      *
      * @param element the information on the control loop element
-     * @param controlLoopDefinition toscaServiceTemplate
+     * @param nodeTemplate toscaNodeTemplate
      */
     @Override
-    public void controlLoopElementUpdate(ControlLoopElement element, ToscaServiceTemplate controlLoopDefinition) {
-
-        for (Map.Entry<String, ToscaNodeTemplate> nodeTemplate : controlLoopDefinition.getToscaTopologyTemplate()
-            .getNodeTemplates().entrySet()) {
-            // Fetching the node template of corresponding CL element
-            if (element.getDefinition().getName().equals(nodeTemplate.getKey())) {
-                try {
-                    var configRequest = CODER.convert(nodeTemplate.getValue().getProperties(), ConfigRequest.class);
-                    Set<ConstraintViolation<ConfigRequest>> violations = Validation.buildDefaultValidatorFactory()
-                        .getValidator().validate(configRequest);
-                    if (violations.isEmpty()) {
-                        invokeHttpClient(configRequest);
-                    } else {
-                        LOGGER.error("Violations found in the config request parameters: {}", violations);
-                        throw new ValidationException("Constraint violations in the config request");
-                    }
-                } catch (CoderException | ValidationException e) {
-                    LOGGER.error("Error invoking the http request for the config ", e);
-                }
+    public void controlLoopElementUpdate(ControlLoopElement element, ToscaNodeTemplate nodeTemplate) {
+        try {
+            var configRequest = CODER.convert(nodeTemplate.getProperties(), ConfigRequest.class);
+            Set<ConstraintViolation<ConfigRequest>> violations = Validation.buildDefaultValidatorFactory()
+                .getValidator().validate(configRequest);
+            if (violations.isEmpty()) {
+                invokeHttpClient(configRequest);
+            } else {
+                LOGGER.error("Violations found in the config request parameters: {}", violations);
+                throw new ValidationException("Constraint violations in the config request");
             }
+        } catch (CoderException | ValidationException e) {
+            LOGGER.error("Error invoking the http request for the config ", e);
         }
     }
 
index 10b8103..46ed355 100644 (file)
@@ -24,6 +24,7 @@ import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doNothing;
 
+import java.util.Map;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.extension.ExtendWith;
@@ -32,6 +33,7 @@ import org.mockito.Spy;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
 import org.onap.policy.clamp.controlloop.participant.http.main.handler.ControlLoopElementHandler;
 import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 import utils.CommonTestData;
@@ -47,6 +49,8 @@ class ClElementHandlerTest {
     private CommonTestData commonTestData = new CommonTestData();
 
     private static ToscaServiceTemplate serviceTemplate;
+    private static final String HTTP_CONTROL_LOOP_ELEMENT =
+            "org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement";
 
     @BeforeAll
     static void init() throws CoderException {
@@ -57,7 +61,11 @@ class ClElementHandlerTest {
     void test_ControlLoopElementUpdate() {
         doNothing().when(controlLoopElementHandler).invokeHttpClient(any());
         ControlLoopElement element = commonTestData.getControlLoopElement();
+
+        Map<String, ToscaNodeTemplate> nodeTemplatesMap =
+            serviceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+
         assertDoesNotThrow(() -> controlLoopElementHandler
-            .controlLoopElementUpdate(element, serviceTemplate));
+            .controlLoopElementUpdate(element, nodeTemplatesMap.get(HTTP_CONTROL_LOOP_ELEMENT)));
     }
 }
index 20a23ca..3f59c08 100644 (file)
@@ -44,7 +44,6 @@ import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -122,41 +121,31 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
      * Callback method to handle an update on a control loop element.
      *
      * @param element the information on the control loop element
-     * @param controlLoopDefinition toscaServiceTemplate
+     * @param nodeTemplate toscaNodeTemplate
      * @throws PfModelException in case of an exception
      */
     @Override
     public synchronized void controlLoopElementUpdate(ControlLoopElement element,
-                                                      ToscaServiceTemplate controlLoopDefinition)
-        throws PfModelException {
-
-        for (Map.Entry<String, ToscaNodeTemplate> nodeTemplate : controlLoopDefinition.getToscaTopologyTemplate()
-            .getNodeTemplates().entrySet()) {
-
-            // Fetching the node template of corresponding CL element
-            if (element.getDefinition().getName().equals(nodeTemplate.getKey())
-                && nodeTemplate.getValue().getProperties().containsKey("chart")) {
-                @SuppressWarnings("unchecked")
-                Map<String, Object> chartData =
-                    (Map<String, Object>) nodeTemplate.getValue().getProperties().get("chart");
-
-                LOGGER.info("Installation request received for the Helm Chart {} ", chartData);
-                try {
-                    var chartInfo =  CODER.decode(String.valueOf(chartData), ChartInfo.class);
-                    var repositoryValue = chartData.get("repository");
-                    if (repositoryValue != null) {
-                        chartInfo.setRepository(repositoryValue.toString());
-                    }
-                    chartService.installChart(chartInfo);
-                    chartMap.put(element.getId(), chartInfo);
+            ToscaNodeTemplate nodeTemplate) throws PfModelException {
+        @SuppressWarnings("unchecked")
+        Map<String, Object> chartData =
+            (Map<String, Object>) nodeTemplate.getProperties().get("chart");
+
+        LOGGER.info("Installation request received for the Helm Chart {} ", chartData);
+        try {
+            var chartInfo =  CODER.convert(chartData, ChartInfo.class);
+            var repositoryValue = chartData.get("repository");
+            if (repositoryValue != null) {
+                chartInfo.setRepository(repositoryValue.toString());
+            }
+            chartService.installChart(chartInfo);
+            chartMap.put(element.getId(), chartInfo);
 
-                    var config = CODER.convert(nodeTemplate.getValue().getProperties(), ThreadConfig.class);
-                    checkPodStatus(chartInfo, config.uninitializedToPassiveTimeout, config.podStatusCheckInterval);
+            var config = CODER.convert(nodeTemplate.getProperties(), ThreadConfig.class);
+            checkPodStatus(chartInfo, config.uninitializedToPassiveTimeout, config.podStatusCheckInterval);
 
-                } catch (ServiceException | CoderException | IOException e) {
-                    LOGGER.warn("Installation of Helm chart failed", e);
-                }
-            }
+        } catch (ServiceException | CoderException | IOException e) {
+            LOGGER.warn("Installation of Helm chart failed", e);
         }
     }
 
index f8381ee..03d5b31 100644 (file)
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.doThrow;
 import java.io.File;
 import java.io.IOException;
 import java.util.List;
+import java.util.Map;
 import java.util.UUID;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
@@ -52,6 +53,7 @@ import org.onap.policy.common.utils.coder.CoderException;
 import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
@@ -64,6 +66,8 @@ class ControlLoopElementHandlerTest {
     private static final String KEY_NAME = "org.onap.domain.database.HelloWorld_K8SMicroserviceControlLoopElement";
     private static List<ChartInfo> charts;
     private static ToscaServiceTemplate toscaServiceTemplate;
+    private static final String K8S_CONTROL_LOOP_ELEMENT =
+        "org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement";
 
 
     @InjectMocks
@@ -118,7 +122,9 @@ class ControlLoopElementHandlerTest {
         element.setDefinition(new ToscaConceptIdentifier(KEY_NAME, "1.0.1"));
         element.setOrderedState(ControlLoopOrderedState.PASSIVE);
 
-        controlLoopElementHandler.controlLoopElementUpdate(element, toscaServiceTemplate);
+        Map<String, ToscaNodeTemplate> nodeTemplatesMap =
+                toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+        controlLoopElementHandler.controlLoopElementUpdate(element, nodeTemplatesMap.get(K8S_CONTROL_LOOP_ELEMENT));
 
         assertThat(controlLoopElementHandler.getChartMap()).hasSize(1).containsKey(elementId1);
 
@@ -127,7 +133,7 @@ class ControlLoopElementHandlerTest {
 
         UUID elementId2 = UUID.randomUUID();
         element.setId(elementId2);
-        controlLoopElementHandler.controlLoopElementUpdate(element, toscaServiceTemplate);
+        controlLoopElementHandler.controlLoopElementUpdate(element, nodeTemplatesMap.get(K8S_CONTROL_LOOP_ELEMENT));
 
         assertThat(controlLoopElementHandler.getChartMap().containsKey(elementId2)).isFalse();
     }
index 1b176f0..6051504 100644 (file)
@@ -35,6 +35,7 @@ import org.onap.policy.clamp.controlloop.participant.intermediary.api.Participan
 import org.onap.policy.clamp.controlloop.participant.policy.client.PolicyApiHttpClient;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.base.PfModelRuntimeException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicy;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
@@ -115,32 +116,35 @@ public class ControlLoopElementHandler implements ControlLoopElementListener {
      * Callback method to handle an update on a control loop element.
      *
      * @param element the information on the control loop element
-     * @param controlLoopDefinition toscaServiceTemplate
+     * @param clElementDefinition toscaNodeTemplate
      * @throws PfModelException in case of an exception
      */
     @Override
-    public void controlLoopElementUpdate(ControlLoopElement element, ToscaServiceTemplate controlLoopDefinition)
+    public void controlLoopElementUpdate(ControlLoopElement element, ToscaNodeTemplate clElementDefinition)
             throws PfModelException {
         intermediaryApi.updateControlLoopElementState(element.getId(), element.getOrderedState(),
                 ControlLoopState.PASSIVE);
-        if (controlLoopDefinition.getPolicyTypes() != null) {
-            for (ToscaPolicyType policyType : controlLoopDefinition.getPolicyTypes().values()) {
-                policyTypeMap.put(policyType.getName(), policyType.getVersion());
+        ToscaServiceTemplate controlLoopDefinition = intermediaryApi.getToscaServiceTemplate();
+        if (controlLoopDefinition.getToscaTopologyTemplate() != null) {
+            if (controlLoopDefinition.getPolicyTypes() != null) {
+                for (ToscaPolicyType policyType : controlLoopDefinition.getPolicyTypes().values()) {
+                    policyTypeMap.put(policyType.getName(), policyType.getVersion());
+                }
+                LOGGER.debug("Found Policy Types in control loop definition: {} , Creating Policy Types",
+                        controlLoopDefinition.getName());
+                apiHttpClient.createPolicyType(controlLoopDefinition);
             }
-            LOGGER.debug("Found Policy Types in control loop definition: {} , Creating Policy Types",
-                    controlLoopDefinition.getName());
-            apiHttpClient.createPolicyType(controlLoopDefinition);
-        }
-        if (controlLoopDefinition.getToscaTopologyTemplate().getPolicies() != null) {
-            for (Map<String, ToscaPolicy> foundPolicyMap : controlLoopDefinition.getToscaTopologyTemplate()
-                    .getPolicies()) {
-                for (ToscaPolicy policy : foundPolicyMap.values()) {
-                    policyMap.put(policy.getName(), policy.getVersion());
+            if (controlLoopDefinition.getToscaTopologyTemplate().getPolicies() != null) {
+                for (Map<String, ToscaPolicy> foundPolicyMap : controlLoopDefinition.getToscaTopologyTemplate()
+                        .getPolicies()) {
+                    for (ToscaPolicy policy : foundPolicyMap.values()) {
+                        policyMap.put(policy.getName(), policy.getVersion());
+                    }
                 }
+                LOGGER.debug("Found Policies in control loop definition: {} , Creating Policies",
+                        controlLoopDefinition.getName());
+                apiHttpClient.createPolicy(controlLoopDefinition);
             }
-            LOGGER.debug("Found Policies in control loop definition: {} , Creating Policies",
-                    controlLoopDefinition.getName());
-            apiHttpClient.createPolicy(controlLoopDefinition);
         }
     }
 
index 08e7154..df9a4b2 100644 (file)
 package org.onap.policy.clamp.controlloop.participant.policy.endtoend;
 
 import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.junit.Assert.assertEquals;
 
 import java.time.Instant;
+import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -36,6 +38,8 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopInfo;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopStatistics;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregister;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantDeregisterAck;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister;
@@ -43,6 +47,7 @@ import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.Parti
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantStatus;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck;
+import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ControlLoopUpdateListener;
 import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantDeregisterAckListener;
 import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantMessagePublisher;
 import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantRegisterAckListener;
@@ -52,7 +57,7 @@ import org.onap.policy.clamp.controlloop.participant.policy.main.utils.TestListe
 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
 import org.onap.policy.common.endpoints.event.comm.TopicSink;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
@@ -135,6 +140,9 @@ class ParticipantMessagesTest {
             ParticipantUpdateListener participantUpdateListener = new ParticipantUpdateListener(participantHandler);
             participantUpdateListener.onTopicEvent(INFRA, TOPIC, null, participantUpdateMsg);
         }
+
+        // Verify the result of GET participants with what is stored
+        assertEquals("org.onap.PM_Policy", participantHandler.getParticipantId().getName());
     }
 
     @Test
@@ -156,13 +164,17 @@ class ParticipantMessagesTest {
         final ParticipantStatus heartbeat = new ParticipantStatus();
         heartbeat.setParticipantId(getParticipantId());
         ControlLoopInfo clInfo = getControlLoopInfo(getControlLoopId());
-        heartbeat.setControlLoopInfoMap(Map.of(getControlLoopId().toString(), clInfo));
+        clInfo.setControlLoopId(getControlLoopId());
+        heartbeat.setControlLoopInfoList(List.of(clInfo));
 
         ControlLoopElementDefinition clDefinition = getClElementDefinition();
-        Map<UUID, ControlLoopElementDefinition> clElementDefinitionMap = Map.of(UUID.randomUUID(), clDefinition);
-        Map<String, Map<UUID, ControlLoopElementDefinition>>
-            participantDefinitionUpdateMap = Map.of(getParticipantId().toString(), clElementDefinitionMap);
-        heartbeat.setParticipantDefinitionUpdateMap(participantDefinitionUpdateMap);
+        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);
 
         synchronized (lockit) {
             ParticipantMessagePublisher publisher =
@@ -208,15 +220,15 @@ class ParticipantMessagesTest {
     }
 
     private ControlLoopElementDefinition getClElementDefinition() {
-        ToscaServiceTemplate toscaServiceTemplate = new ToscaServiceTemplate();
-        toscaServiceTemplate.setName("serviceTemplate");
-        toscaServiceTemplate.setDerivedFrom("parentServiceTemplate");
-        toscaServiceTemplate.setDescription("Description of serviceTemplate");
-        toscaServiceTemplate.setVersion("1.2.3");
+        ToscaNodeTemplate toscaNodeTemplate = new ToscaNodeTemplate();
+        toscaNodeTemplate.setName("serviceTemplate");
+        toscaNodeTemplate.setDerivedFrom("parentServiceTemplate");
+        toscaNodeTemplate.setDescription("Description of serviceTemplate");
+        toscaNodeTemplate.setVersion("1.2.3");
 
         ControlLoopElementDefinition clDefinition = new ControlLoopElementDefinition();
-        clDefinition.setId(UUID.randomUUID());
-        clDefinition.setControlLoopElementToscaServiceTemplate(toscaServiceTemplate);
+        clDefinition.setCommonPropertiesMap(Map.of("Prop1", "Prop1Value"));
+        clDefinition.setControlLoopElementToscaNodeTemplate(toscaNodeTemplate);
         Map<String, String> commonPropertiesMap = Map.of("Prop1", "PropValue");
         clDefinition.setCommonPropertiesMap(commonPropertiesMap);
         return clDefinition;
diff --git a/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/endtoend/ParticipantPolicyTest.java b/participant/participant-impl/participant-impl-policy/src/test/java/org/onap/policy/clamp/controlloop/participant/policy/endtoend/ParticipantPolicyTest.java
deleted file mode 100644 (file)
index 10563cd..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-/*-
- * ============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.policy.endtoend;
-
-import static org.junit.Assert.assertEquals;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
-import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange;
-import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate;
-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.handler.ParticipantHandler;
-import org.onap.policy.clamp.controlloop.participant.policy.main.utils.TestListenerUtils;
-import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.test.context.SpringBootTest;
-import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
-import org.springframework.test.context.TestPropertySource;
-import org.springframework.test.context.junit.jupiter.SpringExtension;
-
-@ExtendWith(SpringExtension.class)
-@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
-@TestPropertySource(locations = {"classpath:application_test.properties"})
-class ParticipantPolicyTest {
-
-    private static final Object lockit = new Object();
-    private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
-    private static final String TOPIC = "my-topic";
-
-    @Autowired
-    private ParticipantHandler participantHandler;
-
-    @Test
-    void testUpdatePolicyTypes() {
-        ControlLoopUpdate controlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg();
-        controlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE);
-
-        synchronized (lockit) {
-            ControlLoopUpdateListener clUpdateListener = new ControlLoopUpdateListener(participantHandler);
-
-            clUpdateListener.onTopicEvent(INFRA, TOPIC, null, controlLoopUpdateMsg);
-        }
-        // Verify the result of GET participants with what is stored
-        assertEquals("org.onap.PM_Policy", participantHandler.getParticipantId().getName());
-    }
-
-    @Test
-    void testUpdatePolicies() throws Exception {
-        ControlLoopUpdate controlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg();
-        controlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE);
-
-        synchronized (lockit) {
-            ControlLoopUpdateListener clUpdateListener = new ControlLoopUpdateListener(participantHandler);
-
-            clUpdateListener.onTopicEvent(INFRA, TOPIC, null, controlLoopUpdateMsg);
-        }
-        // Verify the result of GET participants with what is stored
-        assertEquals("org.onap.PM_Policy", participantHandler.getParticipantId().getName());
-    }
-
-    @Test
-    void testDeletePoliciesAndPolicyTypes() throws Exception {
-        ControlLoopUpdate controlLoopUpdateMsg = TestListenerUtils.createControlLoopUpdateMsg();
-        controlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE);
-
-        synchronized (lockit) {
-            ControlLoopUpdateListener clUpdateListener = new ControlLoopUpdateListener(participantHandler);
-
-            clUpdateListener.onTopicEvent(INFRA, TOPIC, null, controlLoopUpdateMsg);
-        }
-        // Verify the result of GET participants with what is stored
-        assertEquals("org.onap.PM_Policy", participantHandler.getParticipantId().getName());
-
-        ControlLoopStateChangeListener clStateChangeListener = new ControlLoopStateChangeListener(participantHandler);
-        ControlLoopStateChange controlLoopStateChangeMsg =
-                TestListenerUtils.createControlLoopStateChangeMsg(ControlLoopOrderedState.UNINITIALISED);
-        controlLoopStateChangeMsg.setOrderedState(ControlLoopOrderedState.UNINITIALISED);
-        clStateChangeListener.onTopicEvent(INFRA, TOPIC, null, controlLoopStateChangeMsg);
-
-        // Verify the result of GET participants with what is stored
-        assertEquals("org.onap.PM_Policy", participantHandler.getParticipantId().getName());
-    }
-}
index f87714e..5984cf1 100644 (file)
@@ -25,7 +25,9 @@ import static org.junit.Assert.assertTrue;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.time.Instant;
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
@@ -34,6 +36,8 @@ 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.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.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
@@ -55,6 +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 TestListenerUtils() {}
 
@@ -130,47 +135,80 @@ public class TestListenerUtils {
      */
     public static ControlLoopUpdate createControlLoopUpdateMsg() {
         final ControlLoopUpdate clUpdateMsg = new ControlLoopUpdate();
-        ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier();
-        controlLoopId.setName("PMSHInstance0");
-        controlLoopId.setVersion("1.0.0");
-
-        ToscaConceptIdentifier participantId = new ToscaConceptIdentifier();
-        participantId.setName("org.onap.PM_Policy");
-        participantId.setVersion("0.0.0");
+        ToscaConceptIdentifier controlLoopId =
+            new ToscaConceptIdentifier("PMSHInstance0", "1.0.0");
+        ToscaConceptIdentifier participantId =
+            new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0");
 
         clUpdateMsg.setControlLoopId(controlLoopId);
         clUpdateMsg.setParticipantId(participantId);
+        clUpdateMsg.setMessageId(UUID.randomUUID());
+        clUpdateMsg.setTimestamp(Instant.now());
 
-        ControlLoop controlLoop = new ControlLoop();
         Map<UUID, ControlLoopElement> elements = new LinkedHashMap<>();
         ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
         Map<String, ToscaNodeTemplate> nodeTemplatesMap =
                 toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : nodeTemplatesMap.entrySet()) {
-            ControlLoopElement clElement = new ControlLoopElement();
-            clElement.setId(UUID.randomUUID());
+            if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
+                ControlLoopElement clElement = new ControlLoopElement();
+                clElement.setId(UUID.randomUUID());
+                ToscaConceptIdentifier clParticipantId;
+                try {
+                    clParticipantId = CODER.decode(
+                            toscaInputEntry.getValue().getProperties().get("participant_id").toString(),
+                            ToscaConceptIdentifier.class);
+                } catch (CoderException e) {
+                    throw new RuntimeException("cannot get ParticipantId from toscaNodeTemplate", e);
+                }
 
-            ToscaConceptIdentifier clElementParticipantId = new ToscaConceptIdentifier();
-            clElementParticipantId.setName(toscaInputEntry.getKey());
-            clElementParticipantId.setVersion(toscaInputEntry.getValue().getVersion());
-            clElement.setParticipantId(clElementParticipantId);
-            clElement.setParticipantType(clElementParticipantId);
+                clElement.setParticipantId(clParticipantId);
+                clElement.setParticipantType(clParticipantId);
 
-            clElement.setDefinition(clElementParticipantId);
-            clElement.setState(ControlLoopState.UNINITIALISED);
-            clElement.setDescription(toscaInputEntry.getValue().getDescription());
-            clElement.setOrderedState(ControlLoopOrderedState.UNINITIALISED);
-            elements.put(clElement.getId(), clElement);
+                clElement.setDefinition(new ToscaConceptIdentifier(toscaInputEntry.getKey(),
+                    toscaInputEntry.getValue().getVersion()));
+                clElement.setState(ControlLoopState.UNINITIALISED);
+                clElement.setDescription(toscaInputEntry.getValue().getDescription());
+                clElement.setOrderedState(ControlLoopOrderedState.PASSIVE);
+                elements.put(clElement.getId(), clElement);
+            }
         }
-        controlLoop.setElements(elements);
-        controlLoop.setName("PMSHInstance0");
-        controlLoop.setVersion("1.0.0");
-        controlLoop.setDefinition(controlLoopId);
-        clUpdateMsg.setControlLoop(controlLoop);
 
+        List<ParticipantUpdates> participantUpdates = new ArrayList<>();
+        for (ControlLoopElement element : elements.values()) {
+            prepareParticipantUpdateForControlLoop(element, participantUpdates);
+        }
+        clUpdateMsg.setParticipantUpdatesList(participantUpdates);
         return clUpdateMsg;
     }
 
+    private static void prepareParticipantUpdateForControlLoop(ControlLoopElement clElement,
+        List<ParticipantUpdates> participantUpdates) {
+        if (participantUpdates.isEmpty()) {
+            participantUpdates.add(getControlLoopElementList(clElement));
+        } else {
+            boolean participantExists = false;
+            for (ParticipantUpdates participantUpdate : participantUpdates) {
+                if (participantUpdate.getParticipantId().equals(clElement.getParticipantId())) {
+                    participantUpdate.getControlLoopElementList().add(clElement);
+                    participantExists = true;
+                }
+            }
+            if (!participantExists) {
+                participantUpdates.add(getControlLoopElementList(clElement));
+            }
+        }
+    }
+
+    private static ParticipantUpdates getControlLoopElementList(ControlLoopElement clElement) {
+        ParticipantUpdates participantUpdate = new ParticipantUpdates();
+        List<ControlLoopElement> controlLoopElementList = new ArrayList<>();
+        participantUpdate.setParticipantId(clElement.getParticipantId());
+        controlLoopElementList.add(clElement);
+        participantUpdate.setControlLoopElementList(controlLoopElementList);
+        return participantUpdate;
+    }
+
     /**
      * Method to create participantUpdateMsg.
      *
@@ -192,20 +230,63 @@ public class TestListenerUtils {
         // Add policies to the toscaServiceTemplate
         TestListenerUtils.addPoliciesToToscaServiceTemplate(toscaServiceTemplate);
 
-        ControlLoopElementDefinition clDefinition = new ControlLoopElementDefinition();
-        clDefinition.setId(UUID.randomUUID());
-        clDefinition.setControlLoopElementToscaServiceTemplate(toscaServiceTemplate);
-        Map<String, String> commonPropertiesMap = Map.of("Prop1", "PropValue");
-        clDefinition.setCommonPropertiesMap(commonPropertiesMap);
+        List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
+        for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry :
+            toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
+            if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
+                ToscaConceptIdentifier clParticipantId;
+                try {
+                    clParticipantId = CODER.decode(
+                            toscaInputEntry.getValue().getProperties().get("participant_id").toString(),
+                            ToscaConceptIdentifier.class);
+                } catch (CoderException e) {
+                    throw new RuntimeException("cannot get ParticipantId from toscaNodeTemplate", e);
+                }
+                prepareParticipantDefinitionUpdate(clParticipantId, toscaInputEntry.getKey(),
+                    toscaInputEntry.getValue(), participantDefinitionUpdates);
+            }
+        }
 
-        Map<UUID, ControlLoopElementDefinition> controlLoopElementDefinitionMap =
-                Map.of(UUID.randomUUID(), clDefinition);
+        participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates);
+        participantUpdateMsg.setToscaServiceTemplate(toscaServiceTemplate);
+        return participantUpdateMsg;
+    }
 
-        Map<String, Map<UUID, ControlLoopElementDefinition>> participantDefinitionUpdateMap =
-                Map.of(participantId.toString(), controlLoopElementDefinitionMap);
-        participantUpdateMsg.setParticipantDefinitionUpdateMap(participantDefinitionUpdateMap);
+    private static void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantId, String entryKey,
+        ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) {
+
+        var clDefinition = new ControlLoopElementDefinition();
+        clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(
+            entryKey, entryValue.getVersion()));
+        clDefinition.setControlLoopElementToscaNodeTemplate(entryValue);
+        List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>();
+
+        if (participantDefinitionUpdates.isEmpty()) {
+            participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
+                controlLoopElementDefinitionList));
+        } else {
+            boolean participantExists = false;
+            for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) {
+                if (participantDefinitionUpdate.getParticipantId().equals(clParticipantId)) {
+                    participantDefinitionUpdate.getControlLoopElementDefinitionList().add(clDefinition);
+                    participantExists = true;
+                }
+            }
+            if (!participantExists) {
+                participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
+                    controlLoopElementDefinitionList));
+            }
+        }
+    }
 
-        return participantUpdateMsg;
+    private static ParticipantDefinition getParticipantDefinition(ControlLoopElementDefinition clDefinition,
+        ToscaConceptIdentifier clParticipantId,
+        List<ControlLoopElementDefinition> controlLoopElementDefinitionList) {
+        ParticipantDefinition participantDefinition = new ParticipantDefinition();
+        participantDefinition.setParticipantId(clParticipantId);
+        controlLoopElementDefinitionList.add(clDefinition);
+        participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
+        return participantDefinition;
     }
 
     /**
index c2ffb40..4b8e359 100644 (file)
@@ -136,7 +136,7 @@ topology_template:
       description: Control loop element for CDS for Performance Management Subscription Handling
       properties:
         provider: Ericsson
-        participant_Id:
+        participant_id:
           name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant
           version: 3.2.1
         cds_blueprint_id:
index 7d92a08..8615bdb 100644 (file)
 tosca_definitions_version: tosca_simple_yaml_1_3
-policy_types:
-   onap.policies.Monitoring:
-      derived_from: tosca.policies.Root
-      version: 1.0.0
-      name: onap.policies.Monitoring
-      description: a base policy type for all policies that govern monitoring provisioning
-   onap.policies.monitoring.dcae-pm-subscription-handler:
-      derived_from: onap.policies.Monitoring
-      version: 1.0.0
-      properties:
-         subscription:
-            type: map
-            description: PM Subscription Handler Subscription
-            entry_schema:
-               type: onap.datatypes.monitoring.subscription
 data_types:
-   onap.datatypes.monitoring.subscription:
-      derived_from: tosca.datatypes.Root
-      properties:
-         subscriptionName:
-            type: string
-            description: Name of the subscription
-            required: true
-         administrativeState:
-            type: string
-            description: State of the subscription
-            required: true
-            constraints:
-            -  valid_values:
-               - LOCKED
-               - UNLOCKED
-         fileBasedGP:
-            type: integer
-            description: File based granularity period
-            required: true
-         fileLocation:
-            type: string
-            description: ROP file location
-            required: true
-         nfTypeModelInvariantId:
-            type: string
-            description: Network function invariant ID
-            required: true
-         nfFilter:
-            type: map
-            description: Network function filter
-            required: true
-            entry_schema:
-               type: onap.datatypes.monitoring.nfFilter
-         measurementGroups:
-            type: list
-            description: Measurement Groups
-            required: true
-            entry_schema:
-               type: onap.datatypes.monitoring.measurementGroups
-   onap.datatypes.monitoring.nfFilter:
-      derived_from: tosca.datatypes.Root
-      properties:
-         nfNames:
-            type: list
-            description: List of network functions
-            required: true
-            #default: []
-            entry_schema:
-               type: string
-         swVersions:
-            type: list
-            description: List of software versions
-            required: true
-            #default: []
-            entry_schema:
-               type: string
-   onap.datatypes.monitoring.measurementGroups:
-      derived_from: tosca.datatypes.Root
-      properties:
-         measurementGroup:
-            type: map
-            description: Measurement Group
-            required: true
-            entry_schema:
-               type: onap.datatypes.monitoring.measurementGroup
-   onap.datatypes.monitoring.measurementGroup:
-      derived_from: tosca.datatypes.Root
-      properties:
-         measurementTypes:
-            type: list
-            description: List of measurement types
-            required: true
-            #default: []
-            entry_schema:
-               type: onap.datatypes.monitoring.measurementTypes
-         managedObjectDNsBasic:
-            type: list
-            description: List of managed object distinguished names
-            required: true
-            #default: []
-            entry_schema:
-               type: onap.datatypes.monitoring.managedObjectDNsBasics
-   onap.datatypes.monitoring.measurementTypes:
-      derived_from: tosca.datatypes.Root
-      properties:
-         measurementType:
-            type: map
-            description: Measurement type object
-            required: true
-            entry_schema:
-               type: onap.datatypes.monitoring.measurementType
-   onap.datatypes.monitoring.measurementType:
-      derived_from: tosca.datatypes.Root
-      properties:
-         measurementType:
-            type: string
-            description: Measurement type
-            required: true
-   onap.datatypes.monitoring.managedObjectDNsBasics:
-      derived_from: tosca.datatypes.Root
-      properties:
-         managedObjectDNsBasic:
-            type: map
-            description: Managed object distinguished name object
-            required: true
-            entry_schema:
-               type: onap.datatypes.monitoring.managedObjectDNsBasic
-   onap.datatypes.monitoring.managedObjectDNsBasic:
-      derived_from: tosca.datatypes.Root
-      properties:
-         DN:
-            type: string
-            description: Managed object distinguished name
-            required: true
-capability_types:
-  org.onap.EventProducer:
+  onap.datatypes.ToscaConceptIdentifier:
+    derived_from: tosca.datatypes.Root
     properties:
-      carrier_protocol_type:
-        type: string
-        required: true
-        constraints:
-        - valid_values:
-          - DMAAP_message_router
-          - SOMETHING_ELSE
-          - REST
-      data_format:
+      name:
         type: string
         required: true
-        constraints:
-        - valid_values:
-          - JSON
-          - YAML
-          - JMS
-      event_format:
+      version:
         type: string
         required: true
-      event_format_version:
-        type: string
-        required: false
-      config_keys:
-        type: list
-        required: false
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - all valid values should be added here
-            - if not specified, events of any config key may be generated
-            - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out,
-              etc.'
-    version: 0.0.1
-    derived_from: tosca.capabilities.Root
-  org.onap.EventConsumer:
-    properties:
-      responding_capability:
-        type: string
-        required: false
-      carrier_protocol_type:
-        type: string
-        required: true
-        constraints:
-        - valid_values:
-          - DMAAP_message_router
-          - SOMETHING_ELSE
-          - REST
-      data_format:
-        type: string
-        required: true
-        constraints:
-        - valid_values:
-          - JSON
-          - YAML
-          - JMS
-          - all valid values should be added here
-      event_format:
-        type: string
-        description: 'examples for event_format: Ves_specification, LinkUp, VnfConfigured,
-          etc.'
-        required: true
-      event_format_version:
-        type: string
-        description: 'examples for event_format_version: 5.28.4, 7.30.1, etc.'
-        required: false
-      config_keys:
-        type: list
-        required: false
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - all valid values should be added here
-            - if not specified, events of any config key may be generated
-            - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out,
-              etc.'
-    version: 0.0.1
-    derived_from: tosca.capabilities.Root
 node_types:
-  org.onap.DynamicConfig:
+  org.onap.policy.clamp.controlloop.Participant:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
     properties:
-      application_name:
-        type: string
-        description: Value used to tie the config to an application ? should we be
-          using a relationship here instead?
-        required: true
-      application_version:
-        type: string
-        required: true
-      application_provider:
+      provider:
         type: string
-        required: false
-      data_types:
-        type: object
-        required: false
-      schema:
-        type: object
-        required: false
-    version: 0.0.1
-    derived_from: tosca.nodes.Root
-  org.onap.APP:
+        requred: false
+  org.onap.policy.clamp.controlloop.ControlLoopElement:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
     properties:
-      application_name:
-        type: string
-        description: Human readable name for the application Product
-        required: false
       provider:
         type: string
-        description: Provider of the application and of the descriptor
-        required: true
-      application_version:
-        type: string
-        description: Software version of the application
-        required: true
-      blueprint_id:
-        type: string
-        description: A reference to the app blueprint
-        required: false
-      monitoring_policy:
-        type: string
-        description: A reference to the monitoring policy
-        required: false
-    requirements:
-    - receive:
-        capability: org.onap.EventProducer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        type: string
-        type_version: 0.0.0
-        version: 0.0.0
-    - send:
-        capability: org.onap.EventConsumer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        type: string
-        type_version: 0.0.0
-        version: 0.0.0
-    version: 0.0.1
-    derived_from: tosca.nodes.Root
-  org.onap.EventRelay:
+        requred: false
+      participant_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+  org.onap.policy.clamp.controlloop.ControlLoop:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
     properties:
-      event_format:
-        type: string
-        description: 'examples for event_format: Ves_specification, etc.'
-        required: true
-      event_format_version:
+      provider:
         type: string
-        description: 'examples for event_format_version: 5.28.4, 7.30.1, etc.'
-        required: true
-      config_keys:
+        requred: false
+      elements:
         type: list
-        required: false
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - all valid values should be added here
-            - if not specified, events of any config key is relayed
-            - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out,
-              etc.'
-      supported_carrier_protocols:
-        type: map
-        description: 'A map describing supported carrier protocols and translations.
-          The tuples define what protocol combinations are supported on the producer
-          and consumer side: e.g. { REST: REST, DMAAP: REST, DMAAP: DMAAP}'
-        required: true
-        key_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - DMAAP_message_router
-            - SOMETHING_ELSE
-            - REST
-            - all valid values should be added here
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - DMAAP_message_router
-            - SOMETHING_ELSE
-            - REST
-            - all valid values should be added here
-      supported_data_formats:
-        type: map
-        description: 'Is a map describing supported data formats and translation.
-          The tuples define what protocol combinations are supported on the producer
-          and consumer side: e.g. { JSON: JSON, JMS: JSON, YAML:YAML }'
         required: true
-        key_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - JSON
-            - JMS
-            - YAML
-            - etc
-            - all valid values should be added here
         entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - JSON
-            - JMS
-            - YAML
-            - etc
-            - all valid values should be added here
-    requirements:
-    - receive:
-        capability: org.onap.EventProducer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        type: string
-        type_version: 0.0.0
-        version: 0.0.0
-    - send:
-        capability: org.onap.EventConsumer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        type: string
-        type_version: 0.0.0
-        version: 0.0.0
-    version: 0.0.1
-    derived_from: tosca.nodes.Root
-relationship_types:
-  org.onap.PropagateEvent:
+          type: onap.datatypes.ToscaConceptIdentifier
+  org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
     properties:
-      config_keys:
-        type: list
-        description: The relationship type used on requirements to org.onap.EventProducer
-          and org.onap.EventConsumer capabilities. Filters events by specific config_keys
-          to be transferred by this relationship. That is, any event with a specific
-          config_key found in the list is transferred. If list is not defined or is
-          empty, events with all config_keys are transferred.
-        required: false
-        entry_schema:
-          type: string
-    version: 0.0.1
-    derived_from: tosca.relationships.Root
+      dcae_blueprint_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+  org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
+    properties:
+      policy_type_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+  org.onap.policy.clamp.controlloop.CDSControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
+    properties:
+      cds_blueprint_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
 topology_template:
-  inputs:
-    pm_subscription_topic:
-      type: string
-    pm_subscription_response_topic:
-      type: string
-    pm_subscription_handler_blueprint_id:
-      type: string
-    pm_subscription_operational_policy_id:
-      type: string
-    pm_subscription_cds_blueprint_id:
-      type: string
-    enable_tls:
-      type: string
   node_templates:
-    org.onap.PM_Subscription_Handler:
-      type: org.onap.APP
-      type_version: 0.0.0
+    org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant:
+      version: 2.3.4
+      type: org.onap.policy.clamp.controlloop.Participant
+      type_version: 1.0.1
+      description: Participant for DCAE microservices
+      properties:
+        provider: ONAP
+    org.onap.policy.controlloop.PolicyControlLoopParticipant:
+      version: 2.3.1
+      type: org.onap.policy.clamp.controlloop.Participant
+      type_version: 1.0.1
+      description: Participant for DCAE microservices
+      properties:
+        provider: ONAP
+    org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant:
+      version: 2.2.1
+      type: org.onap.policy.clamp.controlloop.Participant
+      type_version: 1.0.1
+      description: Participant for DCAE microservices
+      properties:
+        provider: ONAP
+    org.onap.domain.pmsh.PMSH_DCAEMicroservice:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the DCAE microservice for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription Handler
         provider: Ericsson
-        application_version: 1.0.0
-        artifact_id:
-          get_input: pm_subscription_handler_blueprint_id
-          description: Is this a reference to the DCAE Cloudify Blueprint that is
-            already stored(or will be stored before CL configuration & instatiation)
-            in DCAE Inventory?
-        artifact_config:
-          enable_tls:
-            get_input: enable_tls
-          pmsh_publish_topic_name:
-            get_input: pm_subscription_topic
-      capabilities:
-        pm-subscription-event-publisher:
-          properties:
-            carrier_protocol_type: DMAAP_message_router
-            data_format: JSON
-            event_format: pm-subscription-event-format
-            event_format_version: 1.0.0
-          attributes:
-            type: org.onap.EventProducer
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          type: string
-          type_version: 0.0.0
-          version: 0.0.0
-        pm-subscription-event-receiver:
-          properties:
-            carrier_protocol_type: DMAAP_message_router
-            data_format: JSON
-            event_format: pm-subscription-event-response-format
-            event_format_version: 1.0.0
-            relationships:
-            - type: tosca.relationships.DependsOn
-            - description: any ideas on a better realtionship ? or is it better to
-                just use the root realtionship ?
-            - target: org.onap.PM_Monitoring_Policy
-          attributes:
-            type: org.onap.EventConsumer
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          type: string
-          type_version: 0.0.0
-          version: 0.0.0
-      version: 0.0.0
-    org.onap.PM_Monitoring_Policy:
-      type: org.onap.DynamicConfig
-      type_version: 0.0.0
+        participant_id:
+          name: org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant
+          version: 2.3.4
+        dcae_blueprint_id:
+          name: org.onap.dcae.blueprints.PMSHBlueprint
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the monitoring policy for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription Handler
-        application_version: 1.0.0
         provider: Ericsson
-        data_types:
-          measurementType:
-            type: string
-          DN:
-            type: string
-          nfFilter:
-            properties:
-              nfNames:
-                type: list
-                entry_schema: string
-              modelInvariantIDs:
-                type: list
-                entry_schema:
-                  type: string
-              modelVersionIDs:
-                type: list
-                entry_schema:
-                  type: string
-          measurementGroup:
-            properties:
-              masurementTypes:
-                type: list
-                entry_schema:
-                  type: measurementType
-              managedObjectDNsBasic:
-                type: list
-                entry_schema:
-                  type: DN
-        schema:
-          subscription:
-            subscriptionName:
-              type: string
-              required: true
-            administrativeState:
-              type: string
-              required: true
-            filebasedGP:
-              type: integer
-              required: true
-            fileLocation:
-              type: string
-              required: true
-            nfFilter:
-              type: nfFilter
-            measurementGroups:
-              type: list
-              entry_schema:
-                type: measurementGroup
-      version: 0.0.0
-      description: Should I be showing a dependency between PM Subscription Handler
-        and the PM Monitoring Policy
-    org.onap.PM_Policy:
-      type: org.onap.APP
-      type_version: 0.0.0
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.3.1
+        policy_type_id:
+          name: onap.policies.monitoring.pm-subscription-handler
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the operational policy for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription Operational Policy
         provider: Ericsson
-        application_version: 1.0.0
-        artifact_id:
-          get_input: pm_subscription_operational_policy_id
-        artifact_config: NOT_DEFINED
-      requirements:
-      - receive_0:
-          capability: pm-subscription-event-publisher
-          node: org.onap.PM_Subscription_Handler
-          relationship: NOT_DEFINED
-          properties:
-            config_keys:
-            - topic_name:
-                get_input: pm_subscription_topic
-          type: string
-          type_version: 0.0.0
-          version: 0.0.0
-      - send_0:
-          capability: cds-rest-receive
-          node: org.onap.CDS
-          type: string
-          type_version: 0.0.0
-          version: 0.0.0
-      - receive_1:
-          capability: cds-rest-response
-          node: org.onap.CDS
-          type: string
-          type_version: 0.0.0
-          version: 0.0.0
-      - send_1:
-          capability: pm-subscription-event-receiver
-          node: org.onap.PM_Subscription_Handler
-          relationship: NOT_DEFINED
-          properties:
-            config_keys:
-            - topic_name:
-                get_input: pm_subscription_response_topic
-          type: string
-          type_version: 0.0.0
-          version: 0.0.0
-      capabilities:
-        pm-subscription-response-event-publisher:
-          properties:
-            type: org.onap.EventProducer
-            carrier_protocol_type: DMAAP_message_router
-            data_format: JSON
-            event_format: pm-subscription-event-response-format
-            event_format_version: 1.0.0
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          type: string
-          type_version: 0.0.0
-          version: 0.0.0
-      version: 0.0.0
-    org.onap.PM_CDS_Blueprint:
-      type: org.onap.APP
-      type_version: 0.0.0
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.3.1
+        policy_type_id:
+          name: onap.policies.operational.pm-subscription-handler
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.ControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for CDS for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription CDS Blueprint
         provider: Ericsson
-        application_version: 1.0.0
-        artifact_id:
-          get_input: pm_subscription_cds_blueprint_id
-      capabilities:
-        cds-rest-receive:
-          properties:
-            type: org.onap.EventConsumer
-            protocol_type: REST
-            data_format: JSON
-            event_format: cds_action_format
-            event_format_version: 1.0.0
-            responding_capability: cds-rest-response
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          type: string
-          type_version: 0.0.0
-          version: 0.0.0
-        cds-rest-response:
-          properties:
-            type: org.onap.EventProducer
-            protocol_type: REST
-            data_format: JSON
-            event_format: cds_action_response_format
-            event_format_version: 1.0.0
-          occurrences:
-          - 0.0
-          type: string
-          type_version: 0.0.0
-          version: 0.0.0
-      version: 0.0.0
-    org.onap.controlloop0:
-      type: org.onap.APP
-      type_version: 0.0.0
+        participant_id:
+          name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant
+          version: 3.2.1
+        cds_blueprint_id:
+          name: org.onap.ccsdk.cds.PMSHCdsBlueprint
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSHControlLoopDefinition:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.ControlLoop
+      type_version: 1.0.0
+      description: Control loop for Performance Management Subscription Handling
       properties:
-        application_name: Test Control Loop
         provider: Ericsson
-        application_version: 1.0.0
-        status: NOT_DEPLOYED
-      version: 0.0.0
-version: 0.0.0
-
+        elements:
+          - name: org.onap.domain.pmsh.PMSH_DCAEMicroservice
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement
+            version: 1.2.3
index beb50da..a9dea17 100644 (file)
@@ -105,7 +105,6 @@ class ParticipantSimulatorTest {
 
                 ControlLoopUpdate controlLoopUpdateMsg =
                         TestListenerUtils.createControlLoopUpdateMsg();
-                controlLoopUpdateMsg.getControlLoop().setOrderedState(ControlLoopOrderedState.PASSIVE);
                 clUpdateListener.onTopicEvent(INFRA, TOPIC, null, controlLoopUpdateMsg);
 
             }
@@ -275,10 +274,6 @@ class ParticipantSimulatorTest {
         UUID uuid = controlLoopElements.keySet().iterator().next();
         ControlLoopElement controlLoopElement = controlLoopElements.get(uuid);
 
-        // Check the initial state on the ControlLoopElement, which is UNINITIALISED
-        assertEquals(ControlLoopOrderedState.UNINITIALISED, controlLoopElement.getOrderedState());
-
-        // Change the state of the ControlLoopElement to PASSIVE from UNINITIALISED
         controlLoopElement.setOrderedState(ControlLoopOrderedState.PASSIVE);
 
         // PUT REST call for updating ControlLoopElement
index 999feb1..2b8de6a 100644 (file)
@@ -25,17 +25,22 @@ import static org.junit.Assert.assertTrue;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.time.Instant;
+import java.util.ArrayList;
 import java.util.LinkedHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 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.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.ParticipantState;
+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.ControlLoopStateChange;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate;
+import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
 import org.onap.policy.clamp.controlloop.participant.simulator.main.parameters.CommonTestData;
 import org.onap.policy.common.utils.coder.Coder;
 import org.onap.policy.common.utils.coder.CoderException;
@@ -54,6 +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 TestListenerUtils() {}
 
@@ -125,43 +131,159 @@ public class TestListenerUtils {
      */
     public static ControlLoopUpdate createControlLoopUpdateMsg() {
         final ControlLoopUpdate clUpdateMsg = new ControlLoopUpdate();
-        ToscaConceptIdentifier controlLoopId = new ToscaConceptIdentifier("PMSHInstance0", "1.0.0");
-        ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_CDS_Blueprint", "1.0.0");
+        ToscaConceptIdentifier controlLoopId =
+            new ToscaConceptIdentifier("PMSHInstance0", "1.0.0");
+        ToscaConceptIdentifier participantId =
+            new ToscaConceptIdentifier("org.onap.PM_Policy", "0.0.0");
 
         clUpdateMsg.setControlLoopId(controlLoopId);
         clUpdateMsg.setParticipantId(participantId);
-        clUpdateMsg.setParticipantType(participantId);
+        clUpdateMsg.setMessageId(UUID.randomUUID());
+        clUpdateMsg.setTimestamp(Instant.now());
 
-        ControlLoop controlLoop = new ControlLoop();
         Map<UUID, ControlLoopElement> elements = new LinkedHashMap<>();
         ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
         Map<String, ToscaNodeTemplate> nodeTemplatesMap =
                 toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
         for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry : nodeTemplatesMap.entrySet()) {
-            ControlLoopElement clElement = new ControlLoopElement();
-            clElement.setId(UUID.randomUUID());
+            if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
+                ControlLoopElement clElement = new ControlLoopElement();
+                clElement.setId(UUID.randomUUID());
+                ToscaConceptIdentifier clParticipantId;
+                try {
+                    clParticipantId = CODER.decode(
+                            toscaInputEntry.getValue().getProperties().get("participant_id").toString(),
+                            ToscaConceptIdentifier.class);
+                } catch (CoderException e) {
+                    throw new RuntimeException("cannot get ParticipantId from toscaNodeTemplate", e);
+                }
 
-            ToscaConceptIdentifier clElementParticipantId = new ToscaConceptIdentifier();
-            clElementParticipantId.setName(toscaInputEntry.getKey());
-            clElementParticipantId.setVersion(toscaInputEntry.getValue().getVersion());
-            clElement.setParticipantId(clElementParticipantId);
-            clElement.setParticipantType(clElementParticipantId);
+                clElement.setParticipantId(clParticipantId);
+                clElement.setParticipantType(clParticipantId);
 
-            clElement.setDefinition(clElementParticipantId);
-            clElement.setState(ControlLoopState.UNINITIALISED);
-            clElement.setDescription(toscaInputEntry.getValue().getDescription());
-            clElement.setOrderedState(ControlLoopOrderedState.UNINITIALISED);
-            elements.put(clElement.getId(), clElement);
+                clElement.setDefinition(new ToscaConceptIdentifier(toscaInputEntry.getKey(),
+                    toscaInputEntry.getValue().getVersion()));
+                clElement.setState(ControlLoopState.UNINITIALISED);
+                clElement.setDescription(toscaInputEntry.getValue().getDescription());
+                clElement.setOrderedState(ControlLoopOrderedState.PASSIVE);
+                elements.put(clElement.getId(), clElement);
+            }
         }
-        controlLoop.setElements(elements);
-        controlLoop.setName("PMSHInstance0");
-        controlLoop.setVersion("1.0.0");
-        controlLoop.setDefinition(controlLoopId);
-        clUpdateMsg.setControlLoop(controlLoop);
 
+        List<ParticipantUpdates> participantUpdates = new ArrayList<>();
+        for (ControlLoopElement element : elements.values()) {
+            prepareParticipantUpdateForControlLoop(element, participantUpdates);
+        }
+        clUpdateMsg.setParticipantUpdatesList(participantUpdates);
         return clUpdateMsg;
     }
 
+    private static void prepareParticipantUpdateForControlLoop(ControlLoopElement clElement,
+        List<ParticipantUpdates> participantUpdates) {
+        if (participantUpdates.isEmpty()) {
+            participantUpdates.add(getControlLoopElementList(clElement));
+        } else {
+            boolean participantExists = false;
+            for (ParticipantUpdates participantUpdate : participantUpdates) {
+                if (participantUpdate.getParticipantId().equals(clElement.getParticipantId())) {
+                    participantUpdate.getControlLoopElementList().add(clElement);
+                    participantExists = true;
+                }
+            }
+            if (!participantExists) {
+                participantUpdates.add(getControlLoopElementList(clElement));
+            }
+        }
+    }
+
+    private static ParticipantUpdates getControlLoopElementList(ControlLoopElement clElement) {
+        ParticipantUpdates participantUpdate = new ParticipantUpdates();
+        List<ControlLoopElement> controlLoopElementList = new ArrayList<>();
+        participantUpdate.setParticipantId(clElement.getParticipantId());
+        controlLoopElementList.add(clElement);
+        participantUpdate.setControlLoopElementList(controlLoopElementList);
+        return participantUpdate;
+    }
+
+    /**
+     * Method to create participantUpdateMsg.
+     *
+     * @return ParticipantUpdate message
+     */
+    public static ParticipantUpdate createParticipantUpdateMsg() {
+        final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate();
+        ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0");
+        ToscaConceptIdentifier participantType = new ToscaConceptIdentifier(
+                "org.onap.policy.controlloop.PolicyControlLoopParticipant", "2.3.1");
+
+        participantUpdateMsg.setParticipantId(participantId);
+        participantUpdateMsg.setTimestamp(Instant.now());
+        participantUpdateMsg.setParticipantType(participantType);
+        participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000));
+        participantUpdateMsg.setMessageId(UUID.randomUUID());
+
+        ToscaServiceTemplate toscaServiceTemplate = testControlLoopRead();
+        // Add policies to the toscaServiceTemplate
+
+        List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
+        for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry :
+            toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
+            if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
+                ToscaConceptIdentifier clParticipantId;
+                try {
+                    clParticipantId = CODER.decode(
+                            toscaInputEntry.getValue().getProperties().get("participant_id").toString(),
+                            ToscaConceptIdentifier.class);
+                } catch (CoderException e) {
+                    throw new RuntimeException("cannot get ParticipantId from toscaNodeTemplate", e);
+                }
+                prepareParticipantDefinitionUpdate(clParticipantId, toscaInputEntry.getKey(),
+                    toscaInputEntry.getValue(), participantDefinitionUpdates);
+            }
+        }
+
+        participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates);
+        participantUpdateMsg.setToscaServiceTemplate(toscaServiceTemplate);
+        return participantUpdateMsg;
+    }
+
+    private static void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantId, String entryKey,
+        ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) {
+
+        var clDefinition = new ControlLoopElementDefinition();
+        clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(
+            entryKey, entryValue.getVersion()));
+        clDefinition.setControlLoopElementToscaNodeTemplate(entryValue);
+        List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>();
+
+        if (participantDefinitionUpdates.isEmpty()) {
+            participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
+                controlLoopElementDefinitionList));
+        } else {
+            boolean participantExists = false;
+            for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) {
+                if (participantDefinitionUpdate.getParticipantId().equals(clParticipantId)) {
+                    participantDefinitionUpdate.getControlLoopElementDefinitionList().add(clDefinition);
+                    participantExists = true;
+                }
+            }
+            if (!participantExists) {
+                participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
+                    controlLoopElementDefinitionList));
+            }
+        }
+    }
+
+    private static ParticipantDefinition getParticipantDefinition(ControlLoopElementDefinition clDefinition,
+        ToscaConceptIdentifier clParticipantId,
+        List<ControlLoopElementDefinition> controlLoopElementDefinitionList) {
+        ParticipantDefinition participantDefinition = new ParticipantDefinition();
+        participantDefinition.setParticipantId(clParticipantId);
+        controlLoopElementDefinitionList.add(clDefinition);
+        participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
+        return participantDefinition;
+    }
+
     /**
      * Method to create ControlLoopUpdate using the arguments passed.
      *
index 99dd0ed..c2a68d7 100644 (file)
 tosca_definitions_version: tosca_simple_yaml_1_3
-capability_types:
-  org.onap.EventProducer:
+data_types:
+  onap.datatypes.ToscaConceptIdentifier:
+    derived_from: tosca.datatypes.Root
     properties:
-      carrier_protocol_type:
+      name:
         type: string
         required: true
-        constraints:
-        - valid_values:
-          - DMAAP_message_router
-          - SOMETHING_ELSE
-          - REST
-      data_format:
+      version:
         type: string
         required: true
-        constraints:
-        - valid_values:
-          - JSON
-          - YAML
-          - JMS
-      event_format:
-        type: string
-        required: true
-      event_format_version:
-        type: string
-        required: false
-      config_keys:
-        type: list
-        required: false
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - all valid values should be added here
-            - if not specified, events of any config key may be generated
-            - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out,
-              etc.'
-    version: 0.0.1
-    derived_from: tosca.capabilities.Root
-  org.onap.EventConsumer:
-    properties:
-      responding_capability:
-        type: string
-        required: false
-      carrier_protocol_type:
-        type: string
-        required: true
-        constraints:
-        - valid_values:
-          - DMAAP_message_router
-          - SOMETHING_ELSE
-          - REST
-      data_format:
-        type: string
-        required: true
-        constraints:
-        - valid_values:
-          - JSON
-          - YAML
-          - JMS
-          - all valid values should be added here
-      event_format:
-        type: string
-        description: 'examples for event_format: Ves_specification, LinkUp, VnfConfigured,
-          etc.'
-        required: true
-      event_format_version:
-        type: string
-        description: 'examples for event_format_version: 5.28.4, 7.30.1, etc.'
-        required: false
-      config_keys:
-        type: list
-        required: false
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - all valid values should be added here
-            - if not specified, events of any config key may be generated
-            - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out,
-              etc.'
-    version: 0.0.1
-    derived_from: tosca.capabilities.Root
 node_types:
-  org.onap.DynamicConfig:
+  org.onap.policy.clamp.controlloop.Participant:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
     properties:
-      application_name:
-        type: string
-        description: Value used to tie the config to an application ? should we be
-          using a relationship here instead?
-        required: true
-      application_version:
-        type: string
-        required: true
-      application_provider:
+      provider:
         type: string
-        required: false
-      data_types:
-        type: object
-        required: false
-      schema:
-        type: object
-        required: false
-    version: 0.0.1
-    derived_from: tosca.nodes.Root
-  org.onap.APP:
+        requred: false
+  org.onap.policy.clamp.controlloop.ControlLoopElement:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
     properties:
-      application_name:
-        type: string
-        description: Human readable name for the application Product
-        required: false
       provider:
         type: string
-        description: Provider of the application and of the descriptor
-        required: true
-      application_version:
-        type: string
-        description: Software version of the application
-        required: true
-      blueprint_id:
-        type: string
-        description: A reference to the app blueprint
-        required: false
-      monitoring_policy:
-        type: string
-        description: A reference to the monitoring policy
-        required: false
-    requirements:
-    - receive:
-        capability: org.onap.EventProducer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        version: 0.0.0
-    - send:
-        capability: org.onap.EventConsumer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        version: 0.0.0
-    version: 0.0.1
-    derived_from: tosca.nodes.Root
-  org.onap.EventRelay:
+        requred: false
+      participant_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+  org.onap.policy.clamp.controlloop.ControlLoop:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
     properties:
-      event_format:
-        type: string
-        description: 'examples for event_format: Ves_specification, etc.'
-        required: true
-      event_format_version:
+      provider:
         type: string
-        description: 'examples for event_format_version: 5.28.4, 7.30.1, etc.'
-        required: true
-      config_keys:
+        requred: false
+      elements:
         type: list
-        required: false
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - all valid values should be added here
-            - if not specified, events of any config key is relayed
-            - 'examples for config_key: ves-measurement, ves-syslog, tca_handle_out,
-              etc.'
-      supported_carrier_protocols:
-        type: map
-        description: 'A map describing supported carrier protocols and translations.
-          The tuples define what protocol combinations are supported on the producer
-          and consumer side: e.g. { REST: REST, DMAAP: REST, DMAAP: DMAAP}'
-        required: true
-        key_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - DMAAP_message_router
-            - SOMETHING_ELSE
-            - REST
-            - all valid values should be added here
-        entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - DMAAP_message_router
-            - SOMETHING_ELSE
-            - REST
-            - all valid values should be added here
-      supported_data_formats:
-        type: map
-        description: 'Is a map describing supported data formats and translation.
-          The tuples define what protocol combinations are supported on the producer
-          and consumer side: e.g. { JSON: JSON, JMS: JSON, YAML:YAML }'
         required: true
-        key_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - JSON
-            - JMS
-            - YAML
-            - etc
-            - all valid values should be added here
         entry_schema:
-          type: string
-          constraints:
-          - valid_values:
-            - JSON
-            - JMS
-            - YAML
-            - etc
-            - all valid values should be added here
-    requirements:
-    - receive:
-        capability: org.onap.EventProducer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        version: 0.0.0
-    - send:
-        capability: org.onap.EventConsumer
-        relationship: org.onap.PropagateEvent
-        occurrences:
-        - 0.0
-        - UNBOUNDED
-        version: 0.0.0
-    version: 0.0.1
-    derived_from: tosca.nodes.Root
-relationship_types:
-  org.onap.PropagateEvent:
+          type: onap.datatypes.ToscaConceptIdentifier
+  org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
     properties:
-      config_keys:
-        type: list
-        description: The relationship type used on requirements to org.onap.EventProducer
-          and org.onap.EventConsumer capabilities. Filters events by specific config_keys
-          to be transferred by this relationship. That is, any event with a specific
-          config_key found in the list is transferred. If list is not defined or is
-          empty, events with all config_keys are transferred.
-        required: false
-        entry_schema:
-          type: string
-    version: 0.0.1
-    derived_from: tosca.relationships.Root
+      dcae_blueprint_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+  org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
+    properties:
+      policy_type_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+  org.onap.policy.clamp.controlloop.CDSControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
+    properties:
+      cds_blueprint_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
 topology_template:
-  inputs:
-    pm_subscription_topic:
-      type: string
-    pm_subscription_response_topic:
-      type: string
-    pm_subscription_handler_blueprint_id:
-      type: string
-    pm_subscription_operational_policy_id:
-      type: string
-    pm_subscription_cds_blueprint_id:
-      type: string
-    enable_tls:
-      type: string
   node_templates:
-    org.onap.PM_Subscription_Handler:
-      type: org.onap.APP
+    org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant:
+      version: 2.3.4
+      type: org.onap.policy.clamp.controlloop.Participant
+      type_version: 1.0.1
+      description: Participant for DCAE microservices
+      properties:
+        provider: ONAP
+    org.onap.policy.controlloop.PolicyControlLoopParticipant:
+      version: 2.3.1
+      type: org.onap.policy.clamp.controlloop.Participant
+      type_version: 1.0.1
+      description: Participant for DCAE microservices
+      properties:
+        provider: ONAP
+    org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant:
+      version: 2.2.1
+      type: org.onap.policy.clamp.controlloop.Participant
+      type_version: 1.0.1
+      description: Participant for DCAE microservices
+      properties:
+        provider: ONAP
+    org.onap.domain.pmsh.PMSH_DCAEMicroservice:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the DCAE microservice for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription Handler
         provider: Ericsson
-        application_version: 1.0.0
-        artifact_id:
-          get_input: pm_subscription_handler_blueprint_id
-          description: Is this a reference to the DCAE Cloudify Blueprint that is
-            already stored(or will be stored before CL configuration & instatiation)
-            in DCAE Inventory?
-        artifact_config:
-          enable_tls:
-            get_input: enable_tls
-          pmsh_publish_topic_name:
-            get_input: pm_subscription_topic
-      capabilities:
-        pm-subscription-event-publisher:
-          properties:
-            carrier_protocol_type: DMAAP_message_router
-            data_format: JSON
-            event_format: pm-subscription-event-format
-            event_format_version: 1.0.0
-          attributes:
-            type: org.onap.EventProducer
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          version: 0.0.0
-        pm-subscription-event-receiver:
-          properties:
-            carrier_protocol_type: DMAAP_message_router
-            data_format: JSON
-            event_format: pm-subscription-event-response-format
-            event_format_version: 1.0.0
-            relationships:
-            - type: tosca.relationships.DependsOn
-            - description: any ideas on a better realtionship ? or is it better to
-                just use the root realtionship ?
-            - target: org.onap.PM_Monitoring_Policy
-          attributes:
-            type: org.onap.EventConsumer
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          version: 0.0.0
-      version: 0.0.0
-    org.onap.PM_Monitoring_Policy:
-      type: org.onap.DynamicConfig
+        participant_id:
+          name: org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant
+          version: 2.3.4
+        dcae_blueprint_id:
+          name: org.onap.dcae.blueprints.PMSHBlueprint
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the monitoring policy for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription Handler
-        application_version: 1.0.0
         provider: Ericsson
-        data_types:
-          measurementType:
-            type: string
-          DN:
-            type: string
-          nfFilter:
-            properties:
-              nfNames:
-                type: list
-                entry_schema: string
-              modelInvariantIDs:
-                type: list
-                entry_schema:
-                  type: string
-              modelVersionIDs:
-                type: list
-                entry_schema:
-                  type: string
-          measurementGroup:
-            properties:
-              masurementTypes:
-                type: list
-                entry_schema:
-                  type: measurementType
-              managedObjectDNsBasic:
-                type: list
-                entry_schema:
-                  type: DN
-        schema:
-          subscription:
-            subscriptionName:
-              type: string
-              required: true
-            administrativeState:
-              type: string
-              required: true
-            filebasedGP:
-              type: integer
-              required: true
-            fileLocation:
-              type: string
-              required: true
-            nfFilter:
-              type: nfFilter
-            measurementGroups:
-              type: list
-              entry_schema:
-                type: measurementGroup
-      version: 0.0.0
-      description: Should I be showing a dependency between PM Subscription Handler
-        and the PM Monitoring Policy
-    org.onap.PM_Policy:
-      type: org.onap.APP
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.3.1
+        policy_type_id:
+          name: onap.policies.monitoring.pm-subscription-handler
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.PolicyTypeControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the operational policy for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription Operational Policy
         provider: Ericsson
-        application_version: 1.0.0
-        artifact_id:
-          get_input: pm_subscription_operational_policy_id
-        artifact_config: NOT_DEFINED
-      requirements:
-      - receive_0:
-          capability: pm-subscription-event-publisher
-          node: org.onap.PM_Subscription_Handler
-          relationship: NOT_DEFINED
-          properties:
-            config_keys:
-            - topic_name:
-                get_input: pm_subscription_topic
-          version: 0.0.0
-      - send_0:
-          capability: cds-rest-receive
-          node: org.onap.CDS
-          version: 0.0.0
-      - receive_1:
-          capability: cds-rest-response
-          node: org.onap.CDS
-          version: 0.0.0
-      - send_1:
-          capability: pm-subscription-event-receiver
-          node: org.onap.PM_Subscription_Handler
-          relationship: NOT_DEFINED
-          properties:
-            config_keys:
-            - topic_name:
-                get_input: pm_subscription_response_topic
-          version: 0.0.0
-      capabilities:
-        pm-subscription-response-event-publisher:
-          properties:
-            type: org.onap.EventProducer
-            carrier_protocol_type: DMAAP_message_router
-            data_format: JSON
-            event_format: pm-subscription-event-response-format
-            event_format_version: 1.0.0
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          version: 0.0.0
-      version: 0.0.0
-    org.onap.PM_CDS_Blueprint:
-      type: org.onap.APP
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.3.1
+        policy_type_id:
+          name: onap.policies.operational.pm-subscription-handler
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.ControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for CDS for Performance Management Subscription Handling
       properties:
-        application_name: PM Subscription CDS Blueprint
         provider: Ericsson
-        application_version: 1.0.0
-        artifact_id:
-          get_input: pm_subscription_cds_blueprint_id
-      capabilities:
-        cds-rest-receive:
-          properties:
-            type: org.onap.EventConsumer
-            protocol_type: REST
-            data_format: JSON
-            event_format: cds_action_format
-            event_format_version: 1.0.0
-            responding_capability: cds-rest-response
-          occurrences:
-          - 0.0
-          - UNBOUNDED
-          version: 0.0.0
-        cds-rest-response:
-          properties:
-            type: org.onap.EventProducer
-            protocol_type: REST
-            data_format: JSON
-            event_format: cds_action_response_format
-            event_format_version: 1.0.0
-          occurrences:
-          - 0.0
-          version: 0.0.0
-      version: 1.0.0
-    org.onap.controlloop0:
-      type: org.onap.APP
+        participant_id:
+          name: org.onap.PM_CDS_Blueprint
+          version: 1.0.0
+        cds_blueprint_id:
+          name: org.onap.ccsdk.cds.PMSHCdsBlueprint
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSHControlLoopDefinition:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.ControlLoop
+      type_version: 1.0.0
+      description: Control loop for Performance Management Subscription Handling
       properties:
-        application_name: Test Control Loop
         provider: Ericsson
-        application_version: 1.0.0
-        status: NOT_DEPLOYED
-      version: 0.0.0
-version: 0.0.0
+        elements:
+          - name: org.onap.domain.pmsh.PMSH_DCAEMicroservice
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement
+            version: 1.2.3
index 9e5d2c6..4dd978f 100644 (file)
@@ -25,7 +25,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
 import org.onap.policy.models.base.PfModelException;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 
 /**
  * This interface is implemented by participant implementations to receive updates on control loop elements.
@@ -46,11 +46,11 @@ public interface ControlLoopElementListener {
      * Handle an update on a control loop element.
      *
      * @param element the information on the control loop element
-     * @param controlLoopDefinition toscaServiceTemplate
+     * @param controlLoopElementDefinition toscaNodeTemplate
      * @throws PfModelException from Policy framework
      */
     public void controlLoopElementUpdate(ControlLoopElement element,
-            ToscaServiceTemplate controlLoopDefinition) throws PfModelException;
+            ToscaNodeTemplate controlLoopElementDefinition) throws PfModelException;
 
     /**
      * Handle controlLoopElement statistics.
index 7e448dc..aa2027a 100644 (file)
@@ -32,6 +32,7 @@ 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.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 
 /**
  * This interface is used by participant implementations to use the participant intermediary.
@@ -98,6 +99,13 @@ public interface ParticipantIntermediaryApi {
      */
     Map<UUID, ControlLoopElement> getControlLoopElements(String name, String version);
 
+    /**
+     * Get ToscaServiceTemplate from the intermediary API.
+     *
+     * @return the control loop element
+     */
+    ToscaServiceTemplate getToscaServiceTemplate();
+
     /**
      * Get control loop element from the intermediary API.
      *
index 9652f1a..a2a4c34 100644 (file)
@@ -37,6 +37,7 @@ import org.onap.policy.clamp.controlloop.participant.intermediary.api.ControlLoo
 import org.onap.policy.clamp.controlloop.participant.intermediary.api.ParticipantIntermediaryApi;
 import org.onap.policy.clamp.controlloop.participant.intermediary.handler.ParticipantHandler;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.springframework.stereotype.Component;
 
 /**
@@ -119,6 +120,11 @@ public class ParticipantIntermediaryApiImpl implements ParticipantIntermediaryAp
         return null;
     }
 
+    @Override
+    public ToscaServiceTemplate getToscaServiceTemplate() {
+        return participantHandler.getToscaServiceTemplate();
+    }
+
     @Override
     public ControlLoopElement updateControlLoopElementState(UUID id, ControlLoopOrderedState currentState,
             ControlLoopState newState) {
index 876a4cc..f242114 100644 (file)
@@ -36,6 +36,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopOrderedState;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantUpdates;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopAck;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopStateChange;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ControlLoopUpdate;
@@ -45,6 +46,7 @@ import org.onap.policy.clamp.controlloop.participant.intermediary.comm.MessageSe
 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.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -185,7 +187,7 @@ public class ControlLoopHandler {
      * @param updateMsg the update message
      */
     public void handleControlLoopUpdate(ControlLoopUpdate updateMsg,
-                Map<UUID, ControlLoopElementDefinition> clElementDefinitions) {
+                List<ControlLoopElementDefinition> clElementDefinitions) {
 
         if (!updateMsg.appliesTo(participantType, participantId)) {
             return;
@@ -207,27 +209,26 @@ public class ControlLoopHandler {
             return;
         }
 
-        controlLoop = updateMsg.getControlLoop();
-        controlLoop.getElements().values().removeIf(element -> !participantType.equals(element.getParticipantType()));
+        List<ControlLoopElement> clElements = storeElementsOnThisParticipant(updateMsg.getParticipantUpdatesList());
 
-        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,
-                        clElementDefinitions.get(element.getId()).getControlLoopElementToscaServiceTemplate());
+        try {
+            for (ControlLoopElement element : clElements) {
+                ToscaNodeTemplate clElementNodeTemplate = getClElementNodeTemplate(
+                        clElementDefinitions, element.getDefinition());
+                for (ControlLoopElementListener clElementListener : listeners) {
+                    clElementListener.controlLoopElementUpdate(element, clElementNodeTemplate);
                 }
-            } catch (PfModelException e) {
-                LOGGER.debug("Control loop element update failed {}", updateMsg.getControlLoopId());
             }
+        } catch (PfModelException e) {
+            LOGGER.debug("Control loop element update failed {}", updateMsg.getControlLoopId());
         }
 
+        Map<UUID, ControlLoopElement> clElementMap = prepareClElementMap(clElements);
+        controlLoop = new ControlLoop();
+        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()
@@ -236,6 +237,37 @@ public class ControlLoopHandler {
         messageSender.sendAckResponse(controlLoopUpdateAck);
     }
 
+    private ToscaNodeTemplate getClElementNodeTemplate(List<ControlLoopElementDefinition> clElementDefinitions,
+                ToscaConceptIdentifier clElementDefId) {
+        for (ControlLoopElementDefinition clElementDefinition : clElementDefinitions) {
+            if (clElementDefinition.getClElementDefinitionId().equals(clElementDefId)) {
+                return clElementDefinition.getControlLoopElementToscaNodeTemplate();
+            }
+        }
+        return null;
+    }
+
+    private List<ControlLoopElement> storeElementsOnThisParticipant(List<ParticipantUpdates> participantUpdates) {
+        List<ControlLoopElement> clElementMap = new ArrayList<>();
+        for (ParticipantUpdates participantUpdate : participantUpdates) {
+            if (participantUpdate.getParticipantId().equals(participantType)) {
+                clElementMap = participantUpdate.getControlLoopElementList();
+            }
+        }
+        for (ControlLoopElement element : clElementMap) {
+            elementsOnThisParticipant.put(element.getId(), element);
+        }
+        return clElementMap;
+    }
+
+    private Map<UUID, ControlLoopElement> prepareClElementMap(List<ControlLoopElement> clElements) {
+        Map<UUID, ControlLoopElement> clElementMap = new LinkedHashMap<>();
+        for (ControlLoopElement element : clElements) {
+            clElementMap.put(element.getId(), element);
+        }
+        return clElementMap;
+    }
+
     /**
      * Method to handle when the new state from participant is UNINITIALISED state.
      *
index e1c0f7c..6dcf933 100644 (file)
@@ -22,14 +22,15 @@ package org.onap.policy.clamp.controlloop.participant.intermediary.handler;
 
 import java.io.Closeable;
 import java.time.Instant;
-import java.util.LinkedHashMap;
-import java.util.Map;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Objects;
 import java.util.UUID;
 import lombok.Getter;
 import lombok.Setter;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition;
 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;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantState;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatistics;
@@ -48,6 +49,7 @@ import org.onap.policy.clamp.controlloop.participant.intermediary.comm.MessageSe
 import org.onap.policy.clamp.controlloop.participant.intermediary.comm.ParticipantMessagePublisher;
 import org.onap.policy.clamp.controlloop.participant.intermediary.parameters.ParticipantParameters;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -72,7 +74,10 @@ public class ParticipantHandler implements Closeable {
     @Setter
     private ParticipantHealthStatus healthStatus = ParticipantHealthStatus.UNKNOWN;
 
-    private final Map<UUID, ControlLoopElementDefinition> clElementDefsOnThisParticipant = new LinkedHashMap<>();
+    private List<ControlLoopElementDefinition> clElementDefsOnThisParticipant =
+            new ArrayList<>();
+
+    public ToscaServiceTemplate toscaServiceTemplate = new ToscaServiceTemplate();
 
     /**
      * Constructor, set the participant ID and sender.
@@ -239,13 +244,12 @@ public class ParticipantHandler implements Closeable {
             return;
         }
 
-        Map<UUID, ControlLoopElementDefinition> clDefinitionMap = participantUpdateMsg
-                .getParticipantDefinitionUpdateMap().get(participantUpdateMsg.getParticipantId().toString());
-
-        for (ControlLoopElementDefinition element : clDefinitionMap.values()) {
-            clElementDefsOnThisParticipant.put(element.getId(), element);
+        toscaServiceTemplate = participantUpdateMsg.getToscaServiceTemplate();
+        for (ParticipantDefinition participantDefinition : participantUpdateMsg.getParticipantDefinitionUpdates()) {
+            if (participantDefinition.getParticipantId().equals(participantType)) {
+                clElementDefsOnThisParticipant = participantDefinition.getControlLoopElementDefinitionList();
+            }
         }
-
         sendParticipantUpdateAck(participantUpdateMsg.getMessageId());
     }
 
index 9180ced..0e2ff5c 100644 (file)
@@ -311,18 +311,16 @@ public class SupervisionHandler {
 
     private void superviseControlLoops(ParticipantStatus participantStatusMessage)
             throws PfModelException, ControlLoopException {
-        if (participantStatusMessage.getControlLoopInfoMap() != null) {
-            for (Map.Entry<String, ControlLoopInfo> clEntry : participantStatusMessage.getControlLoopInfoMap()
-                    .entrySet()) {
-                String[] key = clEntry.getKey().split(" ");
+        if (participantStatusMessage.getControlLoopInfoList() != null) {
+            for (ControlLoopInfo clEntry : participantStatusMessage.getControlLoopInfoList()) {
                 var dbControlLoop = controlLoopProvider.getControlLoop(
-                        new ToscaConceptIdentifier(key[0], key[1]));
+                        new ToscaConceptIdentifier(clEntry.getControlLoopId()));
                 if (dbControlLoop == null) {
                     exceptionOccured(Response.Status.NOT_FOUND,
-                            "PARTICIPANT_STATUS control loop not found in database: " + clEntry.getKey());
+                            "PARTICIPANT_STATUS control loop not found in database: " + clEntry.getControlLoopId());
                 }
-                dbControlLoop.setState(clEntry.getValue().getState());
-                monitoringProvider.createClElementStatistics(clEntry.getValue().getControlLoopStatistics()
+                dbControlLoop.setState(clEntry.getState());
+                monitoringProvider.createClElementStatistics(clEntry.getControlLoopStatistics()
                         .getClElementStatisticsList().getClElementStatistics());
             }
         }
index 448662c..be9a2a2 100644 (file)
 
 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;
@@ -44,8 +54,43 @@ public class ControlLoopUpdatePublisher extends AbstractParticipantPublisher<Con
     public void send(ControlLoop controlLoop) {
         var controlLoopUpdateMsg = new ControlLoopUpdate();
         controlLoopUpdateMsg.setControlLoopId(controlLoop.getKey().asIdentifier());
-        controlLoopUpdateMsg.setControlLoop(controlLoop);
+        controlLoopUpdateMsg.setMessageId(UUID.randomUUID());
+        controlLoopUpdateMsg.setTimestamp(Instant.now());
+
+        List<ParticipantUpdates> participantUpdates = new ArrayList<>();
+        for (ControlLoopElement element : controlLoop.getElements().values()) {
+            prepareParticipantUpdate(element, participantUpdates);
+        }
+        controlLoopUpdateMsg.setParticipantUpdatesList(participantUpdates);
+
         LOGGER.debug("ControlLoopUpdate message sent", controlLoopUpdateMsg);
         super.send(controlLoopUpdateMsg);
     }
+
+    private void prepareParticipantUpdate(ControlLoopElement clElement,
+        List<ParticipantUpdates> participantUpdates) {
+        if (participantUpdates.isEmpty()) {
+            participantUpdates.add(getControlLoopElementList(clElement));
+        } else {
+            boolean participantExists = false;
+            for (ParticipantUpdates participantUpdate : participantUpdates) {
+                if (participantUpdate.getParticipantId().equals(clElement.getParticipantId())) {
+                    participantUpdate.getControlLoopElementList().add(clElement);
+                    participantExists = true;
+                }
+            }
+            if (!participantExists) {
+                participantUpdates.add(getControlLoopElementList(clElement));
+            }
+        }
+    }
+
+    private ParticipantUpdates getControlLoopElementList(ControlLoopElement clElement) {
+        ParticipantUpdates participantUpdate = new ParticipantUpdates();
+        List<ControlLoopElement> controlLoopElementList = new ArrayList<>();
+        participantUpdate.setParticipantId(clElement.getParticipantId());
+        controlLoopElementList.add(clElement);
+        participantUpdate.setControlLoopElementList(controlLoopElementList);
+        return participantUpdate;
+    }
 }
index cfc0e39..5edf528 100644 (file)
 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.ControlLoopElement;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -42,8 +50,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 CommissioningProvider commissioningProvider;
+    private static final Coder CODER = new StandardCoder();
 
     /**
      * Send ParticipantUpdate to Participant.
@@ -57,25 +66,71 @@ public class ParticipantUpdatePublisher extends AbstractParticipantPublisher<Par
         message.setParticipantType(participantType);
         message.setTimestamp(Instant.now());
 
-        var clDefinition = new ControlLoopElementDefinition();
-        clDefinition.setId(UUID.randomUUID());
-
+        ToscaServiceTemplate toscaServiceTemplate;
         try {
-            clDefinition.setControlLoopElementToscaServiceTemplate(
-                    commissioningProvider.getToscaServiceTemplate(null, null));
+            toscaServiceTemplate = commissioningProvider.getToscaServiceTemplate(null, null);
         } catch (PfModelException pfme) {
             LOGGER.warn("Get of tosca service template failed, cannot send participantupdate", pfme);
             return;
         }
 
-        Map<UUID, ControlLoopElementDefinition> controlLoopElementDefinitionMap = new LinkedHashMap<>();
-        controlLoopElementDefinitionMap.put(UUID.randomUUID(), clDefinition);
-
-        Map<String, Map<UUID, ControlLoopElementDefinition>> participantDefinitionUpdateMap = new LinkedHashMap<>();
-        participantDefinitionUpdateMap.put(participantId.toString(), controlLoopElementDefinitionMap);
-        message.setParticipantDefinitionUpdateMap(participantDefinitionUpdateMap);
+        List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
+        for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry :
+            toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
+            if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
+                ToscaConceptIdentifier clParticipantId;
+                try {
+                    clParticipantId = CODER.decode(
+                            toscaInputEntry.getValue().getProperties().get("participant_id").toString(),
+                            ToscaConceptIdentifier.class);
+                } catch (CoderException e) {
+                    throw new RuntimeException("cannot get ParticipantId from toscaNodeTemplate", e);
+                }
+                prepareParticipantDefinitionUpdate(clParticipantId, toscaInputEntry.getKey(),
+                    toscaInputEntry.getValue(), participantDefinitionUpdates);
+            }
+        }
 
+        message.setParticipantDefinitionUpdates(participantDefinitionUpdates);
+        message.setToscaServiceTemplate(toscaServiceTemplate);
         LOGGER.debug("Participant Update sent {}", message);
         super.send(message);
     }
+
+    private void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantId, String entryKey,
+        ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) {
+
+        var clDefinition = new ControlLoopElementDefinition();
+        clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(
+            entryKey, entryValue.getVersion()));
+        clDefinition.setControlLoopElementToscaNodeTemplate(entryValue);
+        List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>();
+
+        if (participantDefinitionUpdates.isEmpty()) {
+            participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
+                controlLoopElementDefinitionList));
+        } else {
+            boolean participantExists = false;
+            for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) {
+                if (participantDefinitionUpdate.getParticipantId().equals(clParticipantId)) {
+                    participantDefinitionUpdate.getControlLoopElementDefinitionList().add(clDefinition);
+                    participantExists = true;
+                }
+            }
+            if (!participantExists) {
+                participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
+                    controlLoopElementDefinitionList));
+            }
+        }
+    }
+
+    private ParticipantDefinition getParticipantDefinition(ControlLoopElementDefinition clDefinition,
+        ToscaConceptIdentifier clParticipantId,
+        List<ControlLoopElementDefinition> controlLoopElementDefinitionList) {
+        ParticipantDefinition participantDefinition = new ParticipantDefinition();
+        participantDefinition.setParticipantId(clParticipantId);
+        controlLoopElementDefinitionList.add(clDefinition);
+        participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
+        return participantDefinition;
+    }
 }
index e74af79..10116a2 100644 (file)
@@ -21,7 +21,9 @@
 package org.onap.policy.clamp.controlloop.runtime.supervision.comm;
 
 import java.time.Instant;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.UUID;
@@ -30,6 +32,7 @@ import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElementDefinition;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantDefinition;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ClElementStatisticsProvider;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
@@ -41,6 +44,7 @@ import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.Parti
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdateAck;
 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
+import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationUtils;
 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
 import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
 import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
@@ -48,6 +52,9 @@ import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
 import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController;
 import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
 import org.onap.policy.common.endpoints.event.comm.TopicSink;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardCoder;
 import org.onap.policy.common.utils.coder.YamlJsonTranslator;
 import org.onap.policy.common.utils.resources.ResourceUtils;
 import org.onap.policy.models.base.PfModelException;
@@ -63,12 +70,15 @@ class SupervisionMessagesTest extends CommonRestController {
     private static final Object lockit = new Object();
     private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
     private static final String TOPIC = "my-topic";
-    private static final long interval = 1000;
     private static SupervisionHandler supervisionHandler;
     private static CommissioningProvider commissioningProvider;
     private static ControlLoopProvider clProvider;
     private static PolicyModelsProvider modelsProvider;
     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 Coder CODER = new StandardCoder();
 
     /**
      * setup Db Provider Parameters.
@@ -118,7 +128,6 @@ class SupervisionMessagesTest extends CommonRestController {
             ToscaServiceTemplate serviceTemplate = yamlTranslator.fromYaml(
                     ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), ToscaServiceTemplate.class);
 
-            List<ToscaNodeTemplate> listOfTemplates = commissioningProvider.getControlLoopDefinitions(null, null);
             commissioningProvider.createControlLoopDefinitions(serviceTemplate);
             participantRegisterListener.onTopicEvent(INFRA, TOPIC, null, participantRegisterMsg);
         }
@@ -168,6 +177,9 @@ class SupervisionMessagesTest extends CommonRestController {
 
     @Test
     void testSendParticipantUpdate() throws Exception {
+        InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, commissioningProvider);
+        commissioningProvider.getToscaServiceTemplate(null, null);
+
         final ParticipantUpdate participantUpdateMsg = new ParticipantUpdate();
         participantUpdateMsg.setParticipantId(getParticipantId());
         participantUpdateMsg.setTimestamp(Instant.now());
@@ -175,32 +187,71 @@ class SupervisionMessagesTest extends CommonRestController {
         participantUpdateMsg.setTimestamp(Instant.ofEpochMilli(3000));
         participantUpdateMsg.setMessageId(UUID.randomUUID());
 
-        ToscaServiceTemplate toscaServiceTemplate = new ToscaServiceTemplate();
-        toscaServiceTemplate.setName("serviceTemplate");
-        toscaServiceTemplate.setDerivedFrom("parentServiceTemplate");
-        toscaServiceTemplate.setDescription("Description of serviceTemplate");
-        toscaServiceTemplate.setVersion("1.2.3");
+        ToscaServiceTemplate toscaServiceTemplate = commissioningProvider.getToscaServiceTemplate(null, null);
+        List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
+        for (Map.Entry<String, ToscaNodeTemplate> toscaInputEntry :
+            toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
+            if (toscaInputEntry.getValue().getType().contains(CONTROL_LOOP_ELEMENT)) {
+                ToscaConceptIdentifier clParticipantId;
+                try {
+                    clParticipantId = CODER.decode(
+                            toscaInputEntry.getValue().getProperties().get("participant_id").toString(),
+                            ToscaConceptIdentifier.class);
+                } catch (CoderException e) {
+                    throw new RuntimeException("cannot get ParticipantId from toscaNodeTemplate", e);
+                }
+                prepareParticipantDefinitionUpdate(clParticipantId, toscaInputEntry.getKey(),
+                    toscaInputEntry.getValue(), participantDefinitionUpdates);
+            }
+        }
 
-        ControlLoopElementDefinition clDefinition = new ControlLoopElementDefinition();
-        clDefinition.setId(UUID.randomUUID());
-        clDefinition.setControlLoopElementToscaServiceTemplate(toscaServiceTemplate);
-        Map<String, String> commonPropertiesMap = Map.of("Prop1", "PropValue");
-        clDefinition.setCommonPropertiesMap(commonPropertiesMap);
+        participantUpdateMsg.setParticipantDefinitionUpdates(participantDefinitionUpdates);
+        participantUpdateMsg.setToscaServiceTemplate(toscaServiceTemplate);
+        synchronized (lockit) {
+            ParticipantUpdatePublisher participantUpdatePublisher =
+                new ParticipantUpdatePublisher(commissioningProvider);
+            participantUpdatePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class)));
+            participantUpdatePublisher.send(participantUpdateMsg);
+        }
+    }
 
-        Map<UUID, ControlLoopElementDefinition> controlLoopElementDefinitionMap =
-                Map.of(UUID.randomUUID(), clDefinition);
+    private void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantId, String entryKey,
+        ToscaNodeTemplate entryValue, List<ParticipantDefinition> participantDefinitionUpdates) {
 
-        Map<String, Map<UUID, ControlLoopElementDefinition>> participantDefinitionUpdateMap =
-                Map.of(getParticipantId().toString(), controlLoopElementDefinitionMap);
-        participantUpdateMsg.setParticipantDefinitionUpdateMap(participantDefinitionUpdateMap);
+        var clDefinition = new ControlLoopElementDefinition();
+        clDefinition.setClElementDefinitionId(new ToscaConceptIdentifier(
+            entryKey, entryValue.getVersion()));
+        clDefinition.setControlLoopElementToscaNodeTemplate(entryValue);
+        List<ControlLoopElementDefinition> controlLoopElementDefinitionList = new ArrayList<>();
 
-        synchronized (lockit) {
-            ParticipantUpdatePublisher clUpdatePublisher = new ParticipantUpdatePublisher(commissioningProvider);
-            clUpdatePublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class)));
-            clUpdatePublisher.send(participantUpdateMsg);
+        if (participantDefinitionUpdates.isEmpty()) {
+            participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
+                controlLoopElementDefinitionList));
+        } else {
+            boolean participantExists = false;
+            for (ParticipantDefinition participantDefinitionUpdate : participantDefinitionUpdates) {
+                if (participantDefinitionUpdate.getParticipantId().equals(clParticipantId)) {
+                    participantDefinitionUpdate.getControlLoopElementDefinitionList().add(clDefinition);
+                    participantExists = true;
+                }
+            }
+            if (!participantExists) {
+                participantDefinitionUpdates.add(getParticipantDefinition(clDefinition, clParticipantId,
+                    controlLoopElementDefinitionList));
+            }
         }
     }
 
+    private ParticipantDefinition getParticipantDefinition(ControlLoopElementDefinition clDefinition,
+        ToscaConceptIdentifier clParticipantId,
+        List<ControlLoopElementDefinition> controlLoopElementDefinitionList) {
+        ParticipantDefinition participantDefinition = new ParticipantDefinition();
+        participantDefinition.setParticipantId(clParticipantId);
+        controlLoopElementDefinitionList.add(clDefinition);
+        participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
+        return participantDefinition;
+    }
+
     @Test
     void testReceiveParticipantUpdateAckMessage() throws Exception {
         final ParticipantUpdateAck participantUpdateAckMsg = new ParticipantUpdateAck();
index 13ea1bf..64443ff 100644 (file)
                         "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
                         "version": "1.2.3"
                     },
+                    "participantId": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
                     "participantType": {
                         "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
                         "version": "2.3.4"
                         "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
                         "version": "1.2.3"
                     },
+                    "participantId": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
                     "participantType": {
                         "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
                         "version": "2.3.1"
                         "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
                         "version": "1.2.3"
                     },
+                    "participantId": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
                     "participantType": {
                         "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
                         "version": "2.3.1"
                         "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
                         "version": "1.2.3"
                     },
+                    "participantId": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
                     "participantType": {
                         "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
                         "version": "2.2.1"
                         "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
                         "version": "1.2.3"
                     },
+                    "participantId": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
                     "participantType": {
                         "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
                         "version": "2.3.4"
                         "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
                         "version": "1.2.3"
                     },
+                    "participantId": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
                     "participantType": {
                         "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
                         "version": "2.3.1"
                         "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
                         "version": "1.2.3"
                     },
+                    "participantId": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
                     "participantType": {
                         "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
                         "version": "2.3.1"
                         "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
                         "version": "1.2.3"
                     },
+                    "participantId": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
                     "participantType": {
                         "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
                         "version": "2.2.1"
index 099e2e9..dc09b46 100644 (file)
@@ -129,7 +129,7 @@ topology_template:
       description: Control loop element for CDS for Performance Management Subscription Handling
       properties:
         provider: Ericsson
-        participant_Id:
+        participant_id:
           name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant
           version: 3.2.1
         cds_blueprint_id:
@@ -197,7 +197,7 @@ topology_template:
       description: Control loop element for CDS for Performance Management Subscription Handling
       properties:
         provider: Ericsson
-        participant_Id:
+        participant_id:
           name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant
           version: 3.2.1
         cds_blueprint_id:
index 099e2e9..dc09b46 100644 (file)
@@ -129,7 +129,7 @@ topology_template:
       description: Control loop element for CDS for Performance Management Subscription Handling
       properties:
         provider: Ericsson
-        participant_Id:
+        participant_id:
           name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant
           version: 3.2.1
         cds_blueprint_id:
@@ -197,7 +197,7 @@ topology_template:
       description: Control loop element for CDS for Performance Management Subscription Handling
       properties:
         provider: Ericsson
-        participant_Id:
+        participant_id:
           name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant
           version: 3.2.1
         cds_blueprint_id: