Add validation on create/update Instantiation 18/119318/7
authorFrancescoFioraEst <francesco.fiora@est.tech>
Fri, 12 Mar 2021 09:34:43 +0000 (09:34 +0000)
committerFrancescoFioraEst <francesco.fiora@est.tech>
Thu, 18 Mar 2021 14:29:24 +0000 (14:29 +0000)
Issue-ID: POLICY-2980
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
Change-Id: Iea9c141edfd46e9175061e333ed0f0e42fd8da9f

tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java
tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java
tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java
tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java
tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsElementsNotFound.json [new file with mode: 0644]
tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsNotFound.json [new file with mode: 0644]

index 7586a69..6fd5f32 100644 (file)
@@ -25,26 +25,36 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
+import java.util.function.UnaryOperator;
 import java.util.stream.Collectors;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.Response.Status;
 import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
 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.ControlLoopState;
 import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops;
 import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand;
 import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse;
+import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningProvider;
+import org.onap.policy.common.parameters.BeanValidationResult;
+import org.onap.policy.common.parameters.ObjectValidationResult;
+import org.onap.policy.common.parameters.ValidationResult;
+import org.onap.policy.common.parameters.ValidationStatus;
 import org.onap.policy.models.base.PfModelException;
 import org.onap.policy.models.base.PfModelRuntimeException;
 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;
 
 /**
  * This class is dedicated to the Instantiation of Commissioned control loop.
  */
 public class ControlLoopInstantiationProvider implements Closeable {
     private final ControlLoopProvider controlLoopProvider;
+    private final CommissioningProvider commissioningProvider;
 
     private static final Object lockit = new Object();
 
@@ -56,6 +66,7 @@ public class ControlLoopInstantiationProvider implements Closeable {
     public ControlLoopInstantiationProvider(PolicyModelsProviderParameters databaseProviderParameters) {
         try {
             controlLoopProvider = new ControlLoopProvider(databaseProviderParameters);
+            commissioningProvider = new CommissioningProvider(databaseProviderParameters);
         } catch (PfModelException e) {
             throw new PfModelRuntimeException(e);
         }
@@ -83,6 +94,10 @@ public class ControlLoopInstantiationProvider implements Closeable {
                             controlLoop.getKey().asIdentifier() + " already defined");
                 }
             }
+            BeanValidationResult validationResult = validateControlLoops(controlLoops);
+            if (!validationResult.isValid()) {
+                throw new PfModelException(Response.Status.BAD_REQUEST, validationResult.getResult());
+            }
             controlLoopProvider.createControlLoops(controlLoops.getControlLoopList());
         }
 
@@ -102,6 +117,10 @@ public class ControlLoopInstantiationProvider implements Closeable {
      */
     public InstantiationResponse updateControlLoops(ControlLoops controlLoops) throws PfModelException {
         synchronized (lockit) {
+            BeanValidationResult validationResult = validateControlLoops(controlLoops);
+            if (!validationResult.isValid()) {
+                throw new PfModelException(Response.Status.BAD_REQUEST, validationResult.getResult());
+            }
             controlLoopProvider.updateControlLoops(controlLoops.getControlLoopList());
         }
 
@@ -112,6 +131,71 @@ public class ControlLoopInstantiationProvider implements Closeable {
         return response;
     }
 
+    /**
+     * Validate ControlLoops.
+     *
+     * @param controlLoops ControlLoops to validate
+     * @result the result of validation
+     * @throws PfModelException if controlLoops is not valid
+     */
+    private BeanValidationResult validateControlLoops(ControlLoops controlLoops) throws PfModelException {
+
+        BeanValidationResult validationResult = new BeanValidationResult("ControlLoops", controlLoops);
+
+        for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
+
+            List<ToscaNodeTemplate> toscaNodeTemplates = commissioningProvider.getControlLoopDefinitions(
+                    controlLoop.getDefinition().getName(), controlLoop.getDefinition().getVersion());
+
+            if (toscaNodeTemplates.isEmpty()) {
+                validationResult
+                        .addResult(new ObjectValidationResult("ControlLoop", controlLoop.getDefinition().getName(),
+                                ValidationStatus.INVALID, "Commissioned control loop definition not FOUND"));
+            } else if (toscaNodeTemplates.size() > 1) {
+                validationResult
+                        .addResult(new ObjectValidationResult("ControlLoop", controlLoop.getDefinition().getName(),
+                                ValidationStatus.INVALID, "Commissioned control loop definition not VALID"));
+            } else {
+
+                List<ToscaNodeTemplate> clElementDefinitions =
+                        commissioningProvider.getControlLoopElementDefinitions(toscaNodeTemplates.get(0));
+
+                // @formatter:off
+                Map<String, ToscaConceptIdentifier> definitions = clElementDefinitions
+                        .stream()
+                        .map(nodeTemplate -> nodeTemplate.getKey().asIdentifier())
+                        .collect(Collectors.toMap(ToscaConceptIdentifier::getName, UnaryOperator.identity()));
+                // @formatter:on
+
+                for (ControlLoopElement element : controlLoop.getElements()) {
+                    validationResult.addResult(validateDefinition(definitions, element.getDefinition()));
+                }
+            }
+        }
+        return validationResult;
+    }
+
+    /**
+     * Validate ToscaConceptIdentifier, checking if exist in ToscaConceptIdentifiers map.
+     *
+     * @param definitions map of all ToscaConceptIdentifiers
+     * @param definition ToscaConceptIdentifier to validate
+     * @result result the validation result
+     */
+    private ValidationResult validateDefinition(Map<String, ToscaConceptIdentifier> definitions,
+            ToscaConceptIdentifier definition) {
+        BeanValidationResult result = new BeanValidationResult(definition.getName(), definition);
+        ToscaConceptIdentifier identifier = definitions.get(definition.getName());
+        if (identifier == null) {
+            result.setResult(ValidationStatus.INVALID, "Not FOUND");
+        } else if (!identifier.equals(definition)) {
+            result.setResult(ValidationStatus.INVALID, "Version not matching");
+        } else {
+            result.setResult(ValidationStatus.CLEAN);
+        }
+        return (result.isClean() ? null : result);
+    }
+
     /**
      * Delete the control loop with the given name and version.
      *
index a0940ef..0ec8fe3 100644 (file)
@@ -28,7 +28,6 @@ import java.util.ArrayList;
 import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
-import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException;
 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;
@@ -51,15 +50,36 @@ public class ControlLoopInstantiationProviderTest {
             "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/ControlLoopsElementsNotFound.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 = "examples/controlloop/PMSubscriptionHandling.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"
+                    + "  \"org.onap.domain.pmsh.NotExistFirst\" INVALID, Not FOUND\n"
+                    + "  \"org.onap.domain.pmsh.NotExistSecond\" INVALID, Not FOUND\n";
+
+    private static final String CONTROLLOOP_DEFINITION_NOT_FOUND = "\"ControlLoops\" INVALID, item has status INVALID\n"
+            + "  item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
+            + " Commissioned control loop definition not FOUND\n"
+            + "  item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID,"
+            + " Commissioned control loop definition not FOUND\n";
+
     private static PolicyModelsProviderParameters databaseProviderParameters;
 
+    /**
+     * setup Db Provider Parameters.
+     *
+     * @throws PfModelException if an error occurs
+     */
     @BeforeClass
-    public static void setupDbProviderParameters() throws ControlLoopException, PfModelException {
+    public static void setupDbProviderParameters() throws PfModelException {
         databaseProviderParameters =
                 CommonTestData.geParameterGroup(0, "instantproviderdb").getDatabaseProviderParameters();
     }
@@ -74,6 +94,10 @@ public class ControlLoopInstantiationProviderTest {
 
         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);
 
@@ -152,9 +176,12 @@ public class ControlLoopInstantiationProviderTest {
         try (ControlLoopInstantiationProvider instantiationProvider =
                 new ControlLoopInstantiationProvider(databaseProviderParameters)) {
 
-            assertThatThrownBy(() -> {
-                instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion());
-            }).hasMessageMatching(CONTROL_LOOP_NOT_FOUND);
+            // 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);
@@ -189,15 +216,14 @@ public class ControlLoopInstantiationProviderTest {
                 new ControlLoopInstantiationProvider(databaseProviderParameters)) {
 
             instantiationProvider.updateControlLoops(controlLoops);
-            assertThatThrownBy(() -> {
-                instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion());
-            }).hasMessageMatching(String.format(DELETE_BAD_REQUEST, state));
+            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");
 
@@ -206,12 +232,14 @@ public class ControlLoopInstantiationProviderTest {
 
         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(
+            assertThatThrownBy(() -> instantiationProvider.createControlLoops(controlLoopsCreate)).hasMessageMatching(
                     controlLoopsCreate.getControlLoopList().get(0).getKey().asIdentifier() + " already defined");
 
             for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) {
@@ -220,13 +248,44 @@ public class ControlLoopInstantiationProviderTest {
         }
     }
 
+    @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);
+            assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand()))
+                    .hasMessageMatching(ORDERED_STATE_INVALID);
         }
     }
 
@@ -240,6 +299,10 @@ public class ControlLoopInstantiationProviderTest {
 
         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);
 
index a101568..958d91d 100644 (file)
@@ -33,7 +33,14 @@ import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.Inst
 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.
@@ -41,6 +48,7 @@ import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
 public class InstantiationUtils {
 
     private static final Coder CODER = new StandardCoder();
+    private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator();
 
     /**
      * Gets the ControlLoops from Resource.
@@ -119,4 +127,23 @@ public class InstantiationUtils {
         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);
+        }
+    }
 }
index 9244c7a..63d5a52 100644 (file)
@@ -58,6 +58,8 @@ public class InstantiationControllerTest extends CommonRestController {
 
     private static final String INSTANTIATION_COMMAND_ENDPOINT = "instantiation/command";
 
+    private static final String TOSCA_TEMPLATE_YAML = "examples/controlloop/PMSubscriptionHandling.yaml";
+
     /**
      * starts Main and inserts a commissioning template.
      *
@@ -67,6 +69,9 @@ public class InstantiationControllerTest extends CommonRestController {
     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 =
@@ -112,7 +117,7 @@ public class InstantiationControllerTest extends CommonRestController {
     }
 
     @Test
-    public void testComand_Unauthorized() throws Exception {
+    public void testCommand_Unauthorized() throws Exception {
         InstantiationCommand instantiationCommand = InstantiationUtils
                 .getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Unauthorized");
 
@@ -274,14 +279,14 @@ public class InstantiationControllerTest extends CommonRestController {
     }
 
     @Test
-    public void testComand_NotFound1() throws Exception {
+    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 testComand_NotFound2() throws Exception {
+    public void testCommand_NotFound2() throws Exception {
         InstantiationCommand command =
                 InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Command");
         command.setOrderedState(null);
diff --git a/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsElementsNotFound.json b/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsElementsNotFound.json
new file mode 100644 (file)
index 0000000..2c8ca20
--- /dev/null
@@ -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": [
+                {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.NotExistFirst",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "DCAEParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 0 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "PolicyParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c22",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "PolicyParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c23",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "CDSParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "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": [
+                {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c24",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.NotExistSecond",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "DCAEParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 1 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c25",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "PolicyParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c26",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "PolicyParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c27",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "CDSParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 1 control loop"
+                }
+            ]
+        }
+    ]
+}
diff --git a/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsNotFound.json b/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsNotFound.json
new file mode 100644 (file)
index 0000000..2e13c68
--- /dev/null
@@ -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": [
+                {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c20",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "DCAEParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 0 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "PolicyParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c22",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "PolicyParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 0 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c23",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "CDSParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "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": [
+                {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c24",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_DCAEMicroservice",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "DCAEParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "DCAE Control Loop Element for the PMSH instance 1 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c25",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "PolicyParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Monitoring Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c26",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_OperationalPolicyControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "PolicyParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "Operational Policy Control Loop Element for the PMSH instance 1 control loop"
+                },
+                {
+                    "id": "709c62b3-8918-41b9-a747-e21eb79c6c27",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_CDS_ControlLoopElement",
+                        "version": "1.2.3"
+                    },
+                    "participantId": {
+                        "name": "CDSParticipant0",
+                        "version": "1.0.0"
+                    },
+                    "state": "UNINITIALISED",
+                    "orderedState": "UNINITIALISED",
+                    "description": "CDS Control Loop Element for the PMSH instance 1 control loop"
+                }
+            ]
+        }
+    ]
+}