Handle ParticipantRegister 24/124624/3
authorFrancescoFioraEst <francesco.fiora@est.tech>
Wed, 29 Sep 2021 11:16:06 +0000 (12:16 +0100)
committerFrancescoFioraEst <francesco.fiora@est.tech>
Tue, 5 Oct 2021 14:03:31 +0000 (15:03 +0100)
Send ParticipantUpdate to participant after registration
if commissioning has already been created

Issue-ID: POLICY-3689
Change-Id: Iccc4fc1c0b95e1f270b6810c5b5f130726f24650
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ServiceTemplateProvider.java [new file with mode: 0644]
models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ServiceTemplateProviderTest.java [new file with mode: 0644]
models/src/test/resources/providers/tosca-for-smoke-testing.yaml [new file with mode: 0644]
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProvider.java
runtime-controlloop/src/main/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionAspect.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/SupervisionScanner.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/commissioning/CommissioningProviderTest.java
runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java
runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/supervision/SupervisionHandlerTest.java

diff --git a/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ServiceTemplateProvider.java b/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ServiceTemplateProvider.java
new file mode 100644 (file)
index 0000000..6a6d20f
--- /dev/null
@@ -0,0 +1,226 @@
+/*-
+ * ============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.persistence.provider;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.core.Response.Status;
+import lombok.RequiredArgsConstructor;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.provider.PolicyModelsProvider;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.springframework.stereotype.Component;
+
+@Component
+@RequiredArgsConstructor
+public class ServiceTemplateProvider {
+
+    private final PolicyModelsProvider modelsProvider;
+
+    /**
+     * Create service template.
+     *
+     * @param serviceTemplate the service template to be created
+     * @return the created service template
+     * @throws PfModelException on errors creating the service template
+     */
+    public ToscaServiceTemplate createServiceTemplate(final ToscaServiceTemplate serviceTemplate)
+            throws PfModelException {
+        return modelsProvider.createServiceTemplate(serviceTemplate);
+    }
+
+    /**
+     * Delete service template.
+     *
+     * @param name the name of the service template to delete.
+     * @param version the version of the service template to delete.
+     * @return the TOSCA service template that was deleted
+     * @throws PfModelException on errors deleting policy types
+     */
+    public ToscaServiceTemplate deleteServiceTemplate(final String name, final String version) throws PfModelException {
+        return modelsProvider.deleteServiceTemplate(name, version);
+    }
+
+    /**
+     * Get the requested control loop definitions.
+     *
+     * @param name the name of the definition to get, null for all definitions
+     * @param version the version of the definition to get, null for all definitions
+     * @return the control loop definitions
+     * @throws PfModelException on errors getting control loop definitions
+     */
+    public ToscaServiceTemplate getToscaServiceTemplate(String name, String version) throws PfModelException {
+        var serviceTemplates = modelsProvider.getServiceTemplateList(name, version);
+        if (serviceTemplates.isEmpty()) {
+            throw new PfModelException(Status.NOT_FOUND, "Control Loop definitions not found");
+        }
+        return serviceTemplates.get(0);
+    }
+
+    /**
+     * Get service templates.
+     *
+     * @param name the name of the topology template to get, set to null to get all service templates
+     * @param version the version of the service template to get, set to null to get all service templates
+     * @return the topology templates found
+     * @throws PfModelException on errors getting service templates
+     */
+    public List<ToscaServiceTemplate> getServiceTemplateList(final String name, final String version)
+            throws PfModelException {
+        return modelsProvider.getServiceTemplateList(name, version);
+    }
+
+    /**
+     * Get the initial node types with common or instance properties.
+     *
+     * @param fullNodeTypes map of all the node types in the specified template
+     * @param common boolean to indicate whether common or instance properties are required
+     * @return node types map that only has common properties
+     * @throws PfModelException on errors getting node type with common properties
+     */
+    private Map<String, ToscaNodeType> getInitialNodeTypesMap(Map<String, ToscaNodeType> fullNodeTypes,
+            boolean common) {
+
+        var tempNodeTypesMap = new HashMap<String, ToscaNodeType>();
+
+        fullNodeTypes.forEach((key, nodeType) -> {
+            var tempToscaNodeType = new ToscaNodeType();
+            tempToscaNodeType.setName(key);
+
+            var resultantPropertyMap = findCommonOrInstancePropsInNodeTypes(nodeType, common);
+
+            if (!resultantPropertyMap.isEmpty()) {
+                tempToscaNodeType.setProperties(resultantPropertyMap);
+                tempNodeTypesMap.put(key, tempToscaNodeType);
+            }
+        });
+        return tempNodeTypesMap;
+    }
+
+    private Map<String, ToscaProperty> findCommonOrInstancePropsInNodeTypes(ToscaNodeType nodeType, boolean common) {
+
+        var tempCommonPropertyMap = new HashMap<String, ToscaProperty>();
+        var tempInstancePropertyMap = new HashMap<String, ToscaProperty>();
+
+        nodeType.getProperties().forEach((propKey, prop) -> {
+
+            if (prop.getMetadata() != null) {
+                prop.getMetadata().forEach((k, v) -> {
+                    if (k.equals("common") && v.equals("true") && common) {
+                        tempCommonPropertyMap.put(propKey, prop);
+                    } else if (k.equals("common") && v.equals("false") && !common) {
+                        tempInstancePropertyMap.put(propKey, prop);
+                    }
+
+                });
+            } else {
+                tempInstancePropertyMap.put(propKey, prop);
+            }
+        });
+
+        if (tempCommonPropertyMap.isEmpty() && !common) {
+            return tempInstancePropertyMap;
+        } else {
+            return tempCommonPropertyMap;
+        }
+    }
+
+    /**
+     * Get the node types derived from those that have common properties.
+     *
+     * @param initialNodeTypes map of all the node types in the specified template
+     * @param filteredNodeTypes map of all the node types that have common or instance properties
+     * @return all node types that have common properties including their children
+     * @throws PfModelException on errors getting node type with common properties
+     */
+    private Map<String, ToscaNodeType> getFinalNodeTypesMap(Map<String, ToscaNodeType> initialNodeTypes,
+            Map<String, ToscaNodeType> filteredNodeTypes) {
+        for (var i = 0; i < initialNodeTypes.size(); i++) {
+            initialNodeTypes.forEach((key, nodeType) -> {
+                var tempToscaNodeType = new ToscaNodeType();
+                tempToscaNodeType.setName(key);
+
+                if (filteredNodeTypes.get(nodeType.getDerivedFrom()) != null) {
+                    tempToscaNodeType.setName(key);
+
+                    var finalProps = new HashMap<String, ToscaProperty>(
+                            filteredNodeTypes.get(nodeType.getDerivedFrom()).getProperties());
+
+                    tempToscaNodeType.setProperties(finalProps);
+                } else {
+                    return;
+                }
+                filteredNodeTypes.putIfAbsent(key, tempToscaNodeType);
+
+            });
+        }
+        return filteredNodeTypes;
+    }
+
+    /**
+     * Get the requested node types with common or instance properties.
+     *
+     * @param common boolean indicating common or instance properties
+     * @param serviceTemplate the ToscaServiceTemplate
+     * @return the node types with common or instance properties
+     * @throws PfModelException on errors getting node type properties
+     */
+    public Map<String, ToscaNodeType> getCommonOrInstancePropertiesFromNodeTypes(boolean common,
+            ToscaServiceTemplate serviceTemplate) throws PfModelException {
+        var tempNodeTypesMap = this.getInitialNodeTypesMap(serviceTemplate.getNodeTypes(), common);
+
+        return this.getFinalNodeTypesMap(serviceTemplate.getNodeTypes(), tempNodeTypesMap);
+
+    }
+
+    /**
+     * Get node templates with appropriate common or instance properties added.
+     *
+     * @param initialNodeTemplates map of all the node templates in the specified template
+     * @param nodeTypeProps map of all the node types that have common or instance properties including children
+     * @return all node templates with appropriate common or instance properties added
+     * @throws PfModelException on errors getting map of node templates with common or instance properties added
+     */
+    public Map<String, ToscaNodeTemplate> getDerivedCommonOrInstanceNodeTemplates(
+            Map<String, ToscaNodeTemplate> initialNodeTemplates, Map<String, ToscaNodeType> nodeTypeProps) {
+
+        var finalNodeTemplatesMap = new HashMap<String, ToscaNodeTemplate>();
+
+        initialNodeTemplates.forEach((templateKey, template) -> {
+            if (nodeTypeProps.containsKey(template.getType())) {
+                var finalMergedProps = new HashMap<String, Object>();
+
+                nodeTypeProps.get(template.getType()).getProperties().forEach(finalMergedProps::putIfAbsent);
+
+                template.setProperties(finalMergedProps);
+
+                finalNodeTemplatesMap.put(templateKey, template);
+            } else {
+                return;
+            }
+        });
+        return finalNodeTemplatesMap;
+    }
+}
diff --git a/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ServiceTemplateProviderTest.java b/models/src/test/java/org/onap/policy/clamp/controlloop/models/controlloop/persistence/provider/ServiceTemplateProviderTest.java
new file mode 100644 (file)
index 0000000..a4cbbfb
--- /dev/null
@@ -0,0 +1,161 @@
+/*-
+ * ============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.persistence.provider;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.common.utils.coder.StandardYamlCoder;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.provider.PolicyModelsProvider;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+class ServiceTemplateProviderTest {
+
+    private static final String TOSCA_SERVICE_TEMPLATE_YAML =
+            "src/test/resources/providers/tosca-for-smoke-testing.yaml";
+
+    private static final StandardYamlCoder YAML_TRANSLATOR = new StandardYamlCoder();
+
+    @Test
+    void testGetCommonOrInstancePropertiesFromNodeTypes() throws PfModelException {
+        var serviceTemplateProvider = new ServiceTemplateProvider(mock(PolicyModelsProvider.class));
+
+        var serviceTemplate = getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
+
+        var result = serviceTemplateProvider.getCommonOrInstancePropertiesFromNodeTypes(true, serviceTemplate);
+        assertNotNull(result);
+        assertThat(result).hasSize(8);
+    }
+
+    @Test
+    void testGetDerivedCommonOrInstanceNodeTemplates() throws PfModelException {
+        var serviceTemplateProvider = new ServiceTemplateProvider(mock(PolicyModelsProvider.class));
+
+        var serviceTemplate = getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
+
+        var commonOrInstanceNodeTypeProps =
+                serviceTemplateProvider.getCommonOrInstancePropertiesFromNodeTypes(true, serviceTemplate);
+
+        var result = serviceTemplateProvider.getDerivedCommonOrInstanceNodeTemplates(
+                serviceTemplate.getToscaTopologyTemplate().getNodeTemplates(), commonOrInstanceNodeTypeProps);
+
+        assertNotNull(result);
+        assertThat(result).hasSize(8);
+    }
+
+    @Test
+    void testCreateServiceTemplate() throws PfModelException {
+        var modelsProvider = mock(PolicyModelsProvider.class);
+        var serviceTemplateProvider = new ServiceTemplateProvider(modelsProvider);
+
+        var serviceTemplate = new ToscaServiceTemplate();
+        when(modelsProvider.createServiceTemplate(eq(serviceTemplate))).thenReturn(serviceTemplate);
+
+        var result = serviceTemplateProvider.createServiceTemplate(serviceTemplate);
+
+        assertThat(result).isEqualTo(serviceTemplate);
+    }
+
+    @Test
+    void testDeleteServiceTemplate() throws PfModelException {
+        var serviceTemplate = new ToscaServiceTemplate();
+        serviceTemplate.setName("Name");
+        serviceTemplate.setVersion("1.0.0");
+        var modelsProvider = mock(PolicyModelsProvider.class);
+        when(modelsProvider.deleteServiceTemplate(eq(serviceTemplate.getName()), eq(serviceTemplate.getVersion())))
+                .thenReturn(serviceTemplate);
+
+        var serviceTemplateProvider = new ServiceTemplateProvider(modelsProvider);
+        var result =
+                serviceTemplateProvider.deleteServiceTemplate(serviceTemplate.getName(), serviceTemplate.getVersion());
+
+        assertThat(result).isEqualTo(serviceTemplate);
+    }
+
+    @Test
+    void testGetServiceTemplateListEmpty() throws PfModelException {
+        var modelsProvider = mock(PolicyModelsProvider.class);
+        when(modelsProvider.getServiceTemplateList(any(String.class), any(String.class))).thenReturn(List.of());
+
+        var serviceTemplateProvider = new ServiceTemplateProvider(modelsProvider);
+        assertThatThrownBy(() -> serviceTemplateProvider.getToscaServiceTemplate("Name", "1.0.0"))
+                .hasMessage("Control Loop definitions not found");
+    }
+
+    @Test
+    void testGetServiceTemplateList() throws PfModelException {
+        var serviceTemplate = new ToscaServiceTemplate();
+        serviceTemplate.setName("Name");
+        serviceTemplate.setVersion("1.0.0");
+        var modelsProvider = mock(PolicyModelsProvider.class);
+        when(modelsProvider.getServiceTemplateList(eq(serviceTemplate.getName()), eq(serviceTemplate.getVersion())))
+                .thenReturn(List.of(serviceTemplate));
+
+        var serviceTemplateProvider = new ServiceTemplateProvider(modelsProvider);
+        var result = serviceTemplateProvider.getToscaServiceTemplate(serviceTemplate.getName(),
+                serviceTemplate.getVersion());
+
+        assertThat(result).isEqualTo(serviceTemplate);
+    }
+
+    @Test
+    void testGetServiceTemplate() throws PfModelException {
+        var serviceTemplate = new ToscaServiceTemplate();
+        serviceTemplate.setName("Name");
+        serviceTemplate.setVersion("1.0.0");
+        var modelsProvider = mock(PolicyModelsProvider.class);
+        when(modelsProvider.getServiceTemplateList(eq(serviceTemplate.getName()), eq(serviceTemplate.getVersion())))
+                .thenReturn(List.of(serviceTemplate));
+
+        var serviceTemplateProvider = new ServiceTemplateProvider(modelsProvider);
+        var result =
+                serviceTemplateProvider.getServiceTemplateList(serviceTemplate.getName(), serviceTemplate.getVersion());
+
+        assertThat(result).hasSize(1);
+        assertThat(result.get(0)).isEqualTo(serviceTemplate);
+    }
+
+    /**
+     * Get ToscaServiceTemplate from resource.
+     *
+     * @param path path of the resource
+     */
+    public static ToscaServiceTemplate getToscaServiceTemplate(String path) {
+
+        try {
+            return YAML_TRANSLATOR.decode(ResourceUtils.getResourceAsStream(path), ToscaServiceTemplate.class);
+        } catch (CoderException e) {
+            fail("Cannot read or decode " + path);
+            return null;
+        }
+    }
+}
diff --git a/models/src/test/resources/providers/tosca-for-smoke-testing.yaml b/models/src/test/resources/providers/tosca-for-smoke-testing.yaml
new file mode 100644 (file)
index 0000000..f69755e
--- /dev/null
@@ -0,0 +1,966 @@
+tosca_definitions_version: tosca_simple_yaml_1_3
+data_types:
+  onap.datatypes.ToscaConceptIdentifier:
+    derived_from: tosca.datatypes.Root
+    properties:
+      name:
+        type: string
+        required: true
+      version:
+        type: string
+        required: true
+  onap.datatype.controlloop.Target:
+    derived_from: tosca.datatypes.Root
+    description: Definition for a entity in A&AI to perform a control loop operation on
+    properties:
+      targetType:
+        type: string
+        description: Category for the target type
+        required: true
+        constraints:
+          - valid_values:
+              - VNF
+              - VM
+              - VFMODULE
+              - PNF
+      entityIds:
+        type: map
+        description: |
+          Map of values that identify the resource. If none are provided, it is assumed that the
+          entity that generated the ONSET event will be the target.
+        required: false
+        metadata:
+          clamp_possible_values: ClampExecution:CSAR_RESOURCES
+        entry_schema:
+          type: string
+  onap.datatype.controlloop.Actor:
+    derived_from: tosca.datatypes.Root
+    description: An actor/operation/target definition
+    properties:
+      actor:
+        type: string
+        description: The actor performing the operation.
+        required: true
+        metadata:
+          clamp_possible_values: Dictionary:DefaultActors,ClampExecution:CDS/actor
+      operation:
+        type: string
+        description: The operation the actor is performing.
+        metadata:
+          clamp_possible_values: Dictionary:DefaultOperations,ClampExecution:CDS/operation
+        required: true
+      target:
+        type: onap.datatype.controlloop.Target
+        description: The resource the operation should be performed on.
+        required: true
+      payload:
+        type: map
+        description: Name/value pairs of payload information passed by Policy to the actor
+        required: false
+        metadata:
+          clamp_possible_values: ClampExecution:CDS/payload
+        entry_schema:
+          type: string
+  onap.datatype.controlloop.Operation:
+    derived_from: tosca.datatypes.Root
+    description: An operation supported by an actor
+    properties:
+      id:
+        type: string
+        description: Unique identifier for the operation
+        required: true
+      description:
+        type: string
+        description: A user-friendly description of the intent for the operation
+        required: false
+      operation:
+        type: onap.datatype.controlloop.Actor
+        description: The definition of the operation to be performed.
+        required: true
+      timeout:
+        type: integer
+        description: The amount of time for the actor to perform the operation.
+        required: true
+      retries:
+        type: integer
+        description: The number of retries the actor should attempt to perform the operation.
+        required: true
+        default: 0
+      success:
+        type: string
+        description: Points to the operation to invoke on success. A value of "final_success" indicates and end to the operation.
+        required: false
+        default: final_success
+      failure:
+        type: string
+        description: Points to the operation to invoke on Actor operation failure.
+        required: false
+        default: final_failure
+      failure_timeout:
+        type: string
+        description: Points to the operation to invoke when the time out for the operation occurs.
+        required: false
+        default: final_failure_timeout
+      failure_retries:
+        type: string
+        description: Points to the operation to invoke when the current operation has exceeded its max retries.
+        required: false
+        default: final_failure_retries
+      failure_exception:
+        type: string
+        description: Points to the operation to invoke when the current operation causes an exception.
+        required: false
+        default: final_failure_exception
+      failure_guard:
+        type: string
+        description: Points to the operation to invoke when the current operation is blocked due to guard policy enforcement.
+        required: false
+        default: final_failure_guard
+  onap.datatypes.monitoring.managedObjectDNsBasic:
+    constraints: []
+    properties:
+      DN:
+        name: DN
+        type: string
+        typeVersion: 0.0.0
+        description: Managed object distinguished name
+        required: true
+        constraints: []
+        metadata: {}
+    name: onap.datatypes.monitoring.managedObjectDNsBasic
+    version: 0.0.0
+    derived_from: tosca.datatypes.Root
+    metadata: {}
+  onap.datatypes.monitoring.managedObjectDNsBasics:
+    constraints: []
+    properties:
+      managedObjectDNsBasic:
+        name: managedObjectDNsBasic
+        type: map
+        typeVersion: 0.0.0
+        description: Managed object distinguished name object
+        required: true
+        constraints: []
+        entry_schema:
+          type: onap.datatypes.monitoring.managedObjectDNsBasic
+          typeVersion: 0.0.0
+          constraints: []
+        metadata: {}
+    name: onap.datatypes.monitoring.managedObjectDNsBasics
+    version: 0.0.0
+    derived_from: tosca.datatypes.Root
+    metadata: {}
+  onap.datatypes.monitoring.measurementGroup:
+    constraints: []
+    properties:
+      measurementTypes:
+        name: measurementTypes
+        type: list
+        typeVersion: 0.0.0
+        description: List of measurement types
+        required: true
+        constraints: []
+        entry_schema:
+          type: onap.datatypes.monitoring.measurementTypes
+          typeVersion: 0.0.0
+          constraints: []
+        metadata: {}
+      managedObjectDNsBasic:
+        name: managedObjectDNsBasic
+        type: list
+        typeVersion: 0.0.0
+        description: List of managed object distinguished names
+        required: true
+        constraints: []
+        entry_schema:
+          type: onap.datatypes.monitoring.managedObjectDNsBasics
+          typeVersion: 0.0.0
+          constraints: []
+        metadata: {}
+    name: onap.datatypes.monitoring.measurementGroup
+    version: 0.0.0
+    derived_from: tosca.datatypes.Root
+    metadata: {}
+  onap.datatypes.monitoring.measurementGroups:
+    constraints: []
+    properties:
+      measurementGroup:
+        name: measurementGroup
+        type: map
+        typeVersion: 0.0.0
+        description: Measurement Group
+        required: true
+        constraints: []
+        entry_schema:
+          type: onap.datatypes.monitoring.measurementGroup
+          typeVersion: 0.0.0
+          constraints: []
+        metadata: {}
+    name: onap.datatypes.monitoring.measurementGroups
+    version: 0.0.0
+    derived_from: tosca.datatypes.Root
+    metadata: {}
+  onap.datatypes.monitoring.measurementType:
+    constraints: []
+    properties:
+      measurementType:
+        name: measurementType
+        type: string
+        typeVersion: 0.0.0
+        description: Measurement type
+        required: true
+        constraints: []
+        metadata: {}
+    name: onap.datatypes.monitoring.measurementType
+    version: 0.0.0
+    derived_from: tosca.datatypes.Root
+    metadata: {}
+  onap.datatypes.monitoring.measurementTypes:
+    constraints: []
+    properties:
+      measurementType:
+        name: measurementType
+        type: map
+        typeVersion: 0.0.0
+        description: Measurement type object
+        required: true
+        constraints: []
+        entry_schema:
+          type: onap.datatypes.monitoring.measurementType
+          typeVersion: 0.0.0
+          constraints: []
+        metadata: {}
+    name: onap.datatypes.monitoring.measurementTypes
+    version: 0.0.0
+    derived_from: tosca.datatypes.Root
+    metadata: {}
+  onap.datatypes.monitoring.nfFilter:
+    constraints: []
+    properties:
+      modelNames:
+        name: modelNames
+        type: list
+        typeVersion: 0.0.0
+        description: List of model names
+        required: true
+        constraints: []
+        entry_schema:
+          type: string
+          typeVersion: 0.0.0
+          constraints: []
+        metadata: {}
+      modelInvariantIDs:
+        name: modelInvariantIDs
+        type: list
+        typeVersion: 0.0.0
+        description: List of model invariant IDs
+        required: true
+        constraints: []
+        entry_schema:
+          type: string
+          typeVersion: 0.0.0
+          constraints: []
+        metadata: {}
+      modelVersionIDs:
+        name: modelVersionIDs
+        type: list
+        typeVersion: 0.0.0
+        description: List of model version IDs
+        required: true
+        constraints: []
+        entry_schema:
+          type: string
+          typeVersion: 0.0.0
+          constraints: []
+        metadata: {}
+      nfNames:
+        name: nfNames
+        type: list
+        typeVersion: 0.0.0
+        description: List of network functions
+        required: true
+        constraints: []
+        entry_schema:
+          type: string
+          typeVersion: 0.0.0
+          constraints: []
+        metadata: {}
+    name: onap.datatypes.monitoring.nfFilter
+    version: 0.0.0
+    derived_from: tosca.datatypes.Root
+    metadata: {}
+  onap.datatypes.monitoring.subscription:
+    constraints: []
+    properties:
+      measurementGroups:
+        name: measurementGroups
+        type: list
+        typeVersion: 0.0.0
+        description: Measurement Groups
+        required: true
+        constraints: []
+        entry_schema:
+          type: onap.datatypes.monitoring.measurementGroups
+          typeVersion: 0.0.0
+          constraints: []
+        metadata: {}
+      fileBasedGP:
+        name: fileBasedGP
+        type: integer
+        typeVersion: 0.0.0
+        description: File based granularity period
+        required: true
+        constraints: []
+        metadata: {}
+      fileLocation:
+        name: fileLocation
+        type: string
+        typeVersion: 0.0.0
+        description: ROP file location
+        required: true
+        constraints: []
+        metadata: {}
+      subscriptionName:
+        name: subscriptionName
+        type: string
+        typeVersion: 0.0.0
+        description: Name of the subscription
+        required: true
+        constraints: []
+        metadata: {}
+      administrativeState:
+        name: administrativeState
+        type: string
+        typeVersion: 0.0.0
+        description: State of the subscription
+        required: true
+        constraints:
+          - valid_values:
+              - LOCKED
+              - UNLOCKED
+        metadata: {}
+      nfFilter:
+        name: nfFilter
+        type: map
+        typeVersion: 0.0.0
+        description: Network function filter
+        required: true
+        constraints: []
+        entry_schema:
+          type: onap.datatypes.monitoring.nfFilter
+          typeVersion: 0.0.0
+          constraints: []
+        metadata: {}
+    name: onap.datatypes.monitoring.subscription
+    version: 0.0.0
+    derived_from: tosca.datatypes.Root
+    metadata: {}
+  org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.RestRequest:
+    version: 1.0.0
+    derived_from: tosca.datatypes.Root
+    properties:
+      restRequestId:
+        type:  onap.datatypes.ToscaConceptIdentifier
+        typeVersion: 1.0.0
+        required: true
+        description: The name and version of a REST request to be sent to a REST endpoint
+      httpMethod:
+        type: string
+        required: true
+        constraints:
+          - valid_values: [POST, PUT, GET, DELETE]
+        description: The REST method to use
+      path:
+        type: string
+        required: true
+        description: The path of the REST request relative to the base URL
+      body:
+        type: string
+        required: false
+        description: The body of the REST request for PUT and POST requests
+      expectedResponse:
+        type: integer
+        required: true
+        constraints: []
+        description: THe expected HTTP status code for the REST request
+    org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.ConfigurationEntity:
+      version: 1.0.0
+      derived_from: tosca.datatypes.Root
+      properties:
+        configurationEntityId:
+          type:  onap.datatypes.ToscaConceptIdentifier
+          typeVersion: 1.0.0
+          required: true
+          description: The name and version of a Configuration Entity to be handled by the HTTP Control Loop Element
+        restSequence:
+          type: list
+          entry_schema:
+            type: org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.RestRequest
+            typeVersion: 1.0.0
+          description: A sequence of REST commands to send to the REST endpoint
+policy_types:
+  onap.policies.Monitoring:
+    derived_from: tosca.policies.Root
+    description: a base policy type for all policies that govern monitoring provisioning
+    version: 1.0.0
+    name: onap.policies.Monitoring
+  onap.policies.Sirisha:
+    derived_from: tosca.policies.Root
+    description: a base policy type for all policies that govern monitoring provisioning
+    version: 1.0.0
+    name: onap.policies.Sirisha
+  onap.policies.monitoring.dcae-pm-subscription-handler:
+    properties:
+      pmsh_policy:
+        name: pmsh_policy
+        type: onap.datatypes.monitoring.subscription
+        typeVersion: 0.0.0
+        description: PMSH Policy JSON
+        required: false
+        constraints: []
+        metadata: {}
+    name: onap.policies.monitoring.dcae-pm-subscription-handler
+    version: 1.0.0
+    derived_from: onap.policies.Monitoring
+    metadata: {}
+  onap.policies.controlloop.operational.Common:
+    derived_from: tosca.policies.Root
+    version: 1.0.0
+    name: onap.policies.controlloop.operational.Common
+    description: |
+      Operational Policy for Control Loop execution. Originated in Frankfurt to support TOSCA Compliant
+      Policy Types. This does NOT support the legacy Policy YAML policy type.
+    properties:
+      id:
+        type: string
+        description: The unique control loop id.
+        required: true
+      timeout:
+        type: integer
+        description: |
+          Overall timeout for executing all the operations. This timeout should equal or exceed the total
+          timeout for each operation listed.
+        required: true
+      abatement:
+        type: boolean
+        description: Whether an abatement event message will be expected for the control loop from DCAE.
+        required: true
+        default: false
+      trigger:
+        type: string
+        description: Initial operation to execute upon receiving an Onset event message for the Control Loop.
+        required: true
+      operations:
+        type: list
+        description: List of operations to be performed when Control Loop is triggered.
+        required: true
+        entry_schema:
+          type: onap.datatype.controlloop.Operation
+  onap.policies.controlloop.operational.common.Apex:
+    derived_from: onap.policies.controlloop.operational.Common
+    type_version: 1.0.0
+    version: 1.0.0
+    name: onap.policies.controlloop.operational.common.Apex
+    description: Operational policies for Apex PDP
+    properties:
+      engineServiceParameters:
+        type: string
+        description: The engine parameters like name, instanceCount, policy implementation, parameters etc.
+        required: true
+      eventInputParameters:
+        type: string
+        description: The event input parameters.
+        required: true
+      eventOutputParameters:
+        type: string
+        description: The event output parameters.
+        required: true
+      javaProperties:
+        type: string
+        description: Name/value pairs of properties to be set for APEX if needed.
+        required: false
+node_types:
+  org.onap.policy.clamp.controlloop.Participant:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
+    properties:
+      provider:
+        type: string
+        requred: false
+  org.onap.policy.clamp.controlloop.ControlLoopElement:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
+    properties:
+      provider:
+        type: string
+        required: false
+        metadata:
+          common: true
+        description: Specifies the organization that provides the control loop element
+      participant_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+        metadata:
+          common: true
+      participantType:
+        type: onap.datatypes.ToscaConceptIdentifier
+        required: true
+        metadata:
+          common: true
+        description: The identity of the participant type that hosts this type of Control Loop Element
+      startPhase:
+        type: integer
+        required: false
+        constraints:
+          - greater_or_equal: 0
+        metadata:
+          common: true
+        description: A value indicating the start phase in which this control loop element will be started, the
+          first start phase is zero. Control Loop Elements are started in their start_phase order and stopped
+          in reverse start phase order. Control Loop Elements with the same start phase are started and
+          stopped simultaneously
+      uninitializedToPassiveTimeout:
+        type: integer
+        required: false
+        constraints:
+          - greater_or_equal: 0
+        default: 60
+        metadata:
+          common: true
+        description: The maximum time in seconds to wait for a state chage from uninitialized to passive
+      passiveToRunningTimeout:
+        type: integer
+        required: false
+        constraints:
+          - greater_or_equal: 0
+        default: 60
+        metadata:
+          common: true
+        description: The maximum time in seconds to wait for a state chage from passive to running
+      runningToPassiveTimeout:
+        type: integer
+        required: false
+        constraints:
+          - greater_or_equal: 0
+        default: 60
+        metadata:
+          common: true
+        description: The maximum time in seconds to wait for a state chage from running to passive
+      passiveToUninitializedTimeout:
+        type: integer
+        required: false
+        constraints:
+          - greater_or_equal: 0
+        default: 60
+        metadata:
+          common: true
+        description: The maximum time in seconds to wait for a state chage from passive to uninitialized
+  org.onap.policy.clamp.controlloop.ControlLoop:
+    version: 1.0.1
+    derived_from: tosca.nodetypes.Root
+    properties:
+      provider:
+        type: string
+        required: false
+        metadata:
+          common: true
+        description: Specifies the organization that provides the control loop element
+      elements:
+        type: list
+        required: true
+        metadata:
+          common: true
+        entry_schema:
+          type: onap.datatypes.ToscaConceptIdentifier
+        description: Specifies a list of control loop element definitions that make up this control loop definition
+  org.onap.policy.clamp.controlloop.PolicyControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
+    properties:
+      policy_type_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+      policy_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: false
+  org.onap.policy.clamp.controlloop.DerivedPolicyControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.PolicyControlLoopElement
+    properties:
+      policy_type_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+      policy_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: false
+  org.onap.policy.clamp.controlloop.DerivedDerivedPolicyControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.DerivedPolicyControlLoopElement
+    properties:
+      policy_type_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: true
+      policy_id:
+        type: onap.datatypes.ToscaConceptIdentifier
+        requred: false
+  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
+  org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
+    properties:
+      chart:
+        type: string
+        required: true
+      configs:
+        type: list
+        required: false
+      requirements:
+        type: string
+        requred: false
+      templates:
+        type: list
+        required: false
+        entry_schema:
+      values:
+        type: string
+        requred: true
+  org.onap.policy.clamp.controlloop.HttpControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
+    properties:
+      baseUrl:
+        type: string
+        required: true
+        description: The base URL to be prepended to each path, identifies the host for the REST endpoints.
+      httpHeaders:
+        type: map
+        required: false
+        entry_schema:
+          type: string
+        description: HTTP headers to send on REST requests
+      configurationEntities:
+        type: map
+        required: true
+        entry_schema:
+          type: org.onap.datatypes.policy.clamp.controlloop.httpControlLoopElement.ConfigurationEntity
+          typeVersion: 1.0.0
+        description: The connfiguration entities the Control Loop Element is managing and their associated REST requests
+
+topology_template:
+  inputs:
+    pmsh_monitoring_policy:
+      type: onap.datatypes.ToscaConceptIdentifier
+      description: The ID of the PMSH monitoring policy to use
+      default:
+        name: MICROSERVICE_vLoadBalancerMS_v1_0_dcae-pm-subscription-handler_1_0_0test
+        version: 1.0.0
+    pmsh_operational_policy:
+      type: onap.datatypes.ToscaConceptIdentifier
+      description: The ID of the PMSH operational policy to use
+      default:
+        name: operational.apex.pmcontrol
+        version: 1.0.0
+  node_templates:
+    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.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.PolicyControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the monitoring policy for Performance Management Subscription Handling
+      properties:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.PM_Policy
+          version: 1.0.0
+        participantType:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.3.1
+        policy_type_id:
+          name: onap.policies.monitoring.pm-subscription-handler
+          version: 1.0.0
+        policy_id:
+          get_input: pmsh_monitoring_policy
+    org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.PolicyControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the operational policy for Performance Management Subscription Handling
+      properties:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.PM_Policy
+          version: 1.0.0
+        participantType:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.3.1
+        policy_type_id:
+          name: onap.policies.operational.pm-subscription-handler
+          version: 1.0.0
+        policy_id:
+          get_input: pmsh_operational_policy
+    org.onap.domain.pmsh.DerivedPolicyControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.DerivedPolicyControlLoopElement
+      type_version: 1.0.0
+      description: Control loop for Performance Management Subscription Handling
+      properties:
+        provider: Ericsson
+        participantType:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.3.1
+        participant_id:
+          name: org.onap.PM_Policy
+          version: 1.0.0
+    org.onap.domain.pmsh.DerivedDerivedPolicyControlLoopElement:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.DerivedDerivedPolicyControlLoopElement
+      type_version: 1.0.0
+      description: Control loop for Performance Management Subscription Handling
+      properties:
+        provider: Ericsson
+        participantType:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.3.1
+        participant_id:
+          name: org.onap.PM_Policy
+          version: 1.0.0
+    org.onap.k8s.controlloop.K8SControlLoopParticipant:
+      version: 2.3.4
+      type: org.onap.policy.clamp.controlloop.Participant
+      type_version: 1.0.1
+      description: Participant for K8S
+      properties:
+        provider: ONAP
+    org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement:
+      # Chart from new repository
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the K8S microservice for PMSH
+      properties:
+        provider: ONAP
+        participant_id:
+          name: K8sParticipant0
+          version: 1.0.0
+        participantType:
+          name: org.onap.k8s.controlloop.K8SControlLoopParticipant
+          version: 2.3.4
+        chart:
+          chartId:
+            name: dcae-pmsh
+            version: 8.0.0
+          namespace: onap
+          releaseName: pmshms
+          repository:
+            repoName: chartmuseum
+            protocol: http
+            address: 10.152.183.120
+            port: 80
+            userName: onapinitializer
+            password: demo123456!
+          overrideParams:
+            global.masterPassword: test
+
+    org.onap.domain.database.Local_K8SMicroserviceControlLoopElement:
+      # Chart installation without passing repository info
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.K8SMicroserviceControlLoopElement
+      type_version: 1.0.0
+      description: Control loop element for the K8S microservice for local chart
+      properties:
+        provider: ONAP
+        participant_id:
+          name: K8sParticipant0
+          version: 1.0.0
+        participantType:
+          name: org.onap.k8s.controlloop.K8SControlLoopParticipant
+          version: 2.3.4
+        chart:
+          chartId:
+            name: nginx-ingress
+            version: 0.9.1
+          releaseName: nginxms
+          namespace: test
+    org.onap.controlloop.HttpControlLoopParticipant:
+      version: 2.3.4
+      type: org.onap.policy.clamp.controlloop.Participant
+      type_version: 1.0.1
+      description: Participant for Http requests
+      properties:
+        provider: ONAP
+    org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement:
+      # Consul http config for PMSH.
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.HttpControlLoopElement
+      type_version: 1.0.1
+      description: Control loop element for the http requests of PMSH microservice
+      properties:
+        provider: ONAP
+        participant_id:
+          name: HttpParticipant0
+          version: 1.0.0
+        participantType:
+          name: org.onap.k8s.controlloop.HttpControlLoopParticipant
+          version: 2.3.4
+        uninitializedToPassiveTimeout: 180
+        startPhase: 1
+        baseUrl: http://10.152.183.51:8500
+        httpHeaders:
+          Content-Type: application/json
+        configurationEntities:
+          - configurationEntityId:
+              name: entity1
+              version: 1.0.1
+            restSequence:
+              - restRequestId:
+                  name: request1
+                  version: 1.0.1
+                httpMethod: PUT
+                path: v1/kv/dcae-pmsh2
+                body: '{
+      "control_loop_name":"pmsh-control-loop",
+      "operational_policy_name":"pmsh-operational-policy",
+      "aaf_password":"demo123456!",
+      "aaf_identity":"dcae@dcae.onap.org",
+      "cert_path":"/opt/app/pmsh/etc/certs/cert.pem",
+      "key_path":"/opt/app/pmsh/etc/certs/key.pem",
+      "ca_cert_path":"/opt/app/pmsh/etc/certs/cacert.pem",
+      "enable_tls":"true",
+      "pmsh_policy":{
+         "subscription":{
+            "subscriptionName":"ExtraPM-All-gNB-R2B",
+            "administrativeState":"UNLOCKED",
+            "fileBasedGP":15,
+            "fileLocation":"\/pm\/pm.xml",
+            "nfFilter":{
+               "nfNames":[
+                  "^pnf.*",
+                  "^vnf.*"
+               ],
+               "modelInvariantIDs":[
+               ],
+               "modelVersionIDs":[
+               ],
+               "modelNames":[
+               ]
+            },
+            "measurementGroups":[
+               {
+                  "measurementGroup":{
+                     "measurementTypes":[
+                        {
+                           "measurementType":"countera"
+                        },
+                        {
+                           "measurementType":"counterb"
+                        }
+                     ],
+                     "managedObjectDNsBasic":[
+                        {
+                           "DN":"dna"
+                        },
+                        {
+                           "DN":"dnb"
+                        }
+                     ]
+                  }
+               },
+               {
+                  "measurementGroup":{
+                     "measurementTypes":[
+                        {
+                           "measurementType":"counterc"
+                        },
+                        {
+                           "measurementType":"counterd"
+                        }
+                     ],
+                     "managedObjectDNsBasic":[
+                        {
+                           "DN":"dnc"
+                        },
+                        {
+                           "DN":"dnd"
+                        }
+                     ]
+                  }
+               }
+            ]
+         }
+      },
+      "streams_subscribes":{
+         "aai_subscriber":{
+            "type":"message_router",
+            "dmaap_info":{
+               "topic_url":"https://10.152.183.151:3905/events/AAI_EVENT",
+               "client_role":"org.onap.dcae.aaiSub",
+               "location":"san-francisco",
+               "client_id":"1575976809466"
+            }
+         },
+         "policy_pm_subscriber":{
+            "type":"message_router",
+            "dmaap_info":{
+               "topic_url":"https://10.152.183.151:3905/events/org.onap.dmaap.mr.PM_SUBSCRIPTIONS",
+               "client_role":"org.onap.dcae.pmSubscriber",
+               "location":"san-francisco",
+               "client_id":"1575876809456"
+            }
+         }
+      },
+      "streams_publishes":{
+         "policy_pm_publisher":{
+            "type":"message_router",
+            "dmaap_info":{
+               "topic_url":"https://10.152.183.151:3905/events/org.onap.dmaap.mr.PM_SUBSCRIPTIONS",
+               "client_role":"org.onap.dcae.pmPublisher",
+               "location":"san-francisco",
+               "client_id":"1475976809466"
+            }
+         },
+         "other_publisher":{
+            "type":"message_router",
+            "dmaap_info":{
+               "topic_url":"https://10.152.183.151:3905/events/org.onap.dmaap.mr.SOME_OTHER_TOPIC",
+               "client_role":"org.onap.dcae.pmControlPub",
+               "location":"san-francisco",
+               "client_id":"1875976809466"
+            }
+         }
+      }
+   }'
+                expectedResponse: 200
+    org.onap.domain.sample.GenericK8s_ControlLoopDefinition:
+      version: 1.2.3
+      type: org.onap.policy.clamp.controlloop.ControlLoop
+      type_version: 1.0.0
+      description: Control loop for Hello World
+      properties:
+        provider: ONAP
+        elements:
+          - name: org.onap.domain.database.PMSH_K8SMicroserviceControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.database.Local_K8SMicroserviceControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.database.Http_PMSHMicroserviceControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.DerivedPolicyControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.DerivedDerivedPolicyControlLoopElement
+            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
index d2d57ed..72c153b 100644 (file)
@@ -37,17 +37,16 @@ import org.apache.commons.collections4.MapUtils;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.Participant;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
+import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ServiceTemplateProvider;
 import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse;
 import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
 import org.onap.policy.models.base.PfModelException;
-import org.onap.policy.models.provider.PolicyModelsProvider;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaCapabilityType;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaPolicyType;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaProperty;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaRelationshipType;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplates;
@@ -64,7 +63,7 @@ public class CommissioningProvider {
     public static final String CONTROL_LOOP_NODE_TYPE = "org.onap.policy.clamp.controlloop.ControlLoop";
     private static final String INSTANCE_TEXT = "_Instance";
 
-    private final PolicyModelsProvider modelsProvider;
+    private final ServiceTemplateProvider serviceTemplateProvider;
     private final ControlLoopProvider clProvider;
     private final ObjectMapper mapper = new ObjectMapper();
     private final ParticipantProvider participantProvider;
@@ -75,14 +74,14 @@ public class CommissioningProvider {
     /**
      * Create a commissioning provider.
      *
-     * @param modelsProvider the PolicyModelsProvider
-     * @param clProvider the ControlLoopProvider
+     * @param serviceTemplateProvider the ServiceTemplate Provider
+     * @param clProvider the ControlLoop Provider
+     * @param supervisionHandler the Supervision Handler
+     * @param participantProvider the Participant Provider
      */
-    public CommissioningProvider(PolicyModelsProvider modelsProvider,
-                                 ControlLoopProvider clProvider,
-                                 SupervisionHandler supervisionHandler,
-                                 ParticipantProvider participantProvider) {
-        this.modelsProvider = modelsProvider;
+    public CommissioningProvider(ServiceTemplateProvider serviceTemplateProvider, ControlLoopProvider clProvider,
+            SupervisionHandler supervisionHandler, ParticipantProvider participantProvider) {
+        this.serviceTemplateProvider = serviceTemplateProvider;
         this.clProvider = clProvider;
         this.supervisionHandler = supervisionHandler;
         this.participantProvider = participantProvider;
@@ -97,22 +96,17 @@ public class CommissioningProvider {
      * @throws PfModelException on creation errors
      */
     public CommissioningResponse createControlLoopDefinitions(ToscaServiceTemplate serviceTemplate)
-        throws PfModelException {
+            throws PfModelException {
 
         if (verifyIfInstancePropertiesExists()) {
-            throw new PfModelException(Status.BAD_REQUEST,
-                "Delete instances, to commission control loop definitions");
+            throw new PfModelException(Status.BAD_REQUEST, "Delete instances, to commission control loop definitions");
         }
 
         synchronized (lockit) {
-            modelsProvider.createServiceTemplate(serviceTemplate);
-            List<Participant> participantList =
-                participantProvider.getParticipants(null, null);
+            serviceTemplateProvider.createServiceTemplate(serviceTemplate);
+            List<Participant> participantList = participantProvider.getParticipants(null, null);
             if (!participantList.isEmpty()) {
-                this.supervisionHandler.handleSendCommissionMessage(
-                    getCommonOrInstancePropertiesFromNodeTypes(true,
-                        serviceTemplate.getName(),
-                        serviceTemplate.getVersion()));
+                supervisionHandler.handleSendCommissionMessage(serviceTemplate.getName(), serviceTemplate.getVersion());
             }
         }
 
@@ -136,22 +130,18 @@ public class CommissioningProvider {
      * @return the result of the deletion
      * @throws PfModelException on deletion errors
      */
-    public CommissioningResponse deleteControlLoopDefinition(String name, String version)
-        throws PfModelException {
+    public CommissioningResponse deleteControlLoopDefinition(String name, String version) throws PfModelException {
 
         if (verifyIfInstancePropertiesExists()) {
-            throw new PfModelException(Status.BAD_REQUEST,
-                "Delete instances, to commission control loop definitions");
+            throw new PfModelException(Status.BAD_REQUEST, "Delete instances, to commission control loop definitions");
         }
 
         synchronized (lockit) {
-            List<Participant> participantList =
-                participantProvider.getParticipants(null,
-                    null);
+            List<Participant> participantList = participantProvider.getParticipants(null, null);
             if (!participantList.isEmpty()) {
-                this.supervisionHandler.handleSendDeCommissionMessage();
+                supervisionHandler.handleSendDeCommissionMessage();
             }
-            modelsProvider.deleteServiceTemplate(name, version);
+            serviceTemplateProvider.deleteServiceTemplate(name, version);
         }
 
         var response = new CommissioningResponse();
@@ -223,143 +213,6 @@ public class CommissioningProvider {
         return controlLoopElementList;
     }
 
-    /**
-     * Get the initial node types with common or instance properties.
-     *
-     * @param fullNodeTypes map of all the node types in the specified template
-     * @param common boolean to indicate whether common or instance properties are required
-     * @return node types map that only has common properties
-     * @throws PfModelException on errors getting node type with common properties
-     */
-    private Map<String, ToscaNodeType> getInitialNodeTypesMap(Map<String, ToscaNodeType> fullNodeTypes,
-            boolean common) {
-
-        var tempNodeTypesMap = new HashMap<String, ToscaNodeType>();
-
-        fullNodeTypes.forEach((key, nodeType) -> {
-            var tempToscaNodeType = new ToscaNodeType();
-            tempToscaNodeType.setName(key);
-
-            var resultantPropertyMap = findCommonOrInstancePropsInNodeTypes(nodeType, common);
-
-            if (!resultantPropertyMap.isEmpty()) {
-                tempToscaNodeType.setProperties(resultantPropertyMap);
-                tempNodeTypesMap.put(key, tempToscaNodeType);
-            }
-        });
-        return tempNodeTypesMap;
-    }
-
-    private Map<String, ToscaProperty> findCommonOrInstancePropsInNodeTypes(ToscaNodeType nodeType, boolean common) {
-
-        var tempCommonPropertyMap = new HashMap<String, ToscaProperty>();
-        var tempInstancePropertyMap = new HashMap<String, ToscaProperty>();
-
-        nodeType.getProperties().forEach((propKey, prop) -> {
-
-            if (prop.getMetadata() != null) {
-                prop.getMetadata().forEach((k, v) -> {
-                    if (k.equals("common") && v.equals("true") && common) {
-                        tempCommonPropertyMap.put(propKey, prop);
-                    } else if (k.equals("common") && v.equals("false") && !common) {
-                        tempInstancePropertyMap.put(propKey, prop);
-                    }
-
-                });
-            } else {
-                tempInstancePropertyMap.put(propKey, prop);
-            }
-        });
-
-        if (tempCommonPropertyMap.isEmpty() && !common) {
-            return tempInstancePropertyMap;
-        } else {
-            return tempCommonPropertyMap;
-        }
-    }
-
-    /**
-     * Get the node types derived from those that have common properties.
-     *
-     * @param initialNodeTypes map of all the node types in the specified template
-     * @param filteredNodeTypes map of all the node types that have common or instance properties
-     * @return all node types that have common properties including their children
-     * @throws PfModelException on errors getting node type with common properties
-     */
-    private Map<String, ToscaNodeType> getFinalNodeTypesMap(Map<String, ToscaNodeType> initialNodeTypes,
-            Map<String, ToscaNodeType> filteredNodeTypes) {
-        for (var i = 0; i < initialNodeTypes.size(); i++) {
-            initialNodeTypes.forEach((key, nodeType) -> {
-                var tempToscaNodeType = new ToscaNodeType();
-                tempToscaNodeType.setName(key);
-
-                if (filteredNodeTypes.get(nodeType.getDerivedFrom()) != null) {
-                    tempToscaNodeType.setName(key);
-
-                    var finalProps = new HashMap<String, ToscaProperty>(
-                            filteredNodeTypes.get(nodeType.getDerivedFrom()).getProperties());
-
-                    tempToscaNodeType.setProperties(finalProps);
-                } else {
-                    return;
-                }
-                filteredNodeTypes.putIfAbsent(key, tempToscaNodeType);
-
-            });
-        }
-        return filteredNodeTypes;
-    }
-
-    /**
-     * Get the requested node types with common or instance properties.
-     *
-     * @param common boolean indicating common or instance properties
-     * @param name the name of the definition to get, null for all definitions
-     * @param version the version of the definition to get, null for all definitions
-     * @return the node types with common or instance properties
-     * @throws PfModelException on errors getting node type properties
-     */
-    public Map<String, ToscaNodeType> getCommonOrInstancePropertiesFromNodeTypes(boolean common, String name,
-            String version) throws PfModelException {
-        var serviceTemplates = new ToscaServiceTemplates();
-        serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version));
-        var tempNodeTypesMap =
-                this.getInitialNodeTypesMap(serviceTemplates.getServiceTemplates().get(0).getNodeTypes(), common);
-
-        return this.getFinalNodeTypesMap(serviceTemplates.getServiceTemplates().get(0).getNodeTypes(),
-                tempNodeTypesMap);
-
-    }
-
-    /**
-     * Get node templates with appropriate common or instance properties added.
-     *
-     * @param initialNodeTemplates map of all the node templates in the specified template
-     * @param nodeTypeProps map of all the node types that have common or instance properties including children
-     * @return all node templates with appropriate common or instance properties added
-     * @throws PfModelException on errors getting map of node templates with common or instance properties added
-     */
-    private Map<String, ToscaNodeTemplate> getDerivedCommonOrInstanceNodeTemplates(
-            Map<String, ToscaNodeTemplate> initialNodeTemplates, Map<String, ToscaNodeType> nodeTypeProps) {
-
-        var finalNodeTemplatesMap = new HashMap<String, ToscaNodeTemplate>();
-
-        initialNodeTemplates.forEach((templateKey, template) -> {
-            if (nodeTypeProps.containsKey(template.getType())) {
-                var finalMergedProps = new HashMap<String, Object>();
-
-                nodeTypeProps.get(template.getType()).getProperties().forEach(finalMergedProps::putIfAbsent);
-
-                template.setProperties(finalMergedProps);
-
-                finalNodeTemplatesMap.put(templateKey, template);
-            } else {
-                return;
-            }
-        });
-        return finalNodeTemplatesMap;
-    }
-
     /**
      * Get node templates with common properties added.
      *
@@ -374,17 +227,17 @@ public class CommissioningProvider {
 
         if (common && verifyIfInstancePropertiesExists()) {
             throw new PfModelException(Status.BAD_REQUEST,
-                "Cannot create or edit common properties, delete all the instantiations first");
+                    "Cannot create or edit common properties, delete all the instantiations first");
         }
 
+        var serviceTemplateList = serviceTemplateProvider.getServiceTemplateList(name, version);
         var commonOrInstanceNodeTypeProps =
-            this.getCommonOrInstancePropertiesFromNodeTypes(common, name, version);
+                serviceTemplateProvider.getCommonOrInstancePropertiesFromNodeTypes(common, serviceTemplateList.get(0));
 
         var serviceTemplates = new ToscaServiceTemplates();
-        serviceTemplates.setServiceTemplates(filterToscaNodeTemplateInstance(
-            modelsProvider.getServiceTemplateList(name, version)));
+        serviceTemplates.setServiceTemplates(filterToscaNodeTemplateInstance(serviceTemplateList));
 
-        return this.getDerivedCommonOrInstanceNodeTemplates(
+        return serviceTemplateProvider.getDerivedCommonOrInstanceNodeTemplates(
                 serviceTemplates.getServiceTemplates().get(0).getToscaTopologyTemplate().getNodeTemplates(),
                 commonOrInstanceNodeTypeProps);
     }
@@ -398,9 +251,7 @@ public class CommissioningProvider {
      * @throws PfModelException on errors getting control loop definitions
      */
     public ToscaServiceTemplate getToscaServiceTemplate(String name, String version) throws PfModelException {
-        var serviceTemplates = new ToscaServiceTemplates();
-        serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version));
-        return serviceTemplates.getServiceTemplates().get(0);
+        return serviceTemplateProvider.getToscaServiceTemplate(name, version);
     }
 
     /**
@@ -411,14 +262,11 @@ public class CommissioningProvider {
      * @return the tosca service template
      * @throws PfModelException on errors getting tosca service template
      */
-    public String getToscaServiceTemplateReduced(String name, String version)
-        throws PfModelException {
+    public String getToscaServiceTemplateReduced(String name, String version) throws PfModelException {
 
-        var serviceTemplates = new ToscaServiceTemplates();
-        serviceTemplates.setServiceTemplates(modelsProvider.getServiceTemplateList(name, version));
+        var serviceTemplateList = serviceTemplateProvider.getServiceTemplateList(name, version);
 
-        ToscaServiceTemplate fullTemplate = filterToscaNodeTemplateInstance(
-            serviceTemplates.getServiceTemplates()).get(0);
+        ToscaServiceTemplate fullTemplate = filterToscaNodeTemplateInstance(serviceTemplateList).get(0);
 
         var template = new HashMap<String, Object>();
         template.put("tosca_definitions_version", fullTemplate.getToscaDefinitionsVersion());
@@ -511,7 +359,7 @@ public class CommissioningProvider {
      */
     private boolean verifyIfInstancePropertiesExists() {
         return clProvider.getNodeTemplates(null, null).stream()
-            .anyMatch(nodeTemplate -> nodeTemplate.getKey().getName().contains(INSTANCE_TEXT));
+                .anyMatch(nodeTemplate -> nodeTemplate.getKey().getName().contains(INSTANCE_TEXT));
 
     }
 }
index fbb2742..d975ec6 100644 (file)
@@ -28,6 +28,7 @@ import java.util.concurrent.TimeUnit;
 import lombok.RequiredArgsConstructor;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.aspectj.lang.annotation.After;
+import org.aspectj.lang.annotation.AfterReturning;
 import org.aspectj.lang.annotation.Aspect;
 import org.aspectj.lang.annotation.Before;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantRegister;
@@ -74,10 +75,21 @@ public class SupervisionAspect implements Closeable {
         executor.execute(() -> supervisionScanner.handleParticipantStatus(participantStatusMessage.getParticipantId()));
     }
 
-    @Before("@annotation(MessageIntercept) && args(participantRegisterMessage,..)")
-    public void handleParticipantRegister(ParticipantRegister participantRegisterMessage) {
-        executor.execute(() -> supervisionScanner.handleParticipantRegister(new ImmutablePair<>(
-                participantRegisterMessage.getParticipantId(), participantRegisterMessage.getParticipantType())));
+    /**
+     * Intercepts participant Register Message
+     * if there is a Commissioning starts an execution of handleParticipantRegister.
+     *
+     * @param participantRegisterMessage the ParticipantRegister message
+     * @param isCommissioning is Commissioning
+     */
+    @AfterReturning(
+            value = "@annotation(MessageIntercept) && args(participantRegisterMessage,..)",
+            returning = "isCommissioning")
+    public void handleParticipantRegister(ParticipantRegister participantRegisterMessage, boolean isCommissioning) {
+        if (isCommissioning) {
+            executor.execute(() -> supervisionScanner.handleParticipantRegister(new ImmutablePair<>(
+                    participantRegisterMessage.getParticipantId(), participantRegisterMessage.getParticipantType())));
+        }
     }
 
     @Before("@annotation(MessageIntercept) && args(participantUpdateAckMessage,..)")
index a031cfa..960cb43 100644 (file)
@@ -21,7 +21,6 @@
 
 package org.onap.policy.clamp.controlloop.runtime.supervision;
 
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -53,7 +52,6 @@ import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantReg
 import org.onap.policy.clamp.controlloop.runtime.supervision.comm.ParticipantUpdatePublisher;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
-import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.stereotype.Component;
@@ -144,15 +142,21 @@ public class SupervisionHandler {
      *
      * @param participantRegisterMessage the ParticipantRegister message received from a participant
      */
-    public void handleParticipantMessage(ParticipantRegister participantRegisterMessage) {
+    @MessageIntercept
+    public boolean handleParticipantMessage(ParticipantRegister participantRegisterMessage) {
         LOGGER.debug("Participant Register received {}", participantRegisterMessage);
         try {
             checkParticipant(participantRegisterMessage, ParticipantState.UNKNOWN, ParticipantHealthStatus.UNKNOWN);
         } catch (PfModelException | ControlLoopException svExc) {
             LOGGER.warn("error saving participant {}", participantRegisterMessage.getParticipantId(), svExc);
         }
+
+        var isCommissioning = participantUpdatePublisher.sendCommissioning(null, null,
+                participantRegisterMessage.getParticipantId(), participantRegisterMessage.getParticipantType());
+
         participantRegisterAckPublisher.send(participantRegisterMessage.getMessageId(),
                 participantRegisterMessage.getParticipantId(), participantRegisterMessage.getParticipantType());
+        return isCommissioning;
     }
 
     /**
@@ -213,10 +217,13 @@ public class SupervisionHandler {
     /**
      * Send commissioning update message to dmaap.
      *
+     * @param name the ToscaServiceTemplate name
+     * @param version the ToscaServiceTemplate version
      */
-    public void handleSendCommissionMessage(Map<String, ToscaNodeType> commonPropertiesMap) {
-        LOGGER.debug("Participant update message being sent {}");
-        participantUpdatePublisher.send(commonPropertiesMap, true);
+    public void handleSendCommissionMessage(String name, String version) {
+        LOGGER.debug("Participant update message with serviveTemplate {} {} being sent to all participants", name,
+                version);
+        participantUpdatePublisher.sendComissioningBroadcast(name, version);
     }
 
     /**
@@ -225,7 +232,7 @@ public class SupervisionHandler {
      */
     public void handleSendDeCommissionMessage() {
         LOGGER.debug("Participant update message being sent");
-        participantUpdatePublisher.send(Collections.emptyMap(), false);
+        participantUpdatePublisher.sendDecomisioning();
     }
 
     /**
index df7efbe..5147aa2 100644 (file)
@@ -160,7 +160,7 @@ public class SupervisionScanner {
 
                 if (participantUpdateCounter.count(id)) {
                     LOGGER.debug("retry message ParticipantUpdate");
-                    participantUpdatePublisher.send(null, true);
+                    participantUpdatePublisher.sendCommissioning(null, null, id.getLeft(), id.getRight());
                 } else {
                     LOGGER.debug("report Participant Update fault");
                     participantUpdateCounter.setFault(id);
index 0f6cc7c..5d879dc 100644 (file)
@@ -30,9 +30,9 @@ import lombok.AllArgsConstructor;
 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.concepts.ParticipantUtils;
+import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ServiceTemplateProvider;
 import org.onap.policy.clamp.controlloop.models.messages.dmaap.participant.ParticipantUpdate;
 import org.onap.policy.models.base.PfModelException;
-import org.onap.policy.models.provider.PolicyModelsProvider;
 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.ToscaNodeType;
@@ -50,49 +50,67 @@ public class ParticipantUpdatePublisher extends AbstractParticipantPublisher<Par
 
     private static final Logger LOGGER = LoggerFactory.getLogger(ParticipantUpdatePublisher.class);
 
-    private final PolicyModelsProvider modelsProvider;
+    private final ServiceTemplateProvider serviceTemplateProvider;
 
     /**
-     * Send ParticipantUpdate to Participant.
+     * Send ParticipantUpdate to all Participants.
      *
+     * @param name the ToscaServiceTemplate name
+     * @param version the ToscaServiceTemplate version
      */
-    public void send(Map<String, ToscaNodeType> commonPropertiesMap, boolean commissionFlag) {
+    public void sendComissioningBroadcast(String name, String version) {
+        sendCommissioning(name, version, null, null);
+    }
+
+    /**
+     * Send ParticipantUpdate to Participant
+     * if participantType and participantId are null then message is broadcast.
+     *
+     * @param name the ToscaServiceTemplate name
+     * @param version the ToscaServiceTemplate version
+     * @param participantType the ParticipantType
+     * @param participantId the ParticipantId
+     */
+    public boolean sendCommissioning(String name, String version, ToscaConceptIdentifier participantType,
+            ToscaConceptIdentifier participantId) {
         var message = new ParticipantUpdate();
+        message.setParticipantType(participantType);
+        message.setParticipantId(participantId);
         message.setTimestamp(Instant.now());
 
         ToscaServiceTemplate toscaServiceTemplate = null;
+        Map<String, ToscaNodeType> commonPropertiesMap = null;
         try {
-            var list = modelsProvider.getServiceTemplateList(null, null);
+            var list = serviceTemplateProvider.getServiceTemplateList(name, version);
             if (!list.isEmpty()) {
                 toscaServiceTemplate = list.get(0);
+                commonPropertiesMap =
+                        serviceTemplateProvider.getCommonOrInstancePropertiesFromNodeTypes(true, toscaServiceTemplate);
+            } else {
+                LOGGER.warn("No tosca service template found, cannot send participantupdate {} {}", name, version);
+                return false;
             }
         } catch (PfModelException pfme) {
             LOGGER.warn("Get of tosca service template failed, cannot send participantupdate", pfme);
-            return;
+            return false;
         }
 
         List<ParticipantDefinition> participantDefinitionUpdates = new ArrayList<>();
-        if (toscaServiceTemplate != null) {
-            for (var toscaInputEntry : toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
-                if (ParticipantUtils.checkIfNodeTemplateIsControlLoopElement(toscaInputEntry.getValue(),
-                        toscaServiceTemplate)) {
-                    var clParticipantType =
-                            ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties());
-                    prepareParticipantDefinitionUpdate(clParticipantType, toscaInputEntry.getKey(),
-                            toscaInputEntry.getValue(), participantDefinitionUpdates, commonPropertiesMap);
-                }
+        for (var toscaInputEntry : toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().entrySet()) {
+            if (ParticipantUtils.checkIfNodeTemplateIsControlLoopElement(toscaInputEntry.getValue(),
+                    toscaServiceTemplate)) {
+                var clParticipantType =
+                        ParticipantUtils.findParticipantType(toscaInputEntry.getValue().getProperties());
+                prepareParticipantDefinitionUpdate(clParticipantType, toscaInputEntry.getKey(),
+                        toscaInputEntry.getValue(), participantDefinitionUpdates, commonPropertiesMap);
             }
         }
 
-        if (commissionFlag) {
-            // Commission the controlloop but sending participantdefinitions to participants
-            message.setParticipantDefinitionUpdates(participantDefinitionUpdates);
-        } else {
-            // DeCommission the controlloop but deleting participantdefinitions on participants
-            message.setParticipantDefinitionUpdates(null);
-        }
+        // Commission the controlloop but sending participantdefinitions to participants
+        message.setParticipantDefinitionUpdates(participantDefinitionUpdates);
         LOGGER.debug("Participant Update sent {}", message);
         super.send(message);
+        return true;
     }
 
     private void prepareParticipantDefinitionUpdate(ToscaConceptIdentifier clParticipantType, String entryKey,
@@ -136,4 +154,17 @@ public class ParticipantUpdatePublisher extends AbstractParticipantPublisher<Par
         participantDefinition.setControlLoopElementDefinitionList(controlLoopElementDefinitionList);
         return participantDefinition;
     }
+
+    /**
+     * Send ParticipantUpdate to Participant after that commissioning has been removed.
+     */
+    public void sendDecomisioning() {
+        var message = new ParticipantUpdate();
+        message.setTimestamp(Instant.now());
+        // DeCommission the controlloop but deleting participantdefinitions on participants
+        message.setParticipantDefinitionUpdates(null);
+
+        LOGGER.debug("Participant Update sent {}", message);
+        super.send(message);
+    }
 }
index b0ea009..3fd74f2 100644 (file)
@@ -35,6 +35,7 @@ import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.Test;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
+import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ServiceTemplateProvider;
 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.util.CommonTestData;
@@ -90,8 +91,8 @@ class CommissioningProviderTest {
         clProvider = new ControlLoopProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
         participantProvider = new ParticipantProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
 
-        CommissioningProvider provider =
-                new CommissioningProvider(modelsProvider, clProvider, null, participantProvider);
+        CommissioningProvider provider = new CommissioningProvider(new ServiceTemplateProvider(modelsProvider),
+                clProvider, null, participantProvider);
         ToscaServiceTemplate serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
 
         List<ToscaNodeTemplate> listOfTemplates = provider.getControlLoopDefinitions(null, null);
@@ -128,8 +129,8 @@ class CommissioningProviderTest {
         clProvider = new ControlLoopProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
         participantProvider = new ParticipantProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
 
-        CommissioningProvider provider =
-                new CommissioningProvider(modelsProvider, clProvider, null, participantProvider);
+        CommissioningProvider provider = new CommissioningProvider(new ServiceTemplateProvider(modelsProvider),
+                clProvider, null, participantProvider);
         // Test Service template is null
         assertThatThrownBy(() -> provider.createControlLoopDefinitions(null)).hasMessageMatching(TEMPLATE_IS_NULL);
         List<ToscaNodeTemplate> listOfTemplates = provider.getControlLoopDefinitions(null, null);
@@ -158,8 +159,8 @@ class CommissioningProviderTest {
         clProvider = new ControlLoopProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
         participantProvider = new ParticipantProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
 
-        CommissioningProvider provider =
-                new CommissioningProvider(modelsProvider, clProvider, null, participantProvider);
+        CommissioningProvider provider = new CommissioningProvider(new ServiceTemplateProvider(modelsProvider),
+                clProvider, null, participantProvider);
         ToscaServiceTemplate serviceTemplate =
                 InstantiationUtils.getToscaServiceTemplate(COMMON_TOSCA_SERVICE_TEMPLATE_YAML);
 
@@ -187,8 +188,8 @@ class CommissioningProviderTest {
         clProvider = new ControlLoopProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
         participantProvider = new ParticipantProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
 
-        CommissioningProvider provider =
-                new CommissioningProvider(modelsProvider, clProvider, null, participantProvider);
+        CommissioningProvider provider = new CommissioningProvider(new ServiceTemplateProvider(modelsProvider),
+                clProvider, null, participantProvider);
         ToscaServiceTemplate serviceTemplate =
                 InstantiationUtils.getToscaServiceTemplate(COMMON_TOSCA_SERVICE_TEMPLATE_YAML);
 
@@ -216,8 +217,8 @@ class CommissioningProviderTest {
         clProvider = new ControlLoopProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
         participantProvider = new ParticipantProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
 
-        CommissioningProvider provider =
-                new CommissioningProvider(modelsProvider, clProvider, null, participantProvider);
+        CommissioningProvider provider = new CommissioningProvider(new ServiceTemplateProvider(modelsProvider),
+                clProvider, null, participantProvider);
         ToscaServiceTemplate serviceTemplate =
                 InstantiationUtils.getToscaServiceTemplate(COMMON_TOSCA_SERVICE_TEMPLATE_YAML);
 
@@ -262,8 +263,8 @@ class CommissioningProviderTest {
         clProvider = new ControlLoopProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
         participantProvider = new ParticipantProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
 
-        CommissioningProvider provider =
-                new CommissioningProvider(modelsProvider, clProvider, null, participantProvider);
+        CommissioningProvider provider = new CommissioningProvider(new ServiceTemplateProvider(modelsProvider),
+                clProvider, null, participantProvider);
         ToscaServiceTemplate serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
 
         List<ToscaNodeTemplate> listOfTemplates = provider.getControlLoopDefinitions(null, null);
@@ -291,8 +292,8 @@ class CommissioningProviderTest {
         clProvider = new ControlLoopProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
         participantProvider = new ParticipantProvider(clRuntimeParameterGroup.getDatabaseProviderParameters());
 
-        CommissioningProvider provider =
-                new CommissioningProvider(modelsProvider, clProvider, null, participantProvider);
+        CommissioningProvider provider = new CommissioningProvider(new ServiceTemplateProvider(modelsProvider),
+                clProvider, null, participantProvider);
         ToscaServiceTemplate serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
 
         provider.getControlLoopDefinitions(null, null);
index abf0cfc..82f7e66 100644 (file)
@@ -40,6 +40,7 @@ import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantProvider;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ParticipantStatisticsProvider;
+import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ServiceTemplateProvider;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
 import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
@@ -122,7 +123,8 @@ class ControlLoopInstantiationProviderTest {
                 new ParticipantStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
         var clElementStatisticsProvider =
                 new ClElementStatisticsProvider(controlLoopParameters.getDatabaseProviderParameters());
-        commissioningProvider = new CommissioningProvider(modelsProvider, clProvider, null, participantProvider);
+        commissioningProvider = new CommissioningProvider(new ServiceTemplateProvider(modelsProvider), clProvider, null,
+                participantProvider);
         var monitoringProvider =
                 new MonitoringProvider(participantStatisticsProvider, clElementStatisticsProvider, clProvider);
         var participantProvider = new ParticipantProvider(controlLoopParameters.getDatabaseProviderParameters());
index 25ce611..0ad8aad 100644 (file)
@@ -23,7 +23,6 @@ package org.onap.policy.clamp.controlloop.runtime.supervision;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyList;
-import static org.mockito.ArgumentMatchers.anyMap;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
@@ -230,9 +229,10 @@ class SupervisionHandlerTest {
                 mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
                 mock(ParticipantDeregisterAckPublisher.class), mock(ControlLoopUpdatePublisher.class),
                 participantUpdatePublisher);
-        handler.handleSendCommissionMessage(Map.of());
+        handler.handleSendCommissionMessage(participantId.getName(), participantId.getVersion());
 
-        verify(participantUpdatePublisher).send(anyMap(), eq(true));
+        verify(participantUpdatePublisher).sendComissioningBroadcast(eq(participantId.getName()),
+                eq(participantId.getVersion()));
     }
 
     @Test
@@ -244,7 +244,7 @@ class SupervisionHandlerTest {
                 participantUpdatePublisher);
         handler.handleSendDeCommissionMessage();
 
-        verify(participantUpdatePublisher).send(anyMap(), eq(false));
+        verify(participantUpdatePublisher).sendDecomisioning();
     }
 
     private SupervisionHandler createSupervisionHandler(ControlLoopProvider controlLoopProvider,