Add Instantiation Provider 74/118474/6
authorFrancescoFioraEst <francesco.fiora@est.tech>
Wed, 24 Feb 2021 11:51:58 +0000 (11:51 +0000)
committerFrancescoFioraEst <francesco.fiora@est.tech>
Mon, 1 Mar 2021 17:47:20 +0000 (17:47 +0000)
Issue-ID: POLICY-2980
Signed-off-by: FrancescoFioraEst <francesco.fiora@est.tech>
Change-Id: I957f947ece23fbd5f1745e18f909754c5945f465

tosca-controlloop/models/src/main/java/org/onap/policy/clamp/controlloop/models/controlloop/concepts/ControlLoops.java
tosca-controlloop/runtime/pom.xml
tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java [new file with mode: 0644]
tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java [new file with mode: 0644]
tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java [new file with mode: 0644]
tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java [new file with mode: 0644]
tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml [new file with mode: 0644]
tosca-controlloop/runtime/src/test/resources/parameters/ConfigParametersStd.json [new file with mode: 0644]
tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoops.json [new file with mode: 0644]
tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsUpdate.json [new file with mode: 0644]
tosca-controlloop/runtime/src/test/resources/rest/controlloops/PassiveCommand.json [new file with mode: 0644]

index 7fb6a1a..3a5ab59 100644 (file)
@@ -20,6 +20,7 @@ package org.onap.policy.clamp.controlloop.models.controlloop.concepts;
 
 import java.util.List;
 import lombok.AllArgsConstructor;
+import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.NoArgsConstructor;
 import lombok.Setter;
@@ -30,6 +31,7 @@ import lombok.ToString;
 @ToString
 @NoArgsConstructor
 @AllArgsConstructor
+@EqualsAndHashCode
 public class ControlLoops {
     private List<ControlLoop> controlLoopList;
 }
index e3811bb..5519f61 100644 (file)
             <artifactId>controlloop-common</artifactId>
             <version>${project.version}</version>
         </dependency>
+      <dependency>
+            <groupId>org.onap.policy.clamp.controlloop</groupId>
+            <artifactId>controlloop-models</artifactId>
+            <version>${project.version}</version>
+        </dependency>
     </dependencies>
 </project>
diff --git a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProvider.java
new file mode 100644 (file)
index 0000000..7586a69
--- /dev/null
@@ -0,0 +1,188 @@
+/*-
+ * ============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 java.io.Closeable;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+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.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.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;
+
+/**
+ * This class is dedicated to the Instantiation of Commissioned control loop.
+ */
+public class ControlLoopInstantiationProvider implements Closeable {
+    private final ControlLoopProvider controlLoopProvider;
+
+    private static final Object lockit = new Object();
+
+    /**
+     * Create a instantiation provider.
+     *
+     * @param databaseProviderParameters the parameters for database access
+     */
+    public ControlLoopInstantiationProvider(PolicyModelsProviderParameters databaseProviderParameters) {
+        try {
+            controlLoopProvider = new ControlLoopProvider(databaseProviderParameters);
+        } catch (PfModelException e) {
+            throw new PfModelRuntimeException(e);
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        controlLoopProvider.close();
+    }
+
+    /**
+     * Create control loops.
+     *
+     * @param controlLoops the control loop
+     * @return the result of the instantiation operation
+     * @throws PfModelException on creation errors
+     */
+    public InstantiationResponse createControlLoops(ControlLoops controlLoops) throws PfModelException {
+
+        synchronized (lockit) {
+            for (ControlLoop controlLoop : controlLoops.getControlLoopList()) {
+                ControlLoop checkControlLoop = controlLoopProvider.getControlLoop(controlLoop.getKey().asIdentifier());
+                if (checkControlLoop != null) {
+                    throw new PfModelException(Response.Status.BAD_REQUEST,
+                            controlLoop.getKey().asIdentifier() + " already defined");
+                }
+            }
+            controlLoopProvider.createControlLoops(controlLoops.getControlLoopList());
+        }
+
+        InstantiationResponse response = new InstantiationResponse();
+        response.setAffectedControlLoops(controlLoops.getControlLoopList().stream()
+                .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList()));
+
+        return response;
+    }
+
+    /**
+     * Update control loops.
+     *
+     * @param controlLoops the control loop
+     * @return the result of the instantiation operation
+     * @throws PfModelException on update errors
+     */
+    public InstantiationResponse updateControlLoops(ControlLoops controlLoops) throws PfModelException {
+        synchronized (lockit) {
+            controlLoopProvider.updateControlLoops(controlLoops.getControlLoopList());
+        }
+
+        InstantiationResponse response = new InstantiationResponse();
+        response.setAffectedControlLoops(controlLoops.getControlLoopList().stream()
+                .map(cl -> cl.getKey().asIdentifier()).collect(Collectors.toList()));
+
+        return response;
+    }
+
+    /**
+     * Delete the control loop with the given name and version.
+     *
+     * @param name the name of the control loop to delete
+     * @param version the version of the control loop to delete
+     * @return the result of the deletion
+     * @throws PfModelException on deletion errors
+     */
+    public InstantiationResponse deleteControlLoop(String name, String version) throws PfModelException {
+        InstantiationResponse response = new InstantiationResponse();
+        synchronized (lockit) {
+            List<ControlLoop> controlLoops = controlLoopProvider.getControlLoops(name, version);
+            if (controlLoops.isEmpty()) {
+                throw new PfModelException(Response.Status.NOT_FOUND, "Control Loop not found");
+            }
+            for (ControlLoop controlLoop : controlLoops) {
+                if (!ControlLoopState.UNINITIALISED.equals(controlLoop.getState())) {
+                    throw new PfModelException(Response.Status.BAD_REQUEST,
+                            "Control Loop State is still " + controlLoop.getState());
+                }
+            }
+
+            response.setAffectedControlLoops(Collections
+                    .singletonList(controlLoopProvider.deleteControlLoop(name, version).getKey().asIdentifier()));
+        }
+        return response;
+    }
+
+    /**
+     * Get the requested control loops.
+     *
+     * @param name the name of the control loop to get, null for all control loops
+     * @param version the version of the control loop to get, null for all control loops
+     * @return the control loops
+     * @throws PfModelException on errors getting control loops
+     */
+    public ControlLoops getControlLoops(String name, String version) throws PfModelException {
+        ControlLoops controlLoops = new ControlLoops();
+        controlLoops.setControlLoopList(controlLoopProvider.getControlLoops(name, version));
+
+        return controlLoops;
+    }
+
+    /**
+     * Issue a command to control loops, setting their ordered state.
+     *
+     * @param command the command to issue to control loops
+     * @return the result of the initiation command
+     * @throws PfModelException on errors setting the ordered state on the control loops
+     * @throws ControlLoopException on ordered state invalid
+     */
+    public InstantiationResponse issueControlLoopCommand(InstantiationCommand command)
+            throws ControlLoopException, PfModelException {
+
+        if (command.getOrderedState() == null) {
+            throw new ControlLoopException(Status.BAD_REQUEST, "ordered state invalid or not specified on command");
+        }
+
+        synchronized (lockit) {
+            List<ControlLoop> controlLoops = new ArrayList<>(command.getControlLoopIdentifierList().size());
+            for (ToscaConceptIdentifier id : command.getControlLoopIdentifierList()) {
+                ControlLoop controlLoop = controlLoopProvider.getControlLoop(id);
+                controlLoop.setCascadedOrderedState(command.getOrderedState());
+                controlLoops.add(controlLoop);
+            }
+            controlLoopProvider.updateControlLoops(controlLoops);
+        }
+
+        InstantiationResponse response = new InstantiationResponse();
+        response.setAffectedControlLoops(command.getControlLoopIdentifierList());
+
+        return response;
+    }
+}
diff --git a/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java
new file mode 100644 (file)
index 0000000..a0940ef
--- /dev/null
@@ -0,0 +1,294 @@
+/*-
+ * ============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 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;
+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.util.CommonTestData;
+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 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 PolicyModelsProviderParameters databaseProviderParameters;
+
+    @BeforeClass
+    public static void setupDbProviderParameters() throws ControlLoopException, PfModelException {
+        databaseProviderParameters =
+                CommonTestData.geParameterGroup(0, "instantproviderdb").getDatabaseProviderParameters();
+    }
+
+    @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)) {
+            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)) {
+
+            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)) {
+            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 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)) {
+            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/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java
new file mode 100644 (file)
index 0000000..a101568
--- /dev/null
@@ -0,0 +1,122 @@
+/*-
+ * ============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.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+/**
+ * Utility methods supporting tests for Instantiation.
+ */
+public class InstantiationUtils {
+
+    private static final Coder CODER = new StandardCoder();
+
+    /**
+     * 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()));
+    }
+}
diff --git a/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java
new file mode 100644 (file)
index 0000000..31d4be4
--- /dev/null
@@ -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/ConfigParametersStd.json")
+                .replace("${port}", String.valueOf(port)).replace("${dbName}", "jdbc:h2:mem:" + dbName);
+    }
+}
diff --git a/tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml b/tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml
new file mode 100644 (file)
index 0000000..ff532fe
--- /dev/null
@@ -0,0 +1,59 @@
+<?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="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>
+
+        <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/tosca-controlloop/runtime/src/test/resources/parameters/ConfigParametersStd.json b/tosca-controlloop/runtime/src/test/resources/parameters/ConfigParametersStd.json
new file mode 100644 (file)
index 0000000..19346a0
--- /dev/null
@@ -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": "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/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoops.json b/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoops.json
new file mode 100644 (file)
index 0000000..94c6a61
--- /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.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.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.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"
+                }
+            ]
+        }
+    ]
+}
diff --git a/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsUpdate.json b/tosca-controlloop/runtime/src/test/resources/rest/controlloops/ControlLoopsUpdate.json
new file mode 100644 (file)
index 0000000..9dce01a
--- /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 1",
+            "elements": [
+                {
+                    "id": "709c62b3-8918-41b9-a747-d21eb79c6c21",
+                    "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-d21eb79c6c22",
+                    "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-d21eb79c6c23",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "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-d21eb79c6c24",
+                    "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-e21eb79c6c25",
+                    "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-e21eb79c6c26",
+                    "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-e21eb79c6c27",
+                    "definition": {
+                        "name": "org.onap.domain.pmsh.PMSH_MonitoringPolicyControlLoopElement",
+                        "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-e21eb79c6c28",
+                    "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/PassiveCommand.json b/tosca-controlloop/runtime/src/test/resources/rest/controlloops/PassiveCommand.json
new file mode 100644 (file)
index 0000000..9c87e43
--- /dev/null
@@ -0,0 +1,13 @@
+{
+    "orderedState": "PASSIVE",
+    "controlLoopIdentifierList": [
+        {
+            "name": "PMSHInstance0",
+            "version": "1.0.1"
+        },
+        {
+            "name": "PMSHInstance1",
+            "version": "1.0.1"
+        }
+    ]
+}