Ties monitoring handler into the activator with runtime test classes. 14/119614/3
authorrameshiyer27 <ramesh.murugan.iyer@est.tech>
Tue, 23 Mar 2021 06:10:15 +0000 (06:10 +0000)
committerRamesh Murugan Iyer <ramesh.murugan.iyer@est.tech>
Tue, 23 Mar 2021 15:10:13 +0000 (15:10 +0000)
Issue-ID: POLICY-3051
Signed-off-by: zrrmmua <ramesh.murugan.iyer@est.tech>
Change-Id: I5b651a6a9d4605cabcb0a0b6db2ad4820160415e

tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java
tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java
tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/TestMonitoringProvider.java [new file with mode: 0644]
tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryControllerTest.java [new file with mode: 0644]
tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml
tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestClElementStatistics.json [new file with mode: 0644]
tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestClElementStatistics_Invalid.json [new file with mode: 0644]
tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestParticipantStatistics.json [new file with mode: 0644]
tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestParticipantStatistics_Invalid.json [new file with mode: 0644]

index 0078f61..5959586 100644 (file)
@@ -31,6 +31,7 @@ import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningHand
 import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationHandler;
 import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup;
 import org.onap.policy.clamp.controlloop.runtime.main.rest.ControlLoopAafFilter;
+import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringHandler;
 import org.onap.policy.common.endpoints.event.comm.TopicEndpointManager;
 import org.onap.policy.common.endpoints.event.comm.TopicSink;
 import org.onap.policy.common.endpoints.event.comm.TopicSource;
@@ -85,6 +86,7 @@ public class ClRuntimeActivator extends ServiceManagerContainer {
 
         final AtomicReference<ControlLoopHandler> commissioningHandler = new AtomicReference<>();
         final AtomicReference<ControlLoopHandler> instantiationHandler = new AtomicReference<>();
+        final AtomicReference<ControlLoopHandler> monitoringHandler = new AtomicReference<>();
 
         final AtomicReference<RestServer> restServer = new AtomicReference<>();
         // @formatter:off
@@ -100,9 +102,13 @@ public class ClRuntimeActivator extends ServiceManagerContainer {
         addAction("Instantiation Handler",
                 () -> instantiationHandler.set(new InstantiationHandler(clRuntimeParameterGroup)),
                 () -> instantiationHandler.get().close());
+        addAction("Monitoring Handler",
+            () -> monitoringHandler.set(new MonitoringHandler(clRuntimeParameterGroup)),
+            () -> monitoringHandler.get().close());
 
         addHandlerActions("Commissioning", commissioningHandler);
         addHandlerActions("Instantiation", instantiationHandler);
+        addHandlerActions("Monitoring", monitoringHandler);
 
         addAction("Topic Message Dispatcher", this::registerMsgDispatcher, this::unregisterMsgDispatcher);
 
@@ -113,6 +119,7 @@ public class ClRuntimeActivator extends ServiceManagerContainer {
                     Set<Class<?>> providerClasses = new HashSet<>();
                     providerClasses.addAll(commissioningHandler.get().getProviderClasses());
                     providerClasses.addAll(instantiationHandler.get().getProviderClasses());
+                    providerClasses.addAll(monitoringHandler.get().getProviderClasses());
 
                     RestServer server = new RestServer(clRuntimeParameterGroup.getRestServerParameters(),
                             ControlLoopAafFilter.class,
index aeabce7..e46e665 100644 (file)
@@ -205,19 +205,19 @@ public class MonitoringProvider implements Closeable {
             //Fetch all control loop elements for the control loop
             ControlLoop controlLoop = controlLoopProvider.getControlLoop(new ToscaConceptIdentifier(name,
                 version));
-            clElements.addAll(controlLoop.getElements());
-
-            //Collect control loop element statistics for each cl element.
-            for (ControlLoopElement clElement : clElements) {
-                clElementStats.addAll(fetchFilteredClElementStatistics(clElement.getParticipantId().getName(),
-                    clElement.getParticipantId().getVersion(), clElement.getId().toString(), null,
-                    null, 0).getClElementStatistics());
+            if (controlLoop != null) {
+                clElements.addAll(controlLoop.getElements());
+                //Collect control loop element statistics for each cl element.
+                for (ControlLoopElement clElement : clElements) {
+                    clElementStats.addAll(fetchFilteredClElementStatistics(clElement.getParticipantId().getName(),
+                        clElement.getParticipantId().getVersion(), clElement.getId().toString(), null,
+                        null, 0).getClElementStatistics());
+                }
             }
             clElementStatisticsList.setClElementStatistics(clElementStats);
         } catch (PfModelException e) {
             throw new PfModelRuntimeException(e);
         }
-
         return clElementStatisticsList;
     }
 
@@ -255,14 +255,14 @@ public class MonitoringProvider implements Closeable {
         throws PfModelException {
         Map<String, ToscaConceptIdentifier> clElementId = new HashMap<>();
         ControlLoop controlLoop = controlLoopProvider.getControlLoop(new ToscaConceptIdentifier(name, version));
-        for (ControlLoopElement clElement : controlLoop.getElements()) {
-            clElementId.put(clElement.getId().toString(), clElement.getParticipantId());
+        if (controlLoop != null) {
+            for (ControlLoopElement clElement : controlLoop.getElements()) {
+                clElementId.put(clElement.getId().toString(), clElement.getParticipantId());
+            }
         }
         return clElementId;
     }
 
-
-
     public void updateClElementStatistics(List<ClElementStatistics> clElementStatistics) {
         // TODO Auto-generated method stub
     }
diff --git a/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/TestMonitoringProvider.java b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/TestMonitoringProvider.java
new file mode 100644 (file)
index 0000000..888fb1e
--- /dev/null
@@ -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.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.Arrays;
+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(Arrays.asList(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/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryControllerTest.java b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryControllerTest.java
new file mode 100644 (file)
index 0000000..118199a
--- /dev/null
@@ -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());
+    }
+}
index 610bfe9..5df575c 100644 (file)
@@ -46,6 +46,8 @@
         <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.ddl-generation" value="drop-and-create-tables" />
diff --git a/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestClElementStatistics.json b/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestClElementStatistics.json
new file mode 100644 (file)
index 0000000..21a048f
--- /dev/null
@@ -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/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestClElementStatistics_Invalid.json b/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestClElementStatistics_Invalid.json
new file mode 100644 (file)
index 0000000..2cf2619
--- /dev/null
@@ -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/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestParticipantStatistics.json b/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestParticipantStatistics.json
new file mode 100644 (file)
index 0000000..acd88e2
--- /dev/null
@@ -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/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestParticipantStatistics_Invalid.json b/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestParticipantStatistics_Invalid.json
new file mode 100644 (file)
index 0000000..7281822
--- /dev/null
@@ -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