Transfer tosca-poc onto master

This is the third if three commits, this commit makes the content of
the master branch the same as the tosca-poc branch.

This commit adds the "src" files for TOSCA control loops to the modules
in master.

Difference between this commit and the current master:
------------------------------------------------------
diff -qr clamp clamp-master |diff_filter.sh
Only in clamp/common: src
Only in clamp/models: src
Files clamp/participant/participant-impl/participant-impl-dcae/pom.xml and clamp-master/participant/participant-impl/participant-impl-dcae/pom.xml differ
Only in clamp/participant/participant-impl/participant-impl-dcae: src
Only in clamp/participant/participant-impl/participant-impl-policy: src
Only in clamp/participant/participant-impl/participant-impl-simulator: src
Files clamp/participant/participant-impl/pom.xml and clamp-master/participant/participant-impl/pom.xml differ
Only in clamp/participant/participant-intermediary: src
Files clamp/participant/pom.xml and clamp-master/participant/pom.xml differ
Files clamp/pom.xml and clamp-master/pom.xml differ
Files clamp/runtime/pom.xml and clamp-master/runtime/pom.xml differ
Only in clamp: runtime-controlloop

Difference between this commit and the current tosca-poc branch:
----------------------------------------------------------------
diff -qr clamp clamp-tp |diff_filter.sh
Files clamp/INFO.yaml and clamp-tp/INFO.yaml differ
Only in clamp/releases: 6.0.1-container.yaml
Only in clamp/releases: 6.0.1.yaml
Only in clamp/releases: 6.0.2-container.yaml
Only in clamp/releases: 6.0.2.yaml
Only in clamp/releases: 6.1.0-container.yaml
Only in clamp/releases: 6.1.0.yaml
Only in clamp/releases: 6.1.1-container.yaml
Only in clamp/releases: 6.1.1.yaml
Files clamp/runtime/src/main/resources/META-INF/resources/swagger.html and clamp-tp/runtime/src/main/resources/META-INF/resources/swagger.html differ

Issue-ID: POLICY-3215
Change-Id: Ica1aa3fe5d6110df2396ea856703102e800fa770
Signed-off-by: liamfallon <liam.fallon@est.tech>
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProviderTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProviderTest.java
new file mode 100644
index 0000000..956b5e9
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProviderTest.java
@@ -0,0 +1,216 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.commissioning;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.junit.Before;
+import org.junit.Test;
+import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
+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.provider.PolicyModelsProviderParameters;
+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;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+public class CommissioningProviderTest {
+    private static final String TOSCA_SERVICE_TEMPLATE_YAML =
+            "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
+    private static final String TEMPLATE_IS_NULL = ".*serviceTemplate is marked non-null but is null";
+    private static final Coder CODER = new StandardCoder();
+    private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
+    private static int dbNum = 0;
+    private static final Object lockit = new Object();
+    private PolicyModelsProviderParameters databaseProviderParameters;
+
+    private static String getParameterGroupAsString() {
+        dbNum++;
+        return ResourceUtils.getResourceAsString("src/test/resources/parameters/TestParameters.json")
+                .replace("jdbc:h2:mem:testdb", "jdbc:h2:mem:commissioningdb" + dbNum);
+    }
+
+    /**
+     * Sets up db provider parameters before each test.
+     *
+     * @throws CoderException .
+     */
+    @Before
+    public void setupDbProviderParameters() throws CoderException {
+        synchronized (lockit) {
+            databaseProviderParameters = CODER.decode(getParameterGroupAsString(), ClRuntimeParameterGroup.class)
+                    .getDatabaseProviderParameters();
+        }
+    }
+
+    /**
+     * Test the fetching of control loop definitions (ToscaServiceTemplates).
+     *
+     * @throws Exception .
+     */
+    @Test
+    public void testGetControlLoopDefinitions() throws Exception {
+        List<ToscaNodeTemplate> listOfTemplates;
+
+        try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) {
+            ToscaServiceTemplate serviceTemplate = yamlTranslator
+                    .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML),
+                            ToscaServiceTemplate.class);
+
+
+            listOfTemplates = provider.getControlLoopDefinitions(null, null);
+            assertThat(listOfTemplates).isEmpty();
+
+            provider.createControlLoopDefinitions(serviceTemplate);
+            listOfTemplates = provider.getControlLoopDefinitions(null, null);
+            assertThat(listOfTemplates).hasSize(2);
+
+            //Test Filtering
+            listOfTemplates = provider.getControlLoopDefinitions("org.onap.domain.pmsh.PMSHControlLoopDefinition",
+                    "1.2.3");
+            assertThat(listOfTemplates).hasSize(1);
+            for (ToscaNodeTemplate template : listOfTemplates) {
+                //Other CL elements contain PMSD instead of PMSH in their name
+                assertFalse(template.getName().contains("PMSD"));
+            }
+
+            //Test Wrong Name
+            listOfTemplates = provider.getControlLoopDefinitions("WrongControlLoopName", "0.0.0");
+            assertThat(listOfTemplates).isEmpty();
+        }
+    }
+
+    /**
+     * Test the creation of control loop definitions (ToscaServiceTemplates).
+     *
+     * @throws Exception .
+     */
+    @Test
+    public void testCreateControlLoopDefinitions() throws Exception {
+        List<ToscaNodeTemplate> listOfTemplates;
+
+        try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) {
+            //Test Service template is null
+            assertThatThrownBy(() -> provider.createControlLoopDefinitions(null)).hasMessageMatching(TEMPLATE_IS_NULL);
+            listOfTemplates = provider.getControlLoopDefinitions(null, null);
+            assertThat(listOfTemplates).isEmpty();
+
+            ToscaServiceTemplate serviceTemplate = yamlTranslator
+                    .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML),
+                            ToscaServiceTemplate.class);
+
+            // Response should return the number of node templates present in the service template
+            List<ToscaConceptIdentifier> affectedDefinitions =
+                    provider.createControlLoopDefinitions(serviceTemplate).getAffectedControlLoopDefinitions();
+            assertThat(affectedDefinitions).hasSize(13);
+            listOfTemplates = provider.getControlLoopDefinitions(null, null);
+            assertThat(listOfTemplates).hasSize(2);
+        }
+    }
+
+    /**
+     * Test the deletion of control loop definitions (ToscaServiceTemplate).
+     *
+     * @throws Exception .
+     */
+    @Test
+    public void testDeleteControlLoopDefinitions() throws Exception {
+        List<ToscaNodeTemplate> listOfTemplates;
+
+        try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) {
+            ToscaServiceTemplate serviceTemplate = yamlTranslator
+                    .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML),
+                            ToscaServiceTemplate.class);
+
+            listOfTemplates = provider.getControlLoopDefinitions(null, null);
+            assertThat(listOfTemplates).isEmpty();
+
+            provider.createControlLoopDefinitions(serviceTemplate);
+            listOfTemplates = provider.getControlLoopDefinitions(null, null);
+            assertThat(listOfTemplates).hasSize(2);
+
+            provider.deleteControlLoopDefinition(serviceTemplate.getName(), serviceTemplate.getVersion());
+            listOfTemplates = provider.getControlLoopDefinitions(null, null);
+            assertThat(listOfTemplates).isEmpty();
+        }
+    }
+
+    /**
+     * Test the fetching of control loop element definitions.
+     *
+     * @throws Exception .
+     */
+    @Test
+    public void testGetControlLoopElementDefinitions() throws Exception {
+        try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) {
+            ToscaServiceTemplate serviceTemplate = yamlTranslator
+                    .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML),
+                            ToscaServiceTemplate.class);
+
+            provider.getControlLoopDefinitions(null, null);
+
+            provider.createControlLoopDefinitions(serviceTemplate);
+            List<ToscaNodeTemplate> controlLoopDefinitionList = provider.getControlLoopDefinitions(
+                    "org.onap.domain.pmsh.PMSHControlLoopDefinition", "1.2.3");
+
+            List<ToscaNodeTemplate> controlLoopElementNodeTemplates =
+                    provider.getControlLoopElementDefinitions(controlLoopDefinitionList.get(0));
+
+            // 4 PMSH control loop elements definitions.
+            assertThat(controlLoopElementNodeTemplates).hasSize(4);
+
+            List<ToscaNodeType> derivedTypes = getDerivedNodeTypes(serviceTemplate);
+            for (ToscaNodeTemplate template : controlLoopElementNodeTemplates) {
+                assertTrue(checkNodeType(template, derivedTypes));
+            }
+        }
+    }
+
+    private boolean checkNodeType(ToscaNodeTemplate template, List<ToscaNodeType> derivedNodeTypes) {
+        String controlLoopElementType = "org.onap.policy.clamp.controlloop.ControlLoopElement";
+        for (ToscaNodeType derivedType : derivedNodeTypes) {
+            if (template.getType().equals(derivedType.getName()) || template.getType().equals(controlLoopElementType)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private List<ToscaNodeType> getDerivedNodeTypes(ToscaServiceTemplate serviceTemplate) {
+        String type = "org.onap.policy.clamp.controlloop.ControlLoopElement";
+        List<ToscaNodeType> nodeTypes = new ArrayList<>();
+        for (ToscaNodeType nodeType : serviceTemplate.getNodeTypes().values()) {
+            if (nodeType.getDerivedFrom().equals(type)) {
+                nodeTypes.add(nodeType);
+            }
+        }
+        return nodeTypes;
+    }
+}
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningControllerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningControllerTest.java
new file mode 100644
index 0000000..4dbb3ea
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningControllerTest.java
@@ -0,0 +1,202 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.commissioning.rest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse;
+import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController;
+import org.onap.policy.common.utils.coder.YamlJsonTranslator;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+import org.onap.policy.models.provider.PolicyModelsProvider;
+import org.onap.policy.models.provider.PolicyModelsProviderFactory;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+public class CommissioningControllerTest extends CommonRestController {
+
+    private static final String TOSCA_SERVICE_TEMPLATE_YAML =
+            "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
+    private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
+    private static final String COMMISSIONING_ENDPOINT = "commission";
+    private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
+
+    /**
+     * starts Main and inserts a commissioning template.
+     *
+     * @throws Exception if an error occurs
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        CommonRestController.setUpBeforeClass("CommissioningApi");
+
+        serviceTemplate = yamlTranslator.fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML),
+                ToscaServiceTemplate.class);
+    }
+
+    @AfterClass
+    public static void teardownAfterClass() {
+        CommonRestController.teardownAfterClass();
+    }
+
+    @Test
+    public void testSwagger() throws Exception {
+        super.testSwagger(COMMISSIONING_ENDPOINT);
+    }
+
+    @Test
+    public void testUnauthorizedCreate() throws Exception {
+        assertUnauthorizedPost(COMMISSIONING_ENDPOINT, Entity.json(serviceTemplate));
+    }
+
+    @Test
+    public void testUnauthorizedQuery() throws Exception {
+        assertUnauthorizedGet(COMMISSIONING_ENDPOINT);
+    }
+
+    @Test
+    public void testUnauthorizedQueryElements() throws Exception {
+        assertUnauthorizedGet(COMMISSIONING_ENDPOINT + "/elements");
+    }
+
+    @Test
+    public void testUnauthorizedDelete() throws Exception {
+        assertUnauthorizedDelete(COMMISSIONING_ENDPOINT);
+    }
+
+    @Test
+    public void testCreateBadRequest() throws Exception {
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT);
+        Response resp = invocationBuilder.post(Entity.json("NotToscaServiceTempalte"));
+
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+        CommissioningResponse commissioningResponse = resp.readEntity(CommissioningResponse.class);
+        assertNotNull(commissioningResponse.getErrorDetails());
+        assertNull(commissioningResponse.getAffectedControlLoopDefinitions());
+    }
+
+    @Test
+    public void testCreate() throws Exception {
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT);
+        Response resp = invocationBuilder.post(Entity.json(serviceTemplate));
+        assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+        CommissioningResponse commissioningResponse = resp.readEntity(CommissioningResponse.class);
+
+        assertNotNull(commissioningResponse);
+        assertNull(commissioningResponse.getErrorDetails());
+        // Response should return the number of node templates present in the service template
+        assertThat(commissioningResponse.getAffectedControlLoopDefinitions()).hasSize(13);
+        for (String nodeTemplateName : serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().keySet()) {
+            assertTrue(commissioningResponse.getAffectedControlLoopDefinitions().stream()
+                    .anyMatch(ac -> ac.getName().equals(nodeTemplateName)));
+        }
+    }
+
+    @Test
+    public void testQuery_NoResultWithThisName() throws Exception {
+        createEntryInDB();
+
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "?name=noResultWithThisName");
+        Response rawresp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        List entityList = rawresp.readEntity(List.class);
+        assertThat(entityList).isEmpty();
+    }
+
+    @Test
+    public void testQuery() throws Exception {
+        createEntryInDB();
+
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT);
+        Response rawresp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        List entityList = rawresp.readEntity(List.class);
+        assertNotNull(entityList);
+        assertThat(entityList).hasSize(2);
+    }
+
+    @Test
+    public void testQueryElementsBadRequest() throws Exception {
+        createEntryInDB();
+
+        //Call get elements with no info
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "/elements");
+        Response resp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.NOT_ACCEPTABLE.getStatusCode(), resp.getStatus());
+    }
+
+    @Test
+    public void testQueryElements() throws Exception {
+        createEntryInDB();
+
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "/elements"
+                + "?name=org.onap.domain.pmsh.PMSHControlLoopDefinition");
+        Response rawresp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        List entityList = rawresp.readEntity(List.class);
+        assertNotNull(entityList);
+        assertThat(entityList).hasSize(4);
+    }
+
+    @Test
+    public void testDeleteBadRequest() throws Exception {
+        createEntryInDB();
+
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT);
+        //Call delete with no info
+        Response resp = invocationBuilder.delete();
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), resp.getStatus());
+    }
+
+    @Test
+    public void testDelete() throws Exception {
+        createEntryInDB();
+
+        Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "?name="
+                + serviceTemplate.getName() + "&version=" + serviceTemplate.getVersion());
+        //Call delete with no info
+        Response resp = invocationBuilder.delete();
+        assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+        try (PolicyModelsProvider modelsProvider = new PolicyModelsProviderFactory()
+                .createPolicyModelsProvider(CommonRestController.getParameters())) {
+            List<ToscaServiceTemplate> templatesInDB = modelsProvider.getServiceTemplateList(null, null);
+            assertThat(templatesInDB).isEmpty();
+        }
+    }
+
+    private synchronized void createEntryInDB() throws Exception {
+        try (PolicyModelsProvider modelsProvider = new PolicyModelsProviderFactory()
+                .createPolicyModelsProvider(CommonRestController.getParameters())) {
+            modelsProvider.createServiceTemplate(serviceTemplate);
+        }
+    }
+}
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java
new file mode 100644
index 0000000..ccc54b9
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java
@@ -0,0 +1,370 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.instantiation;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
+import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
+import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
+import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningHandler;
+import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler;
+import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
+import org.onap.policy.common.endpoints.event.comm.TopicSink;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.provider.PolicyModelsProviderParameters;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * Class to perform unit test of {@link ControlLoopInstantiationProvider}}.
+ *
+ */
+public class ControlLoopInstantiationProviderTest {
+
+    private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
+    private static final String CL_INSTANTIATION_UPDATE_JSON =
+            "src/test/resources/rest/controlloops/ControlLoopsUpdate.json";
+    private static final String CL_INSTANTIATION_CHANGE_STATE_JSON =
+            "src/test/resources/rest/controlloops/PassiveCommand.json";
+    private static final String CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON =
+            "src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json";
+    private static final String CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON =
+            "src/test/resources/rest/controlloops/ControlLoopsNotFound.json";
+    private static final String TOSCA_TEMPLATE_YAML =
+            "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
+    private static final String CONTROL_LOOP_NOT_FOUND = "Control Loop not found";
+    private static final String DELETE_BAD_REQUEST = "Control Loop State is still %s";
+    private static final String ORDERED_STATE_INVALID = "ordered state invalid or not specified on command";
+    private static final String CONTROLLOOP_ELEMENT_NAME_NOT_FOUND =
+            "\"ControlLoops\" INVALID, item has status INVALID\n"
+            + "  \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
+            + "    \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n"
+            + "  \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
+            + "    \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n";
+
+    private static final String CONTROLLOOP_DEFINITION_NOT_FOUND = "\"ControlLoops\" INVALID, item has status INVALID\n"
+            + "  \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
+            + "    item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
+            + " Commissioned control loop definition not FOUND\n"
+            + "  \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n"
+            + "    item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
+            + " Commissioned control loop definition not FOUND\n";
+
+    private static PolicyModelsProviderParameters databaseProviderParameters;
+    private static SupervisionHandler supervisionHandler;
+    private static CommissioningHandler commissioningHandler;
+
+    /**
+     * setup Db Provider Parameters.
+     *
+     * @throws PfModelException if an error occurs
+     */
+    @BeforeClass
+    public static void setupDbProviderParameters() throws PfModelException {
+        databaseProviderParameters =
+                CommonTestData.geParameterGroup(0, "instantproviderdb").getDatabaseProviderParameters();
+        commissioningHandler = new CommissioningHandler(CommonTestData.geParameterGroup(0, "instantproviderdb"));
+        commissioningHandler.startProviders();
+        supervisionHandler = new SupervisionHandler(CommonTestData.geParameterGroup(0, "instantproviderdb"));
+        supervisionHandler.startProviders();
+        supervisionHandler.startAndRegisterPublishers(Collections.singletonList(Mockito.mock(TopicSink.class)));
+    }
+
+    @Test
+    public void testInstantiationCrud() throws Exception {
+        ControlLoops controlLoopsCreate =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud");
+        ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
+        assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                     new ControlLoopInstantiationProvider(databaseProviderParameters)) {
+
+            // to validate control Loop, it needs to define ToscaServiceTemplate
+            InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters);
+
+            InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
+            InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
+
+            controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
+            assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
+            Assert.assertEquals(controlLoopsCreate, controlLoopsDb);
+
+            for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
+                ControlLoops controlLoopsGet =
+                        instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
+                assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
+                Assert.assertEquals(controlLoop, controlLoopsGet.getControlLoopList().get(0));
+            }
+
+            ControlLoops controlLoopsUpdate =
+                    InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Crud");
+            Assert.assertNotEquals(controlLoopsUpdate, controlLoopsDb);
+
+            instantiationResponse = instantiationProvider.updateControlLoops(controlLoopsUpdate);
+            InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsUpdate);
+
+            controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
+            assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty();
+            Assert.assertEquals(controlLoopsUpdate, controlLoopsDb);
+
+            InstantiationCommand instantiationCommand =
+                    InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Crud");
+            instantiationResponse = instantiationProvider.issueControlLoopCommand(instantiationCommand);
+            InstantiationUtils.assertInstantiationResponse(instantiationResponse, instantiationCommand);
+
+            for (ToscaConceptIdentifier toscaConceptIdentifier : instantiationCommand.getControlLoopIdentifierList()) {
+                ControlLoops controlLoopsGet = instantiationProvider.getControlLoops(toscaConceptIdentifier.getName(),
+                        toscaConceptIdentifier.getVersion());
+                assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
+                Assert.assertEquals(instantiationCommand.getOrderedState(),
+                        controlLoopsGet.getControlLoopList().get(0).getOrderedState());
+            }
+
+            // in order to delete a controlLoop the state must be UNINITIALISED
+            controlLoopsCreate.getControlLoopList().forEach(cl -> cl.setState(ControlLoopState.UNINITIALISED));
+            instantiationProvider.updateControlLoops(controlLoopsCreate);
+
+            for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
+                instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
+            }
+
+            controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
+            assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
+        }
+    }
+
+    private ControlLoops getControlLoopsFromDb(ControlLoops controlLoopsSource) throws Exception {
+        ControlLoops controlLoopsDb = new ControlLoops();
+        controlLoopsDb.setControlLoopList(new ArrayList<>());
+
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                     new ControlLoopInstantiationProvider(databaseProviderParameters)) {
+
+            for (ControlLoop controlLoop : controlLoopsSource.getControlLoopList()) {
+                ControlLoops controlLoopsFromDb =
+                        instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
+                controlLoopsDb.getControlLoopList().addAll(controlLoopsFromDb.getControlLoopList());
+            }
+            return controlLoopsDb;
+        }
+    }
+
+    @Test
+    public void testInstantiationDelete() throws Exception {
+        ControlLoops controlLoops =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Delete");
+        assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
+
+        ControlLoop controlLoop0 = controlLoops.getControlLoopList().get(0);
+
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                     new ControlLoopInstantiationProvider(databaseProviderParameters)) {
+
+            // to validate control Loop, it needs to define ToscaServiceTemplate
+            InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters);
+
+            assertThatThrownBy(
+                    () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion()))
+                    .hasMessageMatching(CONTROL_LOOP_NOT_FOUND);
+
+            InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoops),
+                    controlLoops);
+
+            for (ControlLoopState state : ControlLoopState.values()) {
+                if (!ControlLoopState.UNINITIALISED.equals(state)) {
+                    assertThatDeleteThrownBy(controlLoops, state);
+                }
+            }
+
+            controlLoop0.setState(ControlLoopState.UNINITIALISED);
+            instantiationProvider.updateControlLoops(controlLoops);
+
+            for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
+                instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
+            }
+
+            for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
+                ControlLoops controlLoopsGet =
+                        instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
+                assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
+            }
+        }
+    }
+
+    private void assertThatDeleteThrownBy(ControlLoops controlLoops, ControlLoopState state) throws Exception {
+        ControlLoop controlLoop = controlLoops.getControlLoopList().get(0);
+
+        controlLoop.setState(state);
+
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                     new ControlLoopInstantiationProvider(databaseProviderParameters)) {
+
+            instantiationProvider.updateControlLoops(controlLoops);
+            assertThatThrownBy(
+                    () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()))
+                    .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state));
+        }
+    }
+
+    @Test
+    public void testCreateControlLoops_NoDuplicates() throws Exception {
+        ControlLoops controlLoopsCreate =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "NoDuplicates");
+
+        ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate);
+        assertThat(controlLoopsDb.getControlLoopList()).isEmpty();
+
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                     new ControlLoopInstantiationProvider(databaseProviderParameters)) {
+
+            // to validate control Loop, it needs to define ToscaServiceTemplate
+            InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters);
+
+            InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate);
+            InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate);
+
+            assertThatThrownBy(() -> instantiationProvider.createControlLoops(controlLoopsCreate)).hasMessageMatching(
+                    controlLoopsCreate.getControlLoopList().get(0).getKey().asIdentifier() + " already defined");
+
+            for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
+                instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
+            }
+        }
+    }
+
+    @Test
+    public void testCreateControlLoops_CommissionedClElementNotFound() throws Exception {
+        ControlLoops controlLoops = InstantiationUtils
+                .getControlLoopsFromResource(CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "ClElementNotFound");
+
+        try (ControlLoopInstantiationProvider provider =
+                     new ControlLoopInstantiationProvider(databaseProviderParameters)) {
+
+            // to validate control Loop, it needs to define ToscaServiceTemplate
+            InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters);
+
+            assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
+
+            assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
+                    .hasMessageMatching(CONTROLLOOP_ELEMENT_NAME_NOT_FOUND);
+        }
+    }
+
+    @Test
+    public void testCreateControlLoops_CommissionedClNotFound() throws Exception {
+        ControlLoops controlLoops = InstantiationUtils
+                .getControlLoopsFromResource(CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON, "ClNotFound");
+
+        assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty();
+
+        try (ControlLoopInstantiationProvider provider =
+                     new ControlLoopInstantiationProvider(databaseProviderParameters)) {
+            assertThatThrownBy(() -> provider.createControlLoops(controlLoops))
+                    .hasMessageMatching(CONTROLLOOP_DEFINITION_NOT_FOUND);
+        }
+    }
+
+    @Test
+    public void testIssueControlLoopCommand_OrderedStateInvalid() throws ControlLoopRuntimeException, IOException {
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                     new ControlLoopInstantiationProvider(databaseProviderParameters)) {
+            assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand()))
+                    .hasMessageMatching(ORDERED_STATE_INVALID);
+        }
+    }
+
+    @Test
+    public void testInstantiationVersions() throws Exception {
+
+        // create controlLoops V1
+        ControlLoops controlLoopsV1 =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V1");
+        assertThat(getControlLoopsFromDb(controlLoopsV1).getControlLoopList()).isEmpty();
+
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                     new ControlLoopInstantiationProvider(databaseProviderParameters)) {
+
+            // to validate control Loop, it needs to define ToscaServiceTemplate
+            InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters);
+
+            InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV1),
+                    controlLoopsV1);
+
+            // create controlLoops V2
+            ControlLoops controlLoopsV2 =
+                    InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V2");
+            assertThat(getControlLoopsFromDb(controlLoopsV2).getControlLoopList()).isEmpty();
+            InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV2),
+                    controlLoopsV2);
+
+            // GET controlLoops V2
+            for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
+                ControlLoops controlLoopsGet =
+                        instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
+                assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
+                Assert.assertEquals(controlLoop, controlLoopsGet.getControlLoopList().get(0));
+            }
+
+            // DELETE controlLoops V1
+            for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
+                instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
+            }
+
+            // GET controlLoops V1 is not available
+            for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) {
+                ControlLoops controlLoopsGet =
+                        instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
+                assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
+            }
+
+            // GET controlLoops V2 is still available
+            for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
+                ControlLoops controlLoopsGet =
+                        instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
+                assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
+                Assert.assertEquals(controlLoop, controlLoopsGet.getControlLoopList().get(0));
+            }
+
+            // DELETE controlLoops V2
+            for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
+                instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
+            }
+
+            // GET controlLoops V2 is not available
+            for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) {
+                ControlLoops controlLoopsGet =
+                        instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion());
+                assertThat(controlLoopsGet.getControlLoopList()).isEmpty();
+            }
+        }
+    }
+}
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java
new file mode 100644
index 0000000..958d91d
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java
@@ -0,0 +1,149 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.instantiation;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import org.junit.Assert;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
+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.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;
+import org.onap.policy.models.provider.PolicyModelsProvider;
+import org.onap.policy.models.provider.PolicyModelsProviderFactory;
+import org.onap.policy.models.provider.PolicyModelsProviderParameters;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+/**
+ * Utility methods supporting tests for Instantiation.
+ */
+public class InstantiationUtils {
+
+    private static final Coder CODER = new StandardCoder();
+    private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
+
+    /**
+     * Gets the ControlLoops from Resource.
+     *
+     * @param path path of the resource
+     * @param suffix suffix to add to all names in ControlLoops
+     * @return the ControlLoops from Resource
+     * @throws CoderException if an error occurs
+     */
+    public static ControlLoops getControlLoopsFromResource(final String path, final String suffix)
+            throws CoderException {
+        ControlLoops controlLoops = CODER.decode(new File(path), ControlLoops.class);
+
+        // add suffix to all names
+        controlLoops.getControlLoopList().forEach(controlLoop -> controlLoop.setName(controlLoop.getName() + suffix));
+        return controlLoops;
+    }
+
+    /**
+     * Gets InstantiationCommand from Resource.
+     *
+     * @param path path of the resource
+     * @param suffix suffix to add to all names in ControlLoops
+     * @return the InstantiationCommand
+     * @throws CoderException if an error occurs
+     */
+    public static InstantiationCommand getInstantiationCommandFromResource(final String path, final String suffix)
+            throws CoderException {
+        InstantiationCommand instantiationCommand = CODER.decode(new File(path), InstantiationCommand.class);
+
+        // add suffix to all names
+        instantiationCommand.getControlLoopIdentifierList().forEach(cl -> cl.setName(cl.getName() + suffix));
+        return instantiationCommand;
+    }
+
+    /**
+     * Assert that Instantiation Response contains proper ControlLoops.
+     *
+     * @param response InstantiationResponse
+     * @param controlLoops ControlLoops
+     */
+    public static void assertInstantiationResponse(InstantiationResponse response, ControlLoops controlLoops) {
+        assertNotNull(response);
+        Assert.assertNull(response.getErrorDetails());
+        assertEquals(response.getAffectedControlLoops().size(), controlLoops.getControlLoopList().size());
+        for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
+            assertTrue(response.getAffectedControlLoops().stream()
+                    .filter(ac -> ac.equals(controlLoop.getKey().asIdentifier())).findAny().isPresent());
+        }
+    }
+
+    /**
+     * Assert that Instantiation Response contains proper ControlLoops.
+     *
+     * @param response InstantiationResponse
+     * @param command InstantiationCommand
+     */
+    public static void assertInstantiationResponse(InstantiationResponse response, InstantiationCommand command) {
+        assertNotNull(response);
+        assertEquals(response.getAffectedControlLoops().size(), command.getControlLoopIdentifierList().size());
+        for (ToscaConceptIdentifier toscaConceptIdentifier : command.getControlLoopIdentifierList()) {
+            assertTrue(response.getAffectedControlLoops().stream()
+                    .filter(ac -> ac.compareTo(toscaConceptIdentifier) == 0).findAny().isPresent());
+        }
+    }
+
+    /**
+     * Assert that Instantiation Response contains ControlLoop equals to controlLoop.
+     *
+     * @param response InstantiationResponse
+     * @param controlLoop ControlLoop
+     */
+    public static void assertInstantiationResponse(InstantiationResponse response, ControlLoop controlLoop) {
+        assertNotNull(response);
+        Assert.assertNull(response.getErrorDetails());
+        assertEquals(1, response.getAffectedControlLoops().size());
+        assertEquals(0, response.getAffectedControlLoops().get(0).compareTo(controlLoop.getKey().asIdentifier()));
+    }
+
+    /**
+     * Store ToscaServiceTemplate from resource to DB.
+     *
+     * @param path path of the resource
+     * @param parameters The parameters for the implementation of the PolicyModelProvider
+     * @throws PfModelException if an error occurs
+     */
+    public static void storeToscaServiceTemplate(String path, PolicyModelsProviderParameters parameters)
+            throws PfModelException {
+
+        ToscaServiceTemplate template =
+                yamlTranslator.fromYaml(ResourceUtils.getResourceAsString(path), ToscaServiceTemplate.class);
+
+        try (PolicyModelsProvider modelsProvider =
+                new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters)) {
+            modelsProvider.createServiceTemplate(template);
+        }
+    }
+}
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java
new file mode 100644
index 0000000..71e7624
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java
@@ -0,0 +1,322 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.instantiation.rest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
+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.instantiation.ControlLoopInstantiationProvider;
+import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * Class to perform unit test of {@link InstantiationController}}.
+ *
+ */
+public class InstantiationControllerTest extends CommonRestController {
+
+    private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json";
+
+    private static final String CL_INSTANTIATION_UPDATE_JSON =
+            "src/test/resources/rest/controlloops/ControlLoopsUpdate.json";
+
+    private static final String CL_INSTANTIATION_CHANGE_STATE_JSON =
+            "src/test/resources/rest/controlloops/PassiveCommand.json";
+
+    private static final String TOSCA_TEMPLATE_YAML =
+            "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml";
+
+    private static final String INSTANTIATION_ENDPOINT = "instantiation";
+
+    private static final String INSTANTIATION_COMMAND_ENDPOINT = "instantiation/command";
+
+    /**
+     * starts Main and inserts a commissioning template.
+     *
+     * @throws Exception if an error occurs
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        CommonRestController.setUpBeforeClass("InstApi");
+
+        // to validate control Loop, it needs to define ToscaServiceTemplate
+        InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, getParameters());
+
+        ControlLoops controlLoops =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Command");
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                new ControlLoopInstantiationProvider(getParameters())) {
+            instantiationProvider.createControlLoops(controlLoops);
+        }
+    }
+
+    @AfterClass
+    public static void teardownAfterClass() {
+        CommonRestController.teardownAfterClass();
+    }
+
+    @Test
+    public void testSwagger() throws Exception {
+        super.testSwagger(INSTANTIATION_ENDPOINT);
+    }
+
+    @Test
+    public void testCreate_Unauthorized() throws Exception {
+        ControlLoops controlLoops =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Unauthorized");
+
+        assertUnauthorizedPost(INSTANTIATION_ENDPOINT, Entity.json(controlLoops));
+    }
+
+    @Test
+    public void testQuery_Unauthorized() throws Exception {
+        assertUnauthorizedGet(INSTANTIATION_ENDPOINT);
+    }
+
+    @Test
+    public void testUpdate_Unauthorized() throws Exception {
+        ControlLoops controlLoops =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Unauthorized");
+
+        assertUnauthorizedPut(INSTANTIATION_ENDPOINT, Entity.json(controlLoops));
+    }
+
+    @Test
+    public void testDelete_Unauthorized() throws Exception {
+        assertUnauthorizedDelete(INSTANTIATION_ENDPOINT);
+    }
+
+    @Test
+    public void testCommand_Unauthorized() throws Exception {
+        InstantiationCommand instantiationCommand = InstantiationUtils
+                .getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Unauthorized");
+
+        assertUnauthorizedPut(INSTANTIATION_COMMAND_ENDPOINT, Entity.json(instantiationCommand));
+    }
+
+    @Test
+    public void testCreate() throws Exception {
+        ControlLoops controlLoopsFromRsc =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Create");
+
+        Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT);
+        Response resp = invocationBuilder.post(Entity.json(controlLoopsFromRsc));
+        assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+        InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+        InstantiationUtils.assertInstantiationResponse(instResponse, controlLoopsFromRsc);
+
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                new ControlLoopInstantiationProvider(getParameters())) {
+            for (ControlLoop controlLoopFromRsc : controlLoopsFromRsc.getControlLoopList()) {
+                ControlLoops controlLoopsFromDb = instantiationProvider.getControlLoops(
+                        controlLoopFromRsc.getKey().getName(), controlLoopFromRsc.getKey().getVersion());
+
+                assertNotNull(controlLoopsFromDb);
+                assertThat(controlLoopsFromDb.getControlLoopList()).hasSize(1);
+                assertEquals(controlLoopFromRsc, controlLoopsFromDb.getControlLoopList().get(0));
+            }
+        }
+    }
+
+    @Test
+    public void testCreateBadRequest() throws Exception {
+        ControlLoops controlLoopsFromRsc =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "CreateBadRequest");
+
+        Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT);
+        Response resp = invocationBuilder.post(Entity.json(controlLoopsFromRsc));
+        assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+        // testing Bad Request: CL already defined
+        resp = invocationBuilder.post(Entity.json(controlLoopsFromRsc));
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+        InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+        assertNotNull(instResponse.getErrorDetails());
+        assertNull(instResponse.getAffectedControlLoops());
+    }
+
+    @Test
+    public void testQuery_NoResultWithThisName() throws Exception {
+        Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT + "?name=noResultWithThisName");
+        Response rawresp = invocationBuilder.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+        ControlLoops resp = rawresp.readEntity(ControlLoops.class);
+        assertThat(resp.getControlLoopList()).isEmpty();
+    }
+
+    @Test
+    public void testQuery() throws Exception {
+        // inserts a ControlLoops to DB
+        ControlLoops controlLoops =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Query");
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                new ControlLoopInstantiationProvider(getParameters())) {
+            instantiationProvider.createControlLoops(controlLoops);
+        }
+
+        for (ControlLoop controlLoopFromRsc : controlLoops.getControlLoopList()) {
+            Invocation.Builder invocationBuilder =
+                    super.sendRequest(INSTANTIATION_ENDPOINT + "?name=" + controlLoopFromRsc.getKey().getName());
+            Response rawresp = invocationBuilder.buildGet().invoke();
+            assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+            ControlLoops controlLoopsQuery = rawresp.readEntity(ControlLoops.class);
+            assertNotNull(controlLoopsQuery);
+            assertThat(controlLoopsQuery.getControlLoopList()).hasSize(1);
+            assertEquals(controlLoopFromRsc, controlLoopsQuery.getControlLoopList().get(0));
+        }
+    }
+
+    @Test
+    public void testUpdate() throws Exception {
+        ControlLoops controlLoopsCreate =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Update");
+
+        ControlLoops controlLoops =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Update");
+
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                new ControlLoopInstantiationProvider(getParameters())) {
+            instantiationProvider.createControlLoops(controlLoopsCreate);
+
+            Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT);
+            Response resp = invocationBuilder.put(Entity.json(controlLoops));
+            assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+            InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+            InstantiationUtils.assertInstantiationResponse(instResponse, controlLoops);
+
+            for (ControlLoop controlLoopUpdate : controlLoops.getControlLoopList()) {
+                ControlLoops controlLoopsFromDb = instantiationProvider
+                        .getControlLoops(controlLoopUpdate.getKey().getName(), controlLoopUpdate.getKey().getVersion());
+
+                assertNotNull(controlLoopsFromDb);
+                assertThat(controlLoopsFromDb.getControlLoopList()).hasSize(1);
+                assertEquals(controlLoopUpdate, controlLoopsFromDb.getControlLoopList().get(0));
+            }
+        }
+    }
+
+    @Test
+    public void testDelete_NoResultWithThisName() throws Exception {
+        Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT + "?name=noResultWithThisName");
+        Response resp = invocationBuilder.delete();
+        assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus());
+        InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+        assertNotNull(instResponse.getErrorDetails());
+        assertNull(instResponse.getAffectedControlLoops());
+    }
+
+    @Test
+    public void testDelete() throws Exception {
+        ControlLoops controlLoopsFromRsc =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Delete");
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                new ControlLoopInstantiationProvider(getParameters())) {
+            instantiationProvider.createControlLoops(controlLoopsFromRsc);
+
+            for (ControlLoop controlLoopFromRsc : controlLoopsFromRsc.getControlLoopList()) {
+                Invocation.Builder invocationBuilder =
+                        super.sendRequest(INSTANTIATION_ENDPOINT + "?name=" + controlLoopFromRsc.getKey().getName()
+                                + "&version=" + controlLoopFromRsc.getKey().getVersion());
+                Response resp = invocationBuilder.delete();
+                assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+                InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+                InstantiationUtils.assertInstantiationResponse(instResponse, controlLoopFromRsc);
+
+                ControlLoops controlLoopsFromDb = instantiationProvider.getControlLoops(
+                        controlLoopFromRsc.getKey().getName(), controlLoopFromRsc.getKey().getVersion());
+                assertThat(controlLoopsFromDb.getControlLoopList()).isEmpty();
+            }
+        }
+    }
+
+    @Test
+    public void testDeleteBadRequest() throws Exception {
+        ControlLoops controlLoopsFromRsc =
+                InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "DelBadRequest");
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                new ControlLoopInstantiationProvider(getParameters())) {
+            instantiationProvider.createControlLoops(controlLoopsFromRsc);
+
+            for (ControlLoop controlLoopFromRsc : controlLoopsFromRsc.getControlLoopList()) {
+                Invocation.Builder invocationBuilder =
+                        super.sendRequest(INSTANTIATION_ENDPOINT + "?name=" + controlLoopFromRsc.getKey().getName());
+                Response resp = invocationBuilder.delete();
+                // should be BAD_REQUEST
+                assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), resp.getStatus());
+            }
+        }
+    }
+
+    @Test
+    public void testCommand_NotFound1() throws Exception {
+        Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_COMMAND_ENDPOINT);
+        Response resp = invocationBuilder.put(Entity.json(new InstantiationCommand()));
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+    }
+
+    @Test
+    public void testCommand_NotFound2() throws Exception {
+        InstantiationCommand command =
+                InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Command");
+        command.setOrderedState(null);
+
+        Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_COMMAND_ENDPOINT);
+        Response resp = invocationBuilder.put(Entity.json(command));
+        assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+    }
+
+    @Test
+    public void testCommand() throws Exception {
+        InstantiationCommand command =
+                InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Command");
+
+        Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_COMMAND_ENDPOINT);
+        Response resp = invocationBuilder.put(Entity.json(command));
+        assertEquals(Response.Status.ACCEPTED.getStatusCode(), resp.getStatus());
+        InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+        InstantiationUtils.assertInstantiationResponse(instResponse, command);
+
+        // check passive state on DB
+        try (ControlLoopInstantiationProvider instantiationProvider =
+                new ControlLoopInstantiationProvider(getParameters())) {
+            for (ToscaConceptIdentifier toscaConceptIdentifier : command.getControlLoopIdentifierList()) {
+                ControlLoops controlLoopsGet = instantiationProvider.getControlLoops(toscaConceptIdentifier.getName(),
+                        toscaConceptIdentifier.getVersion());
+                assertThat(controlLoopsGet.getControlLoopList()).hasSize(1);
+                assertEquals(command.getOrderedState(), controlLoopsGet.getControlLoopList().get(0).getOrderedState());
+            }
+        }
+    }
+}
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestControllerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestControllerTest.java
new file mode 100644
index 0000000..4f68b4f
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestControllerTest.java
@@ -0,0 +1,71 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.main.rest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.util.UUID;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.junit.Test;
+
+/**
+ * Class to perform unit test of {@link RestController}}.
+ *
+ */
+public class RestControllerTest {
+
+    @Test
+    public void testProduces() {
+        Produces annotation = RestController.class.getAnnotation(Produces.class);
+        assertNotNull(annotation);
+        assertThat(annotation.value()).contains(MediaType.APPLICATION_JSON)
+                        .contains(RestController.APPLICATION_YAML);
+    }
+
+    @Test
+    public void testAddVersionControlHeaders() {
+        RestController ctlr = new RestController();
+        Response resp = ctlr.addVersionControlHeaders(Response.status(Response.Status.OK)).build();
+        assertEquals("0", resp.getHeaderString(RestController.VERSION_MINOR_NAME));
+        assertEquals("0", resp.getHeaderString(RestController.VERSION_PATCH_NAME));
+        assertEquals("1.0.0", resp.getHeaderString(RestController.VERSION_LATEST_NAME));
+    }
+
+    @Test
+    public void testAddLoggingHeaders_Null() {
+        RestController ctlr = new RestController();
+        Response resp = ctlr.addLoggingHeaders(Response.status(Response.Status.OK), null).build();
+        assertNotNull(resp.getHeaderString(RestController.REQUEST_ID_NAME));
+    }
+
+    @Test
+    public void testAddLoggingHeaders_NonNull() {
+        UUID uuid = UUID.randomUUID();
+        RestController ctlr = new RestController();
+        Response resp = ctlr.addLoggingHeaders(Response.status(Response.Status.OK), uuid).build();
+        assertEquals(uuid.toString(), resp.getHeaderString(RestController.REQUEST_ID_NAME));
+    }
+
+}
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivatorTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivatorTest.java
new file mode 100644
index 0000000..da71c23
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivatorTest.java
@@ -0,0 +1,82 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.main.startstop;
+
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
+import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
+import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterHandler;
+import org.onap.policy.common.utils.services.Registry;
+
+/**
+ * Class to perform unit test of {@link ClRuntimeActivator}}.
+ *
+ */
+public class ClRuntimeActivatorTest {
+
+    @Test
+    public void testStartAndStop() throws Exception {
+        Registry.newRegistry();
+        final String[] configParameters = {"-c", "src/test/resources/parameters/TestParameters.json"};
+        final ClRuntimeCommandLineArguments arguments = new ClRuntimeCommandLineArguments();
+        arguments.parse(configParameters);
+        ClRuntimeParameterGroup parameterGroup = new ClRuntimeParameterHandler().getParameters(arguments);
+        ClRuntimeActivator activator = new ClRuntimeActivator(parameterGroup);
+        activator.isAlive();
+
+        assertFalse(activator.isAlive());
+        activator.start();
+        assertTrue(activator.isAlive());
+        assertTrue(activator.getParameterGroup().isValid());
+        assertEquals(activator.getParameterGroup().getName(),
+                activator.getParameterGroup().getRestServerParameters().getName());
+
+        // repeat start - should throw an exception
+        assertThatIllegalStateException().isThrownBy(() -> activator.start());
+        assertTrue(activator.isAlive());
+        assertTrue(activator.getParameterGroup().isValid());
+
+        activator.stop();
+        assertFalse(activator.isAlive());
+
+        // repeat stop - should throw an exception
+        assertThatIllegalStateException().isThrownBy(() -> activator.stop());
+        assertFalse(activator.isAlive());
+    }
+
+    @Test
+    public void testNull() {
+        assertThatExceptionOfType(ControlLoopRuntimeException.class).isThrownBy(() -> new ClRuntimeActivator(null));
+    }
+
+    @Test
+    public void testNotValid() {
+        ClRuntimeParameterGroup parameterGroup = new ClRuntimeParameterGroup("name");
+        assertThatExceptionOfType(ControlLoopRuntimeException.class)
+                .isThrownBy(() -> new ClRuntimeActivator(parameterGroup));
+    }
+}
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/MainTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/MainTest.java
new file mode 100644
index 0000000..b06383c
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/MainTest.java
@@ -0,0 +1,157 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.main.startstop;
+
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onap.policy.clamp.controlloop.common.ControlLoopConstants;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException;
+import org.onap.policy.common.utils.resources.MessageConstants;
+import org.onap.policy.common.utils.services.Registry;
+
+/**
+ * Class to perform unit test of {@link Main}}.
+ *
+ */
+public class MainTest {
+
+    public static final String POLICY_CLAMP_FAILURE_MSG =
+            String.format(MessageConstants.START_FAILURE_MSG, MessageConstants.POLICY_CLAMP);
+
+    /**
+     * Set up.
+     */
+    @BeforeClass
+    public static void setUp() {
+        Registry.newRegistry();
+    }
+
+    /**
+     * Shuts "main" down.
+     *
+     * @throws Exception if an error occurs
+     */
+    @AfterClass
+    public static void tearDown() throws Exception {
+        // shut down activator
+        final ClRuntimeActivator activator =
+                Registry.getOrDefault(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR, ClRuntimeActivator.class, null);
+        if (activator != null && activator.isAlive()) {
+            activator.shutdown();
+        }
+    }
+
+    @Test
+    public void testMain_Help() {
+        final String[] configParameters = {"-h"};
+        Main main = new Main(configParameters);
+        assertFalse(main.isRunning());
+    }
+
+    @Test
+    public void testMain_Version() {
+        final String[] configParameters = {"-v"};
+        Main main = new Main(configParameters);
+        assertFalse(main.isRunning());
+    }
+
+    @Test
+    public void testMain_Valid() {
+        final String[] configParameters = {"-c", "src/test/resources/parameters/TestParameters.json"};
+        Main main = new Main(configParameters);
+        assertTrue(main.isRunning());
+
+        // ensure items were added to the registry
+        assertNotNull(Registry.get(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR, ClRuntimeActivator.class));
+
+        assertThatCode(() -> main.shutdown()).doesNotThrowAnyException();
+
+        assertFalse(main.isRunning());
+    }
+
+    @Test
+    public void testMain_NoParameter() {
+        assertThatConfigParameterThrownException(new String[] {});
+    }
+
+    @Test
+    public void testMain_FilePathNotDefined() {
+        assertThatConfigParameterThrownException(new String[] {"-c"});
+    }
+
+    @Test
+    public void testMain_TooManyCommand() {
+        assertThatConfigParameterThrownException(new String[] {"-h", "d"});
+    }
+
+    @Test
+    public void testMain_WrongParameter() {
+        assertThatConfigParameterThrownException(new String[] {"-d"});
+    }
+
+    private void assertThatConfigParameterThrownException(final String[] configParameters) {
+        assertThatThrownBy(() -> Main.main(configParameters)).isInstanceOf(ControlLoopRuntimeException.class)
+                .hasMessage(POLICY_CLAMP_FAILURE_MSG);
+    }
+
+    @Test
+    public void testParticipant_NoFileWithThisName() {
+        assertThatConfigFileThrownException("src/test/resources/parameters/NoFileWithThisName.json");
+    }
+
+    @Test
+    public void testParticipant_NotValidFile() {
+        assertThatConfigFileThrownException("src/test/resources/parameters");
+    }
+
+    @Test
+    public void testParticipant_FileEmpty() {
+        assertThatConfigFileThrownException("src/test/resources/parameters/EmptyParameters.json");
+    }
+
+    @Test
+    public void testParticipant_NoParameters() {
+        assertThatConfigFileThrownException("src/test/resources/parameters/NoParameters.json");
+    }
+
+    @Test
+    public void testParticipant_InvalidParameters() {
+        assertThatConfigFileThrownException("src/test/resources/parameters/InvalidParameters.json");
+    }
+
+    @Test
+    public void testParticipant_WrongJsonFormat() {
+        assertThatConfigFileThrownException("src/test/resources/parameters/Unreadable.json");
+    }
+
+    private void assertThatConfigFileThrownException(final String configFilePath) {
+        final String[] configParameters = new String[] {"-c", configFilePath};
+        assertThatThrownBy(() -> new Main(configParameters)).isInstanceOf(ControlLoopRuntimeException.class)
+                .hasMessage(String.format(POLICY_CLAMP_FAILURE_MSG));
+    }
+}
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/TestMonitoringProvider.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/TestMonitoringProvider.java
new file mode 100644
index 0000000..44096ee
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/TestMonitoringProvider.java
@@ -0,0 +1,264 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.monitoring;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatisticsList;
+import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
+import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
+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.provider.PolicyModelsProviderParameters;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+
+public class TestMonitoringProvider {
+
+    private static final String CL_PARTICIPANT_STATISTICS_JSON =
+        "src/test/resources/rest/monitoring/TestParticipantStatistics.json";
+    private static final String INVALID_PARTICIPANT_JSON_INPUT =
+        "src/test/resources/rest/monitoring/TestParticipantStatistics_Invalid.json";
+    private static final String CL_ELEMENT_STATISTICS_JSON =
+        "src/test/resources/rest/monitoring/TestClElementStatistics.json";
+    private static final String INVALID_CL_ELEMENT_JSON_INPUT =
+        "src/test/resources/rest/monitoring/TestClElementStatistics_Invalid.json";
+    private static final Coder CODER = new StandardCoder();
+
+    private static final String CL_PROVIDER_FIELD = "controlLoopProvider";
+
+    private static final String LIST_IS_NULL = ".*StatisticsList is marked .*ull but is null";
+    private static ParticipantStatisticsList inputParticipantStatistics;
+    private static ParticipantStatisticsList invalidParticipantInput;
+    private static ClElementStatisticsList inputClElementStatistics;
+    private static ClElementStatisticsList invalidClElementInput;
+
+
+
+    @BeforeClass
+    public static void beforeSetupStatistics() throws CoderException {
+        // Reading input json for statistics data
+        inputParticipantStatistics =
+            CODER.decode(new File(CL_PARTICIPANT_STATISTICS_JSON), ParticipantStatisticsList.class);
+        invalidParticipantInput =
+            CODER.decode(new File(INVALID_PARTICIPANT_JSON_INPUT), ParticipantStatisticsList.class);
+        inputClElementStatistics = CODER.decode(new File(CL_ELEMENT_STATISTICS_JSON), ClElementStatisticsList.class);
+        invalidClElementInput = CODER.decode(new File(INVALID_CL_ELEMENT_JSON_INPUT), ClElementStatisticsList.class);
+    }
+
+
+    @Test
+    public void testCreateParticipantStatistics() throws Exception {
+        PolicyModelsProviderParameters parameters =
+            CommonTestData.geParameterGroup(0, "createparStat").getDatabaseProviderParameters();
+
+        try (MonitoringProvider provider = new MonitoringProvider(parameters)) {
+            // Creating statistics data in db with null input
+            assertThatThrownBy(() -> {
+                provider.createParticipantStatistics(null);
+            }).hasMessageMatching(LIST_IS_NULL);
+
+            assertThatThrownBy(() -> {
+                provider.createParticipantStatistics(invalidParticipantInput.getStatisticsList());
+            }).hasMessageMatching("participantStatisticsList is marked .*null but is null");
+
+            // Creating statistics data from input json
+            ParticipantStatisticsList createResponse =
+                provider.createParticipantStatistics(inputParticipantStatistics.getStatisticsList());
+
+            assertThat(createResponse.getStatisticsList()).hasSize(3);
+            assertEquals(createResponse.getStatisticsList().toString().replaceAll("\\s+", ""),
+                inputParticipantStatistics.getStatisticsList().toString().replaceAll("\\s+", ""));
+        }
+    }
+
+    @Test
+    public void testGetParticipantStatistics() throws Exception {
+        PolicyModelsProviderParameters parameters =
+            CommonTestData.geParameterGroup(0, "getparStat").getDatabaseProviderParameters();
+        try (MonitoringProvider provider = new MonitoringProvider(parameters)) {
+            ParticipantStatisticsList getResponse;
+
+            provider.createParticipantStatistics(inputParticipantStatistics.getStatisticsList());
+
+            assertThatThrownBy(() -> {
+                provider.fetchFilteredParticipantStatistics(null, null, 0, null, null);
+            }).hasMessageMatching("name is marked .*null but is null");
+
+            // Fetch specific statistics record with name, version and record count
+            getResponse = provider.fetchFilteredParticipantStatistics("name2", "1.001", 1,
+                null, null);
+            assertThat(getResponse.getStatisticsList()).hasSize(1);
+            assertEquals(getResponse.getStatisticsList().get(0).toString().replaceAll("\\s+", ""),
+                inputParticipantStatistics.getStatisticsList().get(2).toString().replaceAll("\\s+", ""));
+
+            // Fetch statistics using timestamp
+            getResponse = provider.fetchFilteredParticipantStatistics("name1", "1.001", 0,
+                null, Instant.parse("2021-01-10T15:00:00.000Z"));
+            assertThat(getResponse.getStatisticsList()).hasSize(1);
+
+            getResponse = provider.fetchFilteredParticipantStatistics("name1", "1.001", 0,
+                Instant.parse("2021-01-11T12:00:00.000Z"), Instant.parse("2021-01-11T16:00:00.000Z"));
+
+            assertThat(getResponse.getStatisticsList()).isEmpty();
+        }
+    }
+
+    @Test
+    public void testCreateClElementStatistics() throws Exception {
+        PolicyModelsProviderParameters parameters =
+            CommonTestData.geParameterGroup(0, "createelemstat").getDatabaseProviderParameters();
+        try (MonitoringProvider provider = new MonitoringProvider(parameters)) {
+            // Creating statistics data in db with null input
+            assertThatThrownBy(() -> {
+                provider.createClElementStatistics(null);
+            }).hasMessageMatching(LIST_IS_NULL);
+
+            assertThatThrownBy(() -> {
+                provider.createClElementStatistics(invalidClElementInput.getClElementStatistics());
+            }).hasMessageMatching("clElementStatisticsList is marked .*null but is null");
+
+            // Creating clElement statistics data from input json
+            ClElementStatisticsList createResponse =
+                provider.createClElementStatistics(inputClElementStatistics.getClElementStatistics());
+
+            assertThat(createResponse.getClElementStatistics()).hasSize(4);
+            assertEquals(createResponse.getClElementStatistics().toString().replaceAll("\\s+", ""),
+                inputClElementStatistics.getClElementStatistics().toString().replaceAll("\\s+", ""));
+        }
+    }
+
+    @Test
+    public void testGetClElementStatistics() throws Exception {
+        PolicyModelsProviderParameters parameters =
+            CommonTestData.geParameterGroup(0, "getelemstat").getDatabaseProviderParameters();
+        try (MonitoringProvider provider = new MonitoringProvider(parameters)) {
+            ClElementStatisticsList getResponse;
+
+            assertThatThrownBy(() -> {
+                provider.fetchFilteredClElementStatistics(null, null, null,  null,
+                    null, 0);
+            }).hasMessageMatching("name is marked .*null but is null");
+
+            ClElementStatisticsList lists = provider.createClElementStatistics(inputClElementStatistics
+                .getClElementStatistics());
+
+            getResponse = provider.fetchFilteredClElementStatistics("name1", null, null, null,
+                null, 0);
+
+            assertThat(getResponse.getClElementStatistics()).hasSize(2);
+            assertEquals(getResponse.getClElementStatistics().get(0).toString().replaceAll("\\s+", ""),
+                inputClElementStatistics.getClElementStatistics().get(0).toString().replaceAll("\\s+", ""));
+
+            // Fetch specific statistics record with name, id and record count
+            getResponse = provider.fetchFilteredClElementStatistics("name1", "1.001",
+                "709c62b3-8918-41b9-a747-d21eb79c6c20", null, null, 0);
+            assertThat(getResponse.getClElementStatistics()).hasSize(2);
+
+            // Fetch statistics using timestamp
+            getResponse = provider.fetchFilteredClElementStatistics("name1", "1.001", null,
+                Instant.parse("2021-01-10T13:45:00.000Z"), null, 0);
+            assertThat(getResponse.getClElementStatistics()).hasSize(2);
+        }
+    }
+
+    @Test
+    public void testGetParticipantStatsPerCL() throws Exception {
+        PolicyModelsProviderParameters parameters =
+            CommonTestData.geParameterGroup(0, "getparStatCL").getDatabaseProviderParameters();
+        try (MonitoringProvider provider = Mockito.spy(new MonitoringProvider(parameters))) {
+
+            provider.createParticipantStatistics(inputParticipantStatistics.getStatisticsList());
+            //Mock the response for fetching participant conceptIdentifiers per control loop
+            List<ToscaConceptIdentifier> conceptIdentifiers = new ArrayList<>();
+            conceptIdentifiers.add(new ToscaConceptIdentifier("name1", "1.001"));
+            when(provider.getAllParticipantIdsPerControlLoop("testName", "1.001"))
+                .thenReturn(conceptIdentifiers);
+            ParticipantStatisticsList getResponse;
+            getResponse = provider.fetchParticipantStatsPerControlLoop("testName", "1.001");
+            assertThat(getResponse.getStatisticsList()).hasSize(2);
+            assertEquals(getResponse.getStatisticsList().get(0).toString().replaceAll("\\s+", ""),
+                inputParticipantStatistics.getStatisticsList().get(0).toString().replaceAll("\\s+", ""));
+            assertThat(provider.fetchParticipantStatsPerControlLoop("invalidCLName", "1.002")
+                .getStatisticsList()).isEmpty();
+        }
+
+    }
+
+    @Test
+    public void testClElementStatsPerCL() throws Exception {
+        PolicyModelsProviderParameters parameters =
+            CommonTestData.geParameterGroup(0, "getelemstatPerCL").getDatabaseProviderParameters();
+        //Setup a dummy Control loop data
+        ControlLoopElement mockClElement = new ControlLoopElement();
+        mockClElement.setId(inputClElementStatistics.getClElementStatistics().get(0).getId());
+        mockClElement.setParticipantId(new ToscaConceptIdentifier(inputClElementStatistics.getClElementStatistics()
+            .get(0).getParticipantId().getName(), inputClElementStatistics.getClElementStatistics().get(0)
+            .getParticipantId().getVersion()));
+        ControlLoop mockCL = new ControlLoop();
+        mockCL.setElements(new LinkedHashMap<>());
+        mockCL.getElements().put(mockClElement.getId(), mockClElement);
+
+        //Mock controlloop data to be returned for the given CL Id
+        ControlLoopProvider mockClProvider = Mockito.mock(ControlLoopProvider.class);
+        when(mockClProvider.getControlLoop(new ToscaConceptIdentifier("testCLName", "1.001")))
+            .thenReturn(mockCL);
+
+        try (MonitoringProvider monitoringProvider = new MonitoringProvider(parameters)) {
+            monitoringProvider.createClElementStatistics(inputClElementStatistics.getClElementStatistics());
+            Field controlLoopProviderField = monitoringProvider.getClass().getDeclaredField(CL_PROVIDER_FIELD);
+            controlLoopProviderField.setAccessible(true);
+            controlLoopProviderField.set(monitoringProvider, mockClProvider);
+
+            ClElementStatisticsList getResponse;
+            getResponse = monitoringProvider.fetchClElementStatsPerControlLoop("testCLName", "1.001");
+
+            assertThat(getResponse.getClElementStatistics()).hasSize(2);
+            assertEquals(getResponse.getClElementStatistics().get(1).toString().replaceAll("\\s+", ""),
+                inputClElementStatistics.getClElementStatistics().get(1).toString().replaceAll("\\s+", ""));
+
+            assertThat(monitoringProvider.fetchClElementStatsPerControlLoop("invalidCLName", "1.002")
+                .getClElementStatistics()).isEmpty();
+
+            Map<String, ToscaConceptIdentifier> clElementIds = monitoringProvider
+                .getAllClElementsIdPerControlLoop("testCLName", "1.001");
+            assertThat(clElementIds).containsKey(inputClElementStatistics.getClElementStatistics().get(0).getId()
+                .toString());
+        }
+    }
+}
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryControllerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryControllerTest.java
new file mode 100644
index 0000000..118199a
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryControllerTest.java
@@ -0,0 +1,237 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.monitoring.rest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.File;
+import java.time.Instant;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList;
+import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatisticsList;
+import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider;
+import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.StandardCoder;
+
+public class MonitoringQueryControllerTest extends CommonRestController {
+
+    private static final String CL_PARTICIPANT_STATISTICS_JSON =
+        "src/test/resources/rest/monitoring/TestParticipantStatistics.json";
+    private static final String CL_ELEMENT_STATISTICS_JSON =
+        "src/test/resources/rest/monitoring/TestClElementStatistics.json";
+
+    private static final Coder CODER = new StandardCoder();
+
+    private static ParticipantStatisticsList inputParticipantStatistics;
+    private static ClElementStatisticsList inputClElementStatistics;
+
+    private static ParticipantStatisticsList participantStatisticsList;
+    private static  ClElementStatisticsList clElementStatisticsList;
+
+    private static final String CLELEMENT_STATS_ENDPOINT = "monitoring/clelement";
+    private static final String PARTICIPANT_STATS_ENDPOINT = "monitoring/participant";
+    private static final String PARTICIPANT_STATS_PER_CL_ENDPOINT = "monitoring/participants/controlloop";
+    private static final String CLELEMENT_STATS_PER_CL_ENDPOINT = "monitoring/clelements/controlloop";
+
+
+    /**
+     * starts Main.
+     *
+     * @throws Exception if an error occurs
+     */
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        CommonRestController.setUpBeforeClass("testStatisticsQuery");
+        inputParticipantStatistics = CODER.decode(new File(CL_PARTICIPANT_STATISTICS_JSON),
+            ParticipantStatisticsList.class);
+        inputClElementStatistics = CODER.decode(new File(CL_ELEMENT_STATISTICS_JSON),
+            ClElementStatisticsList.class);
+
+        try (MonitoringProvider monitoringProvider = new MonitoringProvider(getParameters())) {
+            // Insert Participant statistics to DB
+            participantStatisticsList = monitoringProvider.createParticipantStatistics(inputParticipantStatistics
+                .getStatisticsList());
+            // Insert CL Element statistics to DB
+            clElementStatisticsList = monitoringProvider.createClElementStatistics(inputClElementStatistics
+                .getClElementStatistics());
+        }
+    }
+
+    @AfterClass
+    public static void teardownAfterClass() {
+        CommonRestController.teardownAfterClass();
+    }
+
+    @Test
+    public void testQuery_Unauthorized_for_ClElementStats() throws Exception {
+        assertUnauthorizedGet(CLELEMENT_STATS_ENDPOINT);
+    }
+
+    @Test
+    public void testQuery_Unauthorized_for_ClParticipantStats() throws Exception {
+        assertUnauthorizedGet(PARTICIPANT_STATS_ENDPOINT);
+    }
+
+    @Test
+    public void testQuery_Unauthorized_for_ParticipantStatsPerCl() throws Exception {
+        assertUnauthorizedGet(PARTICIPANT_STATS_PER_CL_ENDPOINT);
+    }
+
+    @Test
+    public void testQuery_Unauthorized_for_ClElementStatsPerCl() throws Exception {
+        assertUnauthorizedGet(CLELEMENT_STATS_PER_CL_ENDPOINT);
+    }
+
+    @Test
+    public void testSwagger_ClStats() throws Exception {
+        super.testSwagger(CLELEMENT_STATS_ENDPOINT);
+        super.testSwagger(PARTICIPANT_STATS_ENDPOINT);
+        super.testSwagger(CLELEMENT_STATS_PER_CL_ENDPOINT);
+        super.testSwagger(PARTICIPANT_STATS_PER_CL_ENDPOINT);
+    }
+
+    @Test
+    public void testClElementStatisticsEndpoint() throws Exception {
+        // Filter statistics only based on participant Id and UUID
+        Invocation.Builder invokeRequest1 =
+            super.sendRequest(CLELEMENT_STATS_ENDPOINT + "?name=" + clElementStatisticsList
+                .getClElementStatistics().get(0).getParticipantId().getName() + "&version=" + clElementStatisticsList
+                .getClElementStatistics().get(0).getParticipantId().getVersion() + "&id=" + clElementStatisticsList
+                .getClElementStatistics().get(0).getId().toString());
+        Response response1 = invokeRequest1.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus());
+
+        ClElementStatisticsList result1 = response1.readEntity(ClElementStatisticsList.class);
+
+        assertNotNull(result1);
+        assertThat(result1.getClElementStatistics()).hasSize(2);
+        assertEquals(result1.getClElementStatistics().get(0), clElementStatisticsList
+            .getClElementStatistics().get(0));
+
+        // Filter statistics based on timestamp
+        Invocation.Builder invokeRequest2 =
+            super.sendRequest(CLELEMENT_STATS_ENDPOINT + "?name=" + clElementStatisticsList
+                .getClElementStatistics().get(1).getParticipantId().getName() + "&version=" + clElementStatisticsList
+                .getClElementStatistics().get(1).getParticipantId().getVersion() + "&startTime="
+                + Instant.parse("2021-01-10T13:00:00.000Z") + "&endTime=" + Instant.parse("2021-01-10T14:00:00.000Z"));
+        Response response2 = invokeRequest2.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), response2.getStatus());
+        ClElementStatisticsList result2 = response2.readEntity(ClElementStatisticsList.class);
+
+        assertNotNull(result2);
+        assertThat(result2.getClElementStatistics()).hasSize(1);
+        assertEquals(result1.getClElementStatistics().get(0), clElementStatisticsList
+            .getClElementStatistics().get(0));
+    }
+
+    @Test
+    public void testClElementStats_BadRequest() throws Exception {
+        Invocation.Builder invokeRequest1 =
+            super.sendRequest(CLELEMENT_STATS_ENDPOINT + "?version=1.0.0");
+        Response response1 = invokeRequest1.buildGet().invoke();
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus());
+    }
+
+    @Test
+    public void testParticipantStatisticsEndpoint() throws Exception {
+
+        // Filter statistics only based on participant Id
+        Invocation.Builder invokeRequest1 =
+            super.sendRequest(PARTICIPANT_STATS_ENDPOINT + "?name=" + participantStatisticsList
+                .getStatisticsList().get(0).getParticipantId().getName() + "&version=" + participantStatisticsList
+                .getStatisticsList().get(0).getParticipantId().getVersion());
+        Response response1 = invokeRequest1.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus());
+        ParticipantStatisticsList result1 = response1.readEntity(ParticipantStatisticsList.class);
+
+        assertNotNull(result1);
+        assertThat(result1.getStatisticsList()).hasSize(2);
+        assertEquals(result1.getStatisticsList().get(0), participantStatisticsList
+            .getStatisticsList().get(0));
+
+        // Filter statistics based on timestamp
+        Invocation.Builder invokeRequest2 =
+            super.sendRequest(PARTICIPANT_STATS_ENDPOINT + "?name=" + participantStatisticsList
+                .getStatisticsList().get(1).getParticipantId().getName() + "&version=" + participantStatisticsList
+                .getStatisticsList().get(1).getParticipantId().getVersion() + "&startTime="
+                + Instant.parse("2021-01-10T13:00:00.000Z") + "&endTime=" + Instant.parse("2021-01-10T14:00:00.000Z"));
+        Response response2 = invokeRequest2.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), response2.getStatus());
+        ParticipantStatisticsList result2 = response2.readEntity(ParticipantStatisticsList.class);
+
+        assertNotNull(result2);
+        assertThat(result2.getStatisticsList()).hasSize(1);
+        assertEquals(result1.getStatisticsList().get(0), participantStatisticsList
+            .getStatisticsList().get(0));
+    }
+
+    @Test
+    public void testParticipantStats_BadRequest() throws Exception {
+        Invocation.Builder invokeRequest1 =
+            super.sendRequest(PARTICIPANT_STATS_ENDPOINT + "?version=0.0");
+        Response response1 = invokeRequest1.buildGet().invoke();
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus());
+    }
+
+    @Test
+    public void testParticipantStatsPerClEndpoint() throws Exception {
+        Invocation.Builder invokeRequest1 =
+            super.sendRequest(PARTICIPANT_STATS_PER_CL_ENDPOINT + "?name=dummyName&version=1.001");
+        Response response1 = invokeRequest1.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus());
+        ParticipantStatisticsList result1 = response1.readEntity(ParticipantStatisticsList.class);
+        assertThat(result1.getStatisticsList()).isEmpty();
+    }
+
+    @Test
+    public void testParticipantStatsPerCl_BadRequest() throws Exception {
+        Invocation.Builder invokeRequest1 =
+            super.sendRequest(PARTICIPANT_STATS_PER_CL_ENDPOINT);
+        Response response1 = invokeRequest1.buildGet().invoke();
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus());
+    }
+
+    @Test
+    public void testClElementStatisticsPerClEndpoint() throws Exception {
+        Invocation.Builder invokeRequest1 =
+            super.sendRequest(CLELEMENT_STATS_PER_CL_ENDPOINT + "?name=dummyName&version=1.001");
+        Response response1 = invokeRequest1.buildGet().invoke();
+        assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus());
+        ClElementStatisticsList result1 = response1.readEntity(ClElementStatisticsList.class);
+        assertThat(result1.getClElementStatistics()).isEmpty();
+    }
+
+    @Test
+    public void testClElementStatsPerCl_BadRequest() throws Exception {
+        Invocation.Builder invokeRequest1 =
+            super.sendRequest(CLELEMENT_STATS_PER_CL_ENDPOINT);
+        Response response1 = invokeRequest1.buildGet().invoke();
+        assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus());
+    }
+}
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java
new file mode 100644
index 0000000..77f802d
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java
@@ -0,0 +1,63 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.util;
+
+import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
+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.resources.ResourceUtils;
+
+/**
+ * Class to hold/create all parameters for test cases.
+ *
+ */
+public class CommonTestData {
+    private static final Coder coder = new StandardCoder();
+
+    /**
+     * Gets the standard Control Loop parameters.
+     *
+     * @param port port to be inserted into the parameters
+     * @param dbName the database name
+     * @return the standard Control Loop parameters
+     */
+    public static ClRuntimeParameterGroup geParameterGroup(final int port, final String dbName) {
+        try {
+            return coder.decode(getParameterGroupAsString(port, dbName), ClRuntimeParameterGroup.class);
+
+        } catch (CoderException e) {
+            throw new RuntimeException("cannot read Control Loop parameters", e);
+        }
+    }
+
+    /**
+     * Gets the standard Control Loop parameters, as a String.
+     *
+     * @param port port to be inserted into the parameters
+     * @param dbName the database name
+     * @return the standard Control Loop parameters as string
+     */
+    public static String getParameterGroupAsString(final int port, final String dbName) {
+        return ResourceUtils.getResourceAsString("src/test/resources/parameters/InstantiationConfigParametersStd.json")
+                .replace("${port}", String.valueOf(port)).replace("${dbName}", "jdbc:h2:mem:" + dbName);
+    }
+}
diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/rest/CommonRestController.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/rest/CommonRestController.java
new file mode 100644
index 0000000..0d668f1
--- /dev/null
+++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/rest/CommonRestController.java
@@ -0,0 +1,263 @@
+/*-
+ * ============LICENSE_START=======================================================
+ *  Copyright (C) 2021 Nordix Foundation.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ * ============LICENSE_END=========================================================
+ */
+
+package org.onap.policy.clamp.controlloop.runtime.util.rest;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import javax.ws.rs.client.Client;
+import javax.ws.rs.client.ClientBuilder;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.client.WebTarget;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
+import org.onap.policy.clamp.controlloop.runtime.main.startstop.Main;
+import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData;
+import org.onap.policy.common.gson.GsonMessageBodyHandler;
+import org.onap.policy.common.utils.network.NetworkUtil;
+import org.onap.policy.common.utils.services.Registry;
+import org.onap.policy.models.provider.PolicyModelsProviderParameters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class to perform Rest unit tests.
+ *
+ */
+public class CommonRestController {
+
+    private static final String CONFIG_FILE = "src/test/resources/parameters/RuntimeConfigParameters%d.json";
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(CommonRestController.class);
+
+    public static final String SELF = NetworkUtil.getHostname();
+    public static final String ENDPOINT_PREFIX = "onap/controlloop/v2/";
+
+    private static int port;
+    private static String httpPrefix;
+    private static Main main;
+
+    /**
+     * Allocates a port for the server, writes a config file, and then starts Main.
+     *
+     * @param dbName database name
+     * @throws Exception if an error occurs
+     */
+    public static void setUpBeforeClass(final String dbName) throws Exception {
+        port = NetworkUtil.allocPort();
+
+        httpPrefix = "http://" + SELF + ":" + port + "/";
+
+        makeConfigFile(dbName);
+        startMain();
+    }
+
+    /**
+     * Stops Main.
+     */
+    public static void teardownAfterClass() {
+        try {
+            stopMain();
+        } catch (Exception ex) {
+            LOGGER.error("cannot stop main", ex);
+        }
+    }
+
+    protected static PolicyModelsProviderParameters getParameters() {
+        return main.getParameters().getDatabaseProviderParameters();
+    }
+
+    /**
+     * Verifies that an endpoint appears within the swagger response.
+     *
+     * @param endpoint the endpoint of interest
+     * @throws Exception if an error occurs
+     */
+    protected void testSwagger(final String endpoint) throws Exception {
+        final Invocation.Builder invocationBuilder = sendFqeRequest(httpPrefix + "swagger.yaml", true);
+        final String resp = invocationBuilder.get(String.class);
+
+        assertTrue(resp.contains(ENDPOINT_PREFIX + endpoint + ":"));
+    }
+
+    /**
+     * Makes a parameter configuration file.
+     *
+     * @param dbName database name
+     * @throws IOException if an error occurs writing the configuration file
+     * @throws FileNotFoundException if an error occurs writing the configuration file
+     */
+    private static void makeConfigFile(final String dbName) throws FileNotFoundException, IOException {
+        String json = CommonTestData.getParameterGroupAsString(port, dbName);
+
+        File file = new File(String.format(CONFIG_FILE, port));
+        file.deleteOnExit();
+
+        try (FileOutputStream output = new FileOutputStream(file)) {
+            output.write(json.getBytes(StandardCharsets.UTF_8));
+        }
+    }
+
+    /**
+     * Starts the "Main".
+     *
+     * @throws InterruptedException
+     *
+     * @throws Exception if an error occurs
+     */
+    protected static void startMain() throws InterruptedException {
+        Registry.newRegistry();
+
+        // make sure port is available
+        if (NetworkUtil.isTcpPortOpen(SELF, port, 1, 1L)) {
+            throw new IllegalStateException("port " + port + " is not available");
+        }
+
+        final String[] configParameters = {"-c", String.format(CONFIG_FILE, port)};
+
+        main = new Main(configParameters);
+
+        if (!NetworkUtil.isTcpPortOpen(SELF, port, 40, 250L)) {
+            throw new IllegalStateException("server is not listening on port " + port);
+        }
+    }
+
+    /**
+     * Stops the "Main".
+     *
+     * @throws ControlLoopException
+     *
+     * @throws Exception if an error occurs
+     */
+    private static void stopMain() throws Exception {
+        if (main != null) {
+            Main main2 = main;
+            main = null;
+
+            main2.shutdown();
+        }
+        // make sure port is close
+        if (NetworkUtil.isTcpPortOpen(SELF, port, 1, 1L)) {
+            throw new IllegalStateException("port " + port + " is still in use");
+        }
+    }
+
+    /**
+     * Sends a request to an endpoint.
+     *
+     * @param endpoint the target endpoint
+     * @return a request builder
+     * @throws Exception if an error occurs
+     */
+    protected Invocation.Builder sendRequest(final String endpoint) throws Exception {
+        return sendFqeRequest(httpPrefix + ENDPOINT_PREFIX + endpoint, true);
+    }
+
+    /**
+     * Sends a request to an endpoint, without any authorization header.
+     *
+     * @param endpoint the target endpoint
+     * @return a request builder
+     * @throws Exception if an error occurs
+     */
+    protected Invocation.Builder sendNoAuthRequest(final String endpoint) throws Exception {
+        return sendFqeRequest(httpPrefix + ENDPOINT_PREFIX + endpoint, false);
+    }
+
+    /**
+     * Sends a request to a fully qualified endpoint.
+     *
+     * @param fullyQualifiedEndpoint the fully qualified target endpoint
+     * @param includeAuth if authorization header should be included
+     * @return a request builder
+     * @throws Exception if an error occurs
+     */
+    protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth)
+            throws Exception {
+        final Client client = ClientBuilder.newBuilder().build();
+
+        client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true");
+        client.register(GsonMessageBodyHandler.class);
+
+        if (includeAuth) {
+            client.register(HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34"));
+        }
+
+        final WebTarget webTarget = client.target(fullyQualifiedEndpoint);
+
+        return webTarget.request(MediaType.APPLICATION_JSON);
+    }
+
+    /**
+     * Assert that POST call is Unauthorized.
+     *
+     * @param endPoint the endpoint
+     * @param entity the entity ofthe body
+     * @throws Exception if an error occurs
+     */
+    protected void assertUnauthorizedPost(final String endPoint, final Entity<?> entity) throws Exception {
+        Response rawresp = sendNoAuthRequest(endPoint).post(entity);
+        assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus());
+    }
+
+    /**
+     * Assert that PUT call is Unauthorized.
+     *
+     * @param endPoint the endpoint
+     * @param entity the entity ofthe body
+     * @throws Exception if an error occurs
+     */
+    protected void assertUnauthorizedPut(final String endPoint, final Entity<?> entity) throws Exception {
+        Response rawresp = sendNoAuthRequest(endPoint).put(entity);
+        assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus());
+    }
+
+    /**
+     * Assert that GET call is Unauthorized.
+     *
+     * @param endPoint the endpoint
+     * @throws Exception if an error occurs
+     */
+    protected void assertUnauthorizedGet(final String endPoint) throws Exception {
+        Response rawresp = sendNoAuthRequest(endPoint).buildGet().invoke();
+        assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus());
+    }
+
+    /**
+     * Assert that DELETE call is Unauthorized.
+     *
+     * @param endPoint the endpoint
+     * @throws Exception if an error occurs
+     */
+    protected void assertUnauthorizedDelete(final String endPoint) throws Exception {
+        Response rawresp = sendNoAuthRequest(endPoint).delete();
+        assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus());
+    }
+}
\ No newline at end of file
diff --git a/runtime-controlloop/src/test/resources/META-INF/persistence.xml b/runtime-controlloop/src/test/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..6e31cca
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/META-INF/persistence.xml
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============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=========================================================
+-->
+<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
+    <persistence-unit name="CommissioningMariaDb" transaction-type="RESOURCE_LOCAL">
+        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+
+        <class>org.onap.policy.models.base.PfConceptKey</class>
+        <class>org.onap.policy.models.dao.converters.CDataConditioner</class>
+        <class>org.onap.policy.models.dao.converters.Uuid2String</class>
+        <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdp</class>
+        <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpGroup</class>
+        <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpStatistics</class>
+        <class>org.onap.policy.models.pdp.persistence.concepts.JpaPdpSubGroup</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityAssignment</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityAssignments</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaDataType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaDataTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplates</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaParameter</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicies</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaProperty</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRelationshipType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRelationshipTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRequirement</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRequirements</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaTopologyTemplate</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaTrigger</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoop</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoopElement</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaParticipant</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaParticipantStatistics</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaClElementStatistics</class>
+
+        <properties>
+            <property name="eclipselink.ddl-generation" value="create-or-extend-tables" />
+            <property name="eclipselink.ddl-generation.output-mode" value="database" />
+            <property name="eclipselink.logging.level" value="INFO" />
+
+            <!-- property name="eclipselink.logging.level" value="ALL" />
+            <property name="eclipselink.logging.level.jpa" value="ALL" />
+            <property name="eclipselink.logging.level.ddl" value="ALL" />
+            <property name="eclipselink.logging.level.connection" value="ALL" />
+            <property name="eclipselink.logging.level.sql" value="ALL" />
+            <property name="eclipselink.logging.level.transaction" value="ALL" />
+            <property name="eclipselink.logging.level.sequencing" value="ALL" />
+            <property name="eclipselink.logging.level.server" value="ALL" />
+            <property name="eclipselink.logging.level.query" value="ALL" />
+            <property name="eclipselink.logging.level.properties" value="ALL" /-->
+        </properties>
+        <shared-cache-mode>NONE</shared-cache-mode>
+    </persistence-unit>
+
+    <persistence-unit name="ToscaConceptTest" transaction-type="RESOURCE_LOCAL">
+        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityAssignment</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityAssignments</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaDataType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaDataTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplates</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaParameter</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicies</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaProperty</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRelationshipType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRelationshipTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRequirement</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRequirements</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaTopologyTemplate</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoop</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoopElement</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaParticipantStatistics</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaClElementStatistics</class>
+
+        <properties>
+            <property name="eclipselink.target-database" value="MySQL" />
+            <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
+            <property name="eclipselink.ddl-generation.output-mode" value="database" />
+            <property name="eclipselink.logging.level" value="INFO" />
+        </properties>
+        <shared-cache-mode>NONE</shared-cache-mode>
+    </persistence-unit>
+
+    <persistence-unit name="InstantiationTests" transaction-type="RESOURCE_LOCAL">
+        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
+
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityAssignment</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityAssignments</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaCapabilityTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaDataType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaDataTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplate</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTemplates</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaNodeTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaParameter</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicies</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicy</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaPolicyTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaProperty</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRelationshipType</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRelationshipTypes</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRequirement</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaRequirements</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaServiceTemplate</class>
+        <class>org.onap.policy.models.tosca.simple.concepts.JpaToscaTopologyTemplate</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoop</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaControlLoopElement</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaParticipant</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaParticipantStatistics</class>
+        <class>org.onap.policy.clamp.controlloop.models.controlloop.persistence.concepts.JpaClElementStatistics</class>
+
+        <properties>
+            <property name="eclipselink.ddl-generation" value="create-or-extend-tables" />
+            <property name="eclipselink.ddl-generation.output-mode" value="database" />
+            <property name="eclipselink.logging.level" value="INFO" />
+        </properties>
+        <shared-cache-mode>NONE</shared-cache-mode>
+    </persistence-unit>
+
+</persistence>
+
diff --git a/runtime-controlloop/src/test/resources/parameters/CommissioningConfig.json b/runtime-controlloop/src/test/resources/parameters/CommissioningConfig.json
new file mode 100644
index 0000000..bda9da6
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/CommissioningConfig.json
@@ -0,0 +1,20 @@
+{
+  "name": "CommissioningGroup",
+  "restServerParameters": {
+    "host": "127.0.0.1",
+    "port": 6969,
+    "userName": "admin",
+    "password": "password",
+    "https": false,
+    "aaf": false
+  },
+  "databaseProviderParameters": {
+    "name": "CommissioningProviderParameterGroup",
+    "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl",
+    "databaseDriver": "org.h2.Driver",
+    "databaseUrl": "jdbc:h2:mem:testdb",
+    "databaseUser": "controlloop",
+    "databasePassword": "C0ntr0lL00p",
+    "persistenceUnit": "ToscaConceptTest"
+  }
+}
diff --git a/runtime-controlloop/src/test/resources/parameters/EmptyParameters.json b/runtime-controlloop/src/test/resources/parameters/EmptyParameters.json
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/EmptyParameters.json
diff --git a/runtime-controlloop/src/test/resources/parameters/InstantiationConfigParametersStd.json b/runtime-controlloop/src/test/resources/parameters/InstantiationConfigParametersStd.json
new file mode 100644
index 0000000..7682a18
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/InstantiationConfigParametersStd.json
@@ -0,0 +1,79 @@
+{
+    "name": "ControlLoopRuntimeGroup",
+    "restServerParameters": {
+        "host": "0.0.0.0",
+        "port": ${port},
+        "userName": "healthcheck",
+        "password": "zb!XztG34",
+        "https": false,
+        "aaf": false
+    },
+    "participantParameters": {
+        "heartBeatMs": 120000,
+        "updateParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 30000
+        },
+        "stateChangeParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 30000
+        }
+    },
+    "databaseProviderParameters": {
+        "name": "PolicyProviderParameterGroup",
+        "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl",
+        "databaseDriver": "org.h2.Driver",
+        "databaseUrl": "${dbName}",
+        "databaseUser": "policy",
+        "databasePassword": "P01icY",
+        "persistenceUnit": "InstantiationTests"
+    },
+    "topicParameterGroup": {
+        "topicSources": [
+            {
+                "topic": "POLICY-CLRUNTIME-PARTICIPANT",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap",
+                "fetchTimeout": 15000
+            }
+        ],
+        "topicSinks": [
+            {
+                "topic": "POLICY-CLRUNTIME-PARTICIPANT",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap"
+            },
+            {
+                "topic": "POLICY-NOTIFICATION",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap"
+            }
+        ]
+    },
+    "healthCheckRestClientParameters": [
+        {
+            "clientName": "api",
+            "hostname": "policy-api",
+            "port": 6969,
+            "userName": "healthcheck",
+            "password": "zb!XztG34",
+            "useHttps": true,
+            "basePath": "policy/api/v1/healthcheck"
+        },
+        {
+            "clientName": "distribution",
+            "hostname": "policy-distribution",
+            "port": 6969,
+            "userName": "healthcheck",
+            "password": "zb!XztG34",
+            "useHttps": true,
+            "basePath": "healthcheck"
+        }
+    ]
+}
diff --git a/runtime-controlloop/src/test/resources/parameters/InstantiationConfigParameters_InvalidName.json b/runtime-controlloop/src/test/resources/parameters/InstantiationConfigParameters_InvalidName.json
new file mode 100644
index 0000000..b0c322c
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/InstantiationConfigParameters_InvalidName.json
@@ -0,0 +1,31 @@
+{
+    "name":" ",
+  "restServerParameters": {
+    "host": "127.0.0.1",
+    "port": 6969,
+    "userName": "admin",
+    "password": "password",
+    "https": false,
+    "aaf": false
+  },
+    "pdpParameters": {
+        "heartBeatMs": 1,
+        "updateParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 1
+        },
+        "stateChangeParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 1
+        }
+    },
+    "databaseProviderParameters": {
+        "name": "PolicyProviderParameterGroup",
+        "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl",
+        "databaseDriver": "org.h2.Driver",
+        "databaseUrl": "jdbc:h2:mem:testdb",
+        "databaseUser": "policy",
+        "databasePassword": "P01icY",
+        "persistenceUnit": "PdpGroupTest"
+    }
+}
diff --git a/runtime-controlloop/src/test/resources/parameters/InstantiationConfigParameters_sim.json b/runtime-controlloop/src/test/resources/parameters/InstantiationConfigParameters_sim.json
new file mode 100644
index 0000000..0977da9
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/InstantiationConfigParameters_sim.json
@@ -0,0 +1,43 @@
+{
+    "name": "Instantiation",
+  "restServerParameters": {
+    "host": "127.0.0.1",
+    "port": 6969,
+    "userName": "admin",
+    "password": "password",
+    "https": false,
+    "aaf": false
+  },
+    "pdpParameters": {
+        "heartBeatMs": 10,
+        "updateParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 30000
+        },
+        "stateChangeParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 30000
+        }
+    },
+    "databaseProviderParameters": {
+        "name": "PolicyProviderParameterGroup",
+        "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl",
+        "databaseDriver": "org.mariadb.jdbc.Driver",
+        "databaseUrl": "jdbc:mariadb://localhost:3306/policyadmin",
+        "databaseUser": "policy",
+        "databasePassword": "UDAxaWNZ",
+        "persistenceUnit": "PolicyMariaDb"
+    },
+    "topicParameterGroup": {
+        "topicSources" : [{
+            "topic" : "INSTANTIATION",
+            "servers" : [ "localhost:6845" ],
+            "topicCommInfrastructure" : "dmaap"
+        }],
+        "topicSinks" : [{
+            "topic" : "INSTANTIATION",
+            "servers" : [ "localhost:6845" ],
+            "topicCommInfrastructure" : "dmaap"
+        }]
+    }
+}
diff --git a/runtime-controlloop/src/test/resources/parameters/InvalidParameters.json b/runtime-controlloop/src/test/resources/parameters/InvalidParameters.json
new file mode 100644
index 0000000..976ec29
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/InvalidParameters.json
@@ -0,0 +1,3 @@
+{
+  "name": ""
+}
diff --git a/runtime-controlloop/src/test/resources/parameters/MinimumParametersH2.json b/runtime-controlloop/src/test/resources/parameters/MinimumParametersH2.json
new file mode 100644
index 0000000..f784dcd
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/MinimumParametersH2.json
@@ -0,0 +1,59 @@
+{
+    "name":"PapGroup",
+    "restServerParameters":{
+        "host":"0.0.0.0",
+        "port":6969,
+        "userName":"healthcheck",
+        "password":"zb!XztG34"
+    },
+    "pdpParameters": {
+        "heartBeatMs": 1,
+        "updateParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 1
+        },
+        "stateChangeParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 1
+        }
+    },
+    "databaseProviderParameters": {
+        "name": "PolicyProviderParameterGroup",
+        "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl",
+        "databaseDriver": "org.h2.Driver",
+        "databaseUrl": "jdbc:h2:mem:testdb",
+        "databaseUser": "policy",
+        "databasePassword": "P01icY",
+        "persistenceUnit": "PdpGroupTest"
+    },
+    "topicParameterGroup": {
+        "topicSources" : [{
+            "topic" : "POLICY-PDP-PAP",
+            "servers" : [ "message-router" ],
+            "topicCommInfrastructure" : "dmaap"
+        }],
+        "topicSinks" : [{
+            "topic" : "POLICY-PDP-PAP",
+            "servers" : [ "message-router" ],
+            "topicCommInfrastructure" : "dmaap"
+        }]
+    },
+    "healthCheckRestClientParameters":[{
+        "clientName": "api",
+        "hostname": "policy-api",
+        "port": 6969,
+        "userName": "healthcheck",
+        "password": "zb!XztG34",
+        "useHttps": true,
+        "basePath": "policy/api/v1/healthcheck"
+    },
+    {
+        "clientName": "distribution",
+        "hostname": "policy-distribution",
+        "port": 6969,
+        "userName": "healthcheck",
+        "password": "zb!XztG34",
+        "useHttps": true,
+        "basePath": "healthcheck"
+    }]
+}
diff --git a/runtime-controlloop/src/test/resources/parameters/NoParameters.json b/runtime-controlloop/src/test/resources/parameters/NoParameters.json
new file mode 100644
index 0000000..2c63c08
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/NoParameters.json
@@ -0,0 +1,2 @@
+{
+}
diff --git a/runtime-controlloop/src/test/resources/parameters/TestParameters.json b/runtime-controlloop/src/test/resources/parameters/TestParameters.json
new file mode 100644
index 0000000..c3be762
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/TestParameters.json
@@ -0,0 +1,79 @@
+{
+    "name": "ControlLoopRuntimeGroup",
+    "restServerParameters": {
+        "host": "0.0.0.0",
+        "port": 6969,
+        "userName": "healthcheck",
+        "password": "zb!XztG34",
+        "https": false,
+        "aaf": false
+    },
+    "participantParameters": {
+        "heartBeatMs": 120000,
+        "updateParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 30000
+        },
+        "stateChangeParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 30000
+        }
+    },
+    "databaseProviderParameters": {
+        "name": "PolicyProviderParameterGroup",
+        "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl",
+        "databaseDriver": "org.h2.Driver",
+        "databaseUrl": "jdbc:h2:mem:testdb",
+        "databaseUser": "policy",
+        "databasePassword": "P01icY",
+        "persistenceUnit": "ToscaConceptTest"
+    },
+    "topicParameterGroup": {
+        "topicSources": [
+            {
+                "topic": "POLICY-CLRUNTIME-PARTICIPANT",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap",
+                "fetchTimeout": 15000
+            }
+        ],
+        "topicSinks": [
+            {
+                "topic": "POLICY-CLRUNTIME-PARTICIPANT",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap"
+            },
+            {
+                "topic": "POLICY-NOTIFICATION",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap"
+            }
+        ]
+    },
+    "healthCheckRestClientParameters": [
+        {
+            "clientName": "api",
+            "hostname": "policy-api",
+            "port": 6969,
+            "userName": "healthcheck",
+            "password": "zb!XztG34",
+            "useHttps": true,
+            "basePath": "policy/api/v1/healthcheck"
+        },
+        {
+            "clientName": "distribution",
+            "hostname": "policy-distribution",
+            "port": 6969,
+            "userName": "healthcheck",
+            "password": "zb!XztG34",
+            "useHttps": true,
+            "basePath": "healthcheck"
+        }
+    ]
+}
diff --git a/runtime-controlloop/src/test/resources/parameters/TestParametersMariaDB.json b/runtime-controlloop/src/test/resources/parameters/TestParametersMariaDB.json
new file mode 100644
index 0000000..2c0127b
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/TestParametersMariaDB.json
@@ -0,0 +1,79 @@
+{
+    "name": "ControlLoopRuntimeGroup",
+    "restServerParameters": {
+        "host": "0.0.0.0",
+        "port": 6969,
+        "userName": "healthcheck",
+        "password": "zb!XztG34",
+        "https": false,
+        "aaf": false
+    },
+    "participantParameters": {
+        "heartBeatMs": 120000,
+        "updateParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 30000
+        },
+        "stateChangeParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 30000
+        }
+    },
+    "databaseProviderParameters": {
+        "name": "PolicyProviderParameterGroup",
+        "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl",
+        "databaseDriver": "org.mariadb.jdbc.Driver",
+        "databaseUrl": "jdbc:mariadb://localhost:3306/controlloop",
+        "databaseUser": "policy",
+        "databasePassword": "P01icY",
+        "persistenceUnit": "CommissioningMariaDb"
+    },
+    "topicParameterGroup": {
+        "topicSources": [
+            {
+                "topic": "POLICY-CLRUNTIME-PARTICIPANT",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap",
+                "fetchTimeout": 15000
+            }
+        ],
+        "topicSinks": [
+            {
+                "topic": "POLICY-CLRUNTIME-PARTICIPANT",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap"
+            },
+            {
+                "topic": "POLICY-NOTIFICATION",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap"
+            }
+        ]
+    },
+    "healthCheckRestClientParameters": [
+        {
+            "clientName": "api",
+            "hostname": "policy-api",
+            "port": 6969,
+            "userName": "healthcheck",
+            "password": "zb!XztG34",
+            "useHttps": true,
+            "basePath": "policy/api/v1/healthcheck"
+        },
+        {
+            "clientName": "distribution",
+            "hostname": "policy-distribution",
+            "port": 6969,
+            "userName": "healthcheck",
+            "password": "zb!XztG34",
+            "useHttps": true,
+            "basePath": "healthcheck"
+        }
+    ]
+}
diff --git a/runtime-controlloop/src/test/resources/parameters/Unreadable.json b/runtime-controlloop/src/test/resources/parameters/Unreadable.json
new file mode 100644
index 0000000..3d117f4
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/Unreadable.json
@@ -0,0 +1,78 @@
+{
+    "name": "ControlLoopRuntimeGroup",
+    "restServerParameters": {
+        "host": "0.0.0.0",
+        "port": 6969,
+        "userName": "healthcheck",
+        "password": "zb!XztG34",
+        "https": false,
+        "aaf": false
+    },
+    "participantParameters": {
+        "heartBeatMs": 120000,
+        "updateParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 30000
+        },
+        "stateChangeParameters": {
+            "maxRetryCount": 1,
+            "maxWaitMs": 30000
+        }
+    },
+    "databaseProviderParameters": {
+        "name": "PolicyProviderParameterGroup",
+        "implementation": "org.onap.policy.models.provider.impl.DatabasePolicyModelsProviderImpl",
+        "databaseDriver": "org.h2.Driver",
+        "databaseUrl": "jdbc:h2:mem:testdb",
+        "databaseUser": "policy",
+        "databasePassword": "P01icY",
+        "persistenceUnit": "ToscaConceptTest"
+    },
+    "topicParameterGroup": {
+        "topicSources": [
+            {
+                "topic": "POLICY-CLRUNTIME-PARTICIPANT",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap",
+                "fetchTimeout": 15000
+            }
+        ],
+        "topicSinks": [
+            {
+                "topic": "POLICY-CLRUNTIME-PARTICIPANT",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap"
+            },
+            {
+                "topic": "POLICY-NOTIFICATION",
+                "servers": [
+                    "localhost"
+                ],
+                "topicCommInfrastructure": "dmaap"
+            }
+        ]
+    },
+    "healthCheckRestClientParameters": [
+        {
+            "clientName": "api",
+            "hostname": "policy-api",
+            "port": 6969,
+            "userName": "healthcheck",
+            "password": "zb!XztG34",
+            "useHttps": true,
+            "basePath": "policy/api/v1/healthcheck"
+        },
+        {
+            "clientName": "distribution",
+            "hostname": "policy-distribution",
+            "port": 6969,
+            "userName": "healthcheck",
+            "password": "zb!XztG34",
+            "useHttps": true,
+            "basePath": "healthcheck"
+        }
+    ]
diff --git a/runtime-controlloop/src/test/resources/parameters/logback-test.xml b/runtime-controlloop/src/test/resources/parameters/logback-test.xml
new file mode 100644
index 0000000..e00c36b
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/parameters/logback-test.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ============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=========================================================
+-->
+
+<configuration>
+
+    <contextName>Apex</contextName>
+    <statusListener class="ch.qos.logback.core.status.OnConsoleStatusListener" />
+    <property name="LOG_DIR" value="${java.io.tmpdir}/clamp_logging/" />
+
+    <!-- USE FOR STD OUT ONLY -->
+    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <Pattern>%d %contextName [%t] %level %logger{36} - %msg%n</Pattern>
+        </encoder>
+    </appender>
+
+    <root level="info">
+        <appender-ref ref="STDOUT" />
+    </root>
+
+    <logger name="org.onap.policy.clamp.controlloop.runtime" level="trace" additivity="false">
+        <appender-ref ref="STDOUT" />
+    </logger>
+</configuration>
diff --git a/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json
new file mode 100644
index 0000000..faea7cd
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json
@@ -0,0 +1,142 @@
+{
+    "controlLoopList": [
+        {
+            "name": "PMSHInstance0",
+            "version": "1.0.1",
+            "definition": {
+                "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition",
+                "version": "1.2.3"
+            },
+            "state": "UNINITIALISED",
+            "orderedState": "UNINITIALISED",
+            "description": "PMSH control loop instance 0",
+            "elements": {
+                "709c62b3-8918-41b9-a747-d21eb79c6c20": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.DCAEMicroservice",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c21": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c22": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c22",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c23": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c23",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 0 control loop"
+                }
+            }
+        },
+        {
+            "name": "PMSHInstance1",
+            "version": "1.0.1",
+            "definition": {
+                "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition",
+                "version": "1.2.3"
+            },
+            "state": "UNINITIALISED",
+            "orderedState": "UNINITIALISED",
+            "description": "PMSH control loop instance 1",
+            "elements": {
+                "709c62b3-8918-41b9-a747-d21eb79c6c24": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c24",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.DCAEMicroservice",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c25": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c25",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c26": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c26",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c27": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c27",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 1 control loop"
+                }
+            }
+        }
+    ]
+}
diff --git a/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoops.json b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoops.json
new file mode 100644
index 0000000..13ea1bf
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoops.json
@@ -0,0 +1,142 @@
+{
+    "controlLoopList": [
+        {
+            "name": "PMSHInstance0",
+            "version": "1.0.1",
+            "definition": {
+                "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition",
+                "version": "1.2.3"
+            },
+            "state": "UNINITIALISED",
+            "orderedState": "UNINITIALISED",
+            "description": "PMSH control loop instance 0",
+            "elements": {
+                "709c62b3-8918-41b9-a747-d21eb79c6c20": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c21": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c22": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c22",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c23": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c23",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 0 control loop"
+                }
+            }
+        },
+        {
+            "name": "PMSHInstance1",
+            "version": "1.0.1",
+            "definition": {
+                "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition",
+                "version": "1.2.3"
+            },
+            "state": "UNINITIALISED",
+            "orderedState": "UNINITIALISED",
+            "description": "PMSH control loop instance 1",
+            "elements": {
+                "709c62b3-8918-41b9-a747-d21eb79c6c24": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c24",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c25": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c25",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c26": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c26",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c27": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c27",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 1 control loop"
+                }
+            }
+        }
+    ]
+}
diff --git a/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsNotFound.json b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsNotFound.json
new file mode 100644
index 0000000..9e97674
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsNotFound.json
@@ -0,0 +1,142 @@
+{
+    "controlLoopList": [
+        {
+            "name": "PMSHInstance0",
+            "version": "1.0.1",
+            "definition": {
+                "name": "org.onap.domain.PMSHControlLoopDefinition",
+                "version": "1.2.3"
+            },
+            "state": "UNINITIALISED",
+            "orderedState": "UNINITIALISED",
+            "description": "PMSH control loop instance 0",
+            "elements": {
+                "709c62b3-8918-41b9-a747-d21eb79c6c20": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c21": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c22": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c22",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c23": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c23",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 0 control loop"
+                }
+            }
+        },
+        {
+            "name": "PMSHInstance1",
+            "version": "1.0.1",
+            "definition": {
+                "name": "org.onap.domain.PMSHControlLoopDefinition",
+                "version": "1.2.3"
+            },
+            "state": "UNINITIALISED",
+            "orderedState": "UNINITIALISED",
+            "description": "PMSH control loop instance 1",
+            "elements": {
+                "709c62b3-8918-41b9-a747-d21eb79c6c24": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c24",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c25": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c25",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c26": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c26",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c27": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c27",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 1 control loop"
+                }
+            }
+        }
+    ]
+}
diff --git a/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsUpdate.json b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsUpdate.json
new file mode 100644
index 0000000..025e2a1
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsUpdate.json
@@ -0,0 +1,142 @@
+{
+    "controlLoopList": [
+        {
+            "name": "PMSHInstance0",
+            "version": "1.0.1",
+            "definition": {
+                "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition",
+                "version": "1.2.3"
+            },
+            "state": "UNINITIALISED",
+            "orderedState": "UNINITIALISED",
+            "description": "PMSH control loop instance 1",
+            "elements": {
+                "709c62b3-8918-41b9-a747-d21eb79c6c21": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c22": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c22",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c23": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c23",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c24": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c24",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 0 control loop"
+                }
+            }
+        },
+        {
+            "name": "PMSHInstance1",
+            "version": "1.0.1",
+            "definition": {
+                "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition",
+                "version": "1.2.3"
+            },
+            "state": "UNINITIALISED",
+            "orderedState": "UNINITIALISED",
+            "description": "PMSH control loop instance 1",
+            "elements": {
+                "709c62b3-8918-41b9-a747-d21eb79c6c25": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c25",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c26": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c26",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c27": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c27",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c28": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c28",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 1 control loop"
+                }
+            }
+        }
+    ]
+}
diff --git a/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsVersionNotMatches.json b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsVersionNotMatches.json
new file mode 100644
index 0000000..76131af
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/controlloops/ControlLoopsVersionNotMatches.json
@@ -0,0 +1,142 @@
+{
+    "controlLoopList": [
+        {
+            "name": "PMSHInstance0",
+            "version": "1.0.1",
+            "definition": {
+                "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition",
+                "version": "1.2.3"
+            },
+            "state": "UNINITIALISED",
+            "orderedState": "UNINITIALISED",
+            "description": "PMSH control loop instance 0",
+            "elements": {
+                "709c62b3-8918-41b9-a747-d21eb79c6c20": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
+                        "version": "1.0.0"
+                    },
+                    "participantType": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c21": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c22": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c22",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c23": {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c23",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 0 control loop"
+                }
+            }
+        },
+        {
+            "name": "PMSHInstance1",
+            "version": "1.0.1",
+            "definition": {
+                "name": "org.onap.domain.pmsh.PMSHControlLoopDefinition",
+                "version": "1.2.3"
+            },
+            "state": "UNINITIALISED",
+            "orderedState": "UNINITIALISED",
+            "description": "PMSH control loop instance 1",
+            "elements": {
+                "709c62b3-8918-41b9-a747-d21eb79c6c24": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c24",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
+                        "version": "1.0.0"
+                    },
+                    "participantType": {
+                        "name": "org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant",
+                        "version": "2.3.4"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c25": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c25",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c26": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c26",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.policy.controlloop.PolicyControlLoopParticipant",
+                        "version": "2.3.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                "709c62b3-8918-41b9-a747-d21eb79c6c27": {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c27",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantType": {
+                        "name": "org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant",
+                        "version": "2.2.1"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 1 control loop"
+                }
+            }
+        }
+    ]
+}
diff --git a/runtime-controlloop/src/test/resources/rest/controlloops/PassiveCommand.json b/runtime-controlloop/src/test/resources/rest/controlloops/PassiveCommand.json
new file mode 100644
index 0000000..9c87e43
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/controlloops/PassiveCommand.json
@@ -0,0 +1,13 @@
+{
+    "orderedState": "PASSIVE",
+    "controlLoopIdentifierList": [
+        {
+            "name": "PMSHInstance0",
+            "version": "1.0.1"
+        },
+        {
+            "name": "PMSHInstance1",
+            "version": "1.0.1"
+        }
+    ]
+}
diff --git a/runtime-controlloop/src/test/resources/rest/monitoring/TestClElementStatistics.json b/runtime-controlloop/src/test/resources/rest/monitoring/TestClElementStatistics.json
new file mode 100644
index 0000000..21a048f
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/monitoring/TestClElementStatistics.json
@@ -0,0 +1,44 @@
+{
+  "clElementStatistics":[
+    {
+      "participantId":{
+        "name":"name1",
+        "version":"1.001"
+      },
+      "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+      "timeStamp": "2021-01-10T13:45:00.000Z",
+      "controlLoopState": "UNINITIALISED",
+      "clElementUptime":250
+    },
+    {
+      "participantId":{
+        "name":"name1",
+        "version":"1.001"
+      },
+      "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+      "timeStamp": "2021-01-10T15:45:00.000Z",
+      "controlLoopState": "UNINITIALISED",
+      "clElementUptime":450
+    },
+    {
+      "participantId":{
+        "name":"name2",
+        "version":"1.001"
+      },
+      "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+      "timeStamp": "2021-01-10T14:25:00.000Z",
+      "controlLoopState": "UNINITIALISED",
+      "clElementUptime":330
+    },
+    {
+      "participantId":{
+        "name":"name2",
+        "version":"1.001"
+      },
+      "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+      "timeStamp": "2021-01-10T16:35:00.000Z",
+      "controlLoopState": "UNINITIALISED",
+      "clElementUptime":650
+    }
+  ]
+}
\ No newline at end of file
diff --git a/runtime-controlloop/src/test/resources/rest/monitoring/TestClElementStatistics_Invalid.json b/runtime-controlloop/src/test/resources/rest/monitoring/TestClElementStatistics_Invalid.json
new file mode 100644
index 0000000..2cf2619
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/monitoring/TestClElementStatistics_Invalid.json
@@ -0,0 +1,13 @@
+{
+  "clElementStatisticsList":[
+    {
+      "participantId":{
+        "name":"name1",
+        "version":"1.001"
+      },
+      "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+      "controlLoopState": "UNINITIALISED",
+      "clElementUptime":250
+    }
+  ]
+}
\ No newline at end of file
diff --git a/runtime-controlloop/src/test/resources/rest/monitoring/TestParticipantStatistics.json b/runtime-controlloop/src/test/resources/rest/monitoring/TestParticipantStatistics.json
new file mode 100644
index 0000000..acd88e2
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/monitoring/TestParticipantStatistics.json
@@ -0,0 +1,46 @@
+{
+  "statisticsList":[
+    {
+      "participantId":{
+        "name":"name1",
+        "version":"1.001"
+      },
+      "timeStamp": "2021-01-10T13:45:00.000Z",
+      "state": "PASSIVE",
+      "healthStatus": "HEALTHY",
+      "eventCount":250,
+      "lastExecutionTime":100,
+      "averageExecutionTime":90,
+      "upTime":1000,
+      "lastStart":3000
+    },
+    {
+      "participantId":{
+        "name":"name1",
+        "version":"1.001"
+      },
+      "timeStamp": "2021-01-10T15:45:00.000Z",
+      "state": "PASSIVE",
+      "healthStatus": "HEALTHY",
+      "eventCount":262,
+      "lastExecutionTime":100,
+      "averageExecutionTime":90,
+      "upTime":2000,
+      "lastStart":3000
+    },
+    {
+      "participantId":{
+        "name":"name2",
+        "version":"1.001"
+      },
+      "timeStamp": "2021-01-27T14:25:00.000Z",
+      "state": "PASSIVE",
+      "healthStatus": "HEALTHY",
+      "eventCount":245,
+      "lastExecutionTime":1020,
+      "averageExecutionTime":85,
+      "upTime":1050,
+      "lastStart":3100
+    }
+  ]
+}
\ No newline at end of file
diff --git a/runtime-controlloop/src/test/resources/rest/monitoring/TestParticipantStatistics_Invalid.json b/runtime-controlloop/src/test/resources/rest/monitoring/TestParticipantStatistics_Invalid.json
new file mode 100644
index 0000000..7281822
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/monitoring/TestParticipantStatistics_Invalid.json
@@ -0,0 +1,16 @@
+{
+  "participantStatisticsList":[
+    {
+      "participantId":{
+        "name":"name3",
+        "version":"1.001"
+      },
+      "state": "PASSIVE",
+      "eventCount":250,
+      "lastExecutionTime":100,
+      "averageExecutionTime":90,
+      "upTime":1000,
+      "lastStart":3000
+    }
+  ]
+}
\ No newline at end of file
diff --git a/runtime-controlloop/src/test/resources/rest/servicetemplates/PMSHMultipleCLTosca.yaml b/runtime-controlloop/src/test/resources/rest/servicetemplates/PMSHMultipleCLTosca.yaml
new file mode 100644
index 0000000..099e2e9
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/servicetemplates/PMSHMultipleCLTosca.yaml
@@ -0,0 +1,221 @@
+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
+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
+        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:
+      provider:
+        type: string
+        requred: false
+      elements:
+        type: list
+        required: true
+        entry_schema:
+          type: onap.datatypes.ToscaConceptIdentifier
+  org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
+    properties:
+      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:
+  node_templates:
+    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.2.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:
+        provider: Ericsson
+        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:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.2.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:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.2.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:
+        provider: Ericsson
+        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:
+        provider: Ericsson
+        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
+    org.onap.domain.pmsh.PMSD_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:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant
+          version: 2.3.4
+        dcae_blueprint_id:
+          name: org.onap.dcae.blueprints.PMSDBlueprint
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSD_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:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.2.1
+        policy_type_id:
+          name: onap.policies.monitoring.pm-subscription-handler
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSD_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:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.2.1
+        policy_type_id:
+          name: onap.policies.operational.pm-subscription-handler
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSD_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:
+        provider: Ericsson
+        participant_Id:
+          name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant
+          version: 3.2.1
+        cds_blueprint_id:
+          name: org.onap.ccsdk.cds.PMSDCdsBlueprint
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSDControlLoopDefinition:
+      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:
+        provider: Ericsson
+        elements:
+          - name: org.onap.domain.pmsh.PMSD_DCAEMicroservice
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSD_MonitoringPolicyControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSD_OperationalPolicyControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSD_CDS_ControlLoopElement
+            version: 1.2.3
diff --git a/runtime-controlloop/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml b/runtime-controlloop/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml
new file mode 100644
index 0000000..01f825f
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/servicetemplates/pm_control_loop_tosca.yaml
@@ -0,0 +1,452 @@
+tosca_definitions_version: tosca_simple_yaml_1_3
+capability_types:
+  org.onap.EventProducer:
+    properties:
+      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
+      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:
+    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:
+        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:
+    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:
+    properties:
+      event_format:
+        type: string
+        description: 'examples for event_format: Ves_specification, etc.'
+        required: true
+      event_format_version:
+        type: string
+        description: 'examples for event_format_version: 5.28.4, 7.30.1, etc.'
+        required: true
+      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 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:
+    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
+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
+      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
+      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
+      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
+      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
+      properties:
+        application_name: Test Control Loop
+        provider: Ericsson
+        application_version: 1.0.0
+        status: NOT_DEPLOYED
+      version: 0.0.0
+version: 0.0.0
diff --git a/runtime-controlloop/src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml b/runtime-controlloop/src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml
new file mode 100644
index 0000000..099e2e9
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml
@@ -0,0 +1,221 @@
+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
+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
+        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:
+      provider:
+        type: string
+        requred: false
+      elements:
+        type: list
+        required: true
+        entry_schema:
+          type: onap.datatypes.ToscaConceptIdentifier
+  org.onap.policy.clamp.controlloop.DCAEMicroserviceControlLoopElement:
+    version: 1.0.1
+    derived_from: org.onap.policy.clamp.controlloop.ControlLoopElement
+    properties:
+      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:
+  node_templates:
+    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.2.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:
+        provider: Ericsson
+        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:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.2.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:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.2.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:
+        provider: Ericsson
+        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:
+        provider: Ericsson
+        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
+    org.onap.domain.pmsh.PMSD_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:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.dcae.controlloop.DCAEMicroserviceControlLoopParticipant
+          version: 2.3.4
+        dcae_blueprint_id:
+          name: org.onap.dcae.blueprints.PMSDBlueprint
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSD_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:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.2.1
+        policy_type_id:
+          name: onap.policies.monitoring.pm-subscription-handler
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSD_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:
+        provider: Ericsson
+        participant_id:
+          name: org.onap.policy.controlloop.PolicyControlLoopParticipant
+          version: 2.2.1
+        policy_type_id:
+          name: onap.policies.operational.pm-subscription-handler
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSD_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:
+        provider: Ericsson
+        participant_Id:
+          name: org.onap.ccsdk.cds.controlloop.CdsControlLoopParticipant
+          version: 3.2.1
+        cds_blueprint_id:
+          name: org.onap.ccsdk.cds.PMSDCdsBlueprint
+          version: 1.0.0
+    org.onap.domain.pmsh.PMSDControlLoopDefinition:
+      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:
+        provider: Ericsson
+        elements:
+          - name: org.onap.domain.pmsh.PMSD_DCAEMicroservice
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSD_MonitoringPolicyControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSD_OperationalPolicyControlLoopElement
+            version: 1.2.3
+          - name: org.onap.domain.pmsh.PMSD_CDS_ControlLoopElement
+            version: 1.2.3
diff --git a/runtime-controlloop/src/test/resources/testscripts/listenOnTopic.sh b/runtime-controlloop/src/test/resources/testscripts/listenOnTopic.sh
new file mode 100644
index 0000000..5e66177
--- /dev/null
+++ b/runtime-controlloop/src/test/resources/testscripts/listenOnTopic.sh
@@ -0,0 +1,31 @@
+#! /bin/bash
+#  ============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=========================================================
+
+if [ $# -ne 1 ]
+then
+    echo invalid parameters $*, specify a single parameter as the topic to listen on
+    exit 1
+fi
+
+while true
+do
+    curl "http://localhost:3904/events/$1/TEST/1?timeout=60000"
+    echo ""
+done
+