diff options
9 files changed, 640 insertions, 12 deletions
diff --git a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java index 0078f6129..5959586da 100644 --- a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java +++ b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivator.java @@ -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, diff --git a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java index aeabce7a5..e46e66501 100644 --- a/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java +++ b/tosca-controlloop/runtime/src/main/java/org/onap/policy/clamp/controlloop/runtime/monitoring/MonitoringProvider.java @@ -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 index 000000000..888fb1e98 --- /dev/null +++ b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/TestMonitoringProvider.java @@ -0,0 +1,263 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.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 index 000000000..118199a2d --- /dev/null +++ b/tosca-controlloop/runtime/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryControllerTest.java @@ -0,0 +1,237 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.monitoring.rest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.File; +import java.time.Instant; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.core.Response; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatisticsList; +import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider; +import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.StandardCoder; + +public class MonitoringQueryControllerTest extends CommonRestController { + + private static final String CL_PARTICIPANT_STATISTICS_JSON = + "src/test/resources/rest/monitoring/TestParticipantStatistics.json"; + private static final String CL_ELEMENT_STATISTICS_JSON = + "src/test/resources/rest/monitoring/TestClElementStatistics.json"; + + private static final Coder CODER = new StandardCoder(); + + private static ParticipantStatisticsList inputParticipantStatistics; + private static ClElementStatisticsList inputClElementStatistics; + + private static ParticipantStatisticsList participantStatisticsList; + private static ClElementStatisticsList clElementStatisticsList; + + private static final String CLELEMENT_STATS_ENDPOINT = "monitoring/clelement"; + private static final String PARTICIPANT_STATS_ENDPOINT = "monitoring/participant"; + private static final String PARTICIPANT_STATS_PER_CL_ENDPOINT = "monitoring/participants/controlloop"; + private static final String CLELEMENT_STATS_PER_CL_ENDPOINT = "monitoring/clelements/controlloop"; + + + /** + * starts Main. + * + * @throws Exception if an error occurs + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + CommonRestController.setUpBeforeClass("testStatisticsQuery"); + inputParticipantStatistics = CODER.decode(new File(CL_PARTICIPANT_STATISTICS_JSON), + ParticipantStatisticsList.class); + inputClElementStatistics = CODER.decode(new File(CL_ELEMENT_STATISTICS_JSON), + ClElementStatisticsList.class); + + try (MonitoringProvider monitoringProvider = new MonitoringProvider(getParameters())) { + // Insert Participant statistics to DB + participantStatisticsList = monitoringProvider.createParticipantStatistics(inputParticipantStatistics + .getStatisticsList()); + // Insert CL Element statistics to DB + clElementStatisticsList = monitoringProvider.createClElementStatistics(inputClElementStatistics + .getClElementStatistics()); + } + } + + @AfterClass + public static void teardownAfterClass() { + CommonRestController.teardownAfterClass(); + } + + @Test + public void testQuery_Unauthorized_for_ClElementStats() throws Exception { + assertUnauthorizedGet(CLELEMENT_STATS_ENDPOINT); + } + + @Test + public void testQuery_Unauthorized_for_ClParticipantStats() throws Exception { + assertUnauthorizedGet(PARTICIPANT_STATS_ENDPOINT); + } + + @Test + public void testQuery_Unauthorized_for_ParticipantStatsPerCl() throws Exception { + assertUnauthorizedGet(PARTICIPANT_STATS_PER_CL_ENDPOINT); + } + + @Test + public void testQuery_Unauthorized_for_ClElementStatsPerCl() throws Exception { + assertUnauthorizedGet(CLELEMENT_STATS_PER_CL_ENDPOINT); + } + + @Test + public void testSwagger_ClStats() throws Exception { + super.testSwagger(CLELEMENT_STATS_ENDPOINT); + super.testSwagger(PARTICIPANT_STATS_ENDPOINT); + super.testSwagger(CLELEMENT_STATS_PER_CL_ENDPOINT); + super.testSwagger(PARTICIPANT_STATS_PER_CL_ENDPOINT); + } + + @Test + public void testClElementStatisticsEndpoint() throws Exception { + // Filter statistics only based on participant Id and UUID + Invocation.Builder invokeRequest1 = + super.sendRequest(CLELEMENT_STATS_ENDPOINT + "?name=" + clElementStatisticsList + .getClElementStatistics().get(0).getParticipantId().getName() + "&version=" + clElementStatisticsList + .getClElementStatistics().get(0).getParticipantId().getVersion() + "&id=" + clElementStatisticsList + .getClElementStatistics().get(0).getId().toString()); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus()); + + ClElementStatisticsList result1 = response1.readEntity(ClElementStatisticsList.class); + + assertNotNull(result1); + assertThat(result1.getClElementStatistics()).hasSize(2); + assertEquals(result1.getClElementStatistics().get(0), clElementStatisticsList + .getClElementStatistics().get(0)); + + // Filter statistics based on timestamp + Invocation.Builder invokeRequest2 = + super.sendRequest(CLELEMENT_STATS_ENDPOINT + "?name=" + clElementStatisticsList + .getClElementStatistics().get(1).getParticipantId().getName() + "&version=" + clElementStatisticsList + .getClElementStatistics().get(1).getParticipantId().getVersion() + "&startTime=" + + Instant.parse("2021-01-10T13:00:00.000Z") + "&endTime=" + Instant.parse("2021-01-10T14:00:00.000Z")); + Response response2 = invokeRequest2.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response2.getStatus()); + ClElementStatisticsList result2 = response2.readEntity(ClElementStatisticsList.class); + + assertNotNull(result2); + assertThat(result2.getClElementStatistics()).hasSize(1); + assertEquals(result1.getClElementStatistics().get(0), clElementStatisticsList + .getClElementStatistics().get(0)); + } + + @Test + public void testClElementStats_BadRequest() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(CLELEMENT_STATS_ENDPOINT + "?version=1.0.0"); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus()); + } + + @Test + public void testParticipantStatisticsEndpoint() throws Exception { + + // Filter statistics only based on participant Id + Invocation.Builder invokeRequest1 = + super.sendRequest(PARTICIPANT_STATS_ENDPOINT + "?name=" + participantStatisticsList + .getStatisticsList().get(0).getParticipantId().getName() + "&version=" + participantStatisticsList + .getStatisticsList().get(0).getParticipantId().getVersion()); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus()); + ParticipantStatisticsList result1 = response1.readEntity(ParticipantStatisticsList.class); + + assertNotNull(result1); + assertThat(result1.getStatisticsList()).hasSize(2); + assertEquals(result1.getStatisticsList().get(0), participantStatisticsList + .getStatisticsList().get(0)); + + // Filter statistics based on timestamp + Invocation.Builder invokeRequest2 = + super.sendRequest(PARTICIPANT_STATS_ENDPOINT + "?name=" + participantStatisticsList + .getStatisticsList().get(1).getParticipantId().getName() + "&version=" + participantStatisticsList + .getStatisticsList().get(1).getParticipantId().getVersion() + "&startTime=" + + Instant.parse("2021-01-10T13:00:00.000Z") + "&endTime=" + Instant.parse("2021-01-10T14:00:00.000Z")); + Response response2 = invokeRequest2.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response2.getStatus()); + ParticipantStatisticsList result2 = response2.readEntity(ParticipantStatisticsList.class); + + assertNotNull(result2); + assertThat(result2.getStatisticsList()).hasSize(1); + assertEquals(result1.getStatisticsList().get(0), participantStatisticsList + .getStatisticsList().get(0)); + } + + @Test + public void testParticipantStats_BadRequest() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(PARTICIPANT_STATS_ENDPOINT + "?version=0.0"); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus()); + } + + @Test + public void testParticipantStatsPerClEndpoint() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(PARTICIPANT_STATS_PER_CL_ENDPOINT + "?name=dummyName&version=1.001"); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus()); + ParticipantStatisticsList result1 = response1.readEntity(ParticipantStatisticsList.class); + assertThat(result1.getStatisticsList()).isEmpty(); + } + + @Test + public void testParticipantStatsPerCl_BadRequest() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(PARTICIPANT_STATS_PER_CL_ENDPOINT); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus()); + } + + @Test + public void testClElementStatisticsPerClEndpoint() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(CLELEMENT_STATS_PER_CL_ENDPOINT + "?name=dummyName&version=1.001"); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus()); + ClElementStatisticsList result1 = response1.readEntity(ClElementStatisticsList.class); + assertThat(result1.getClElementStatistics()).isEmpty(); + } + + @Test + public void testClElementStatsPerCl_BadRequest() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(CLELEMENT_STATS_PER_CL_ENDPOINT); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus()); + } +} diff --git a/tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml b/tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml index 610bfe97e..5df575c22 100644 --- a/tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml +++ b/tosca-controlloop/runtime/src/test/resources/META-INF/persistence.xml @@ -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 index 000000000..21a048ff0 --- /dev/null +++ b/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestClElementStatistics.json @@ -0,0 +1,44 @@ +{ + "clElementStatistics":[ + { + "participantId":{ + "name":"name1", + "version":"1.001" + }, + "id": "709c62b3-8918-41b9-a747-d21eb79c6c20", + "timeStamp": "2021-01-10T13:45:00.000Z", + "controlLoopState": "UNINITIALISED", + "clElementUptime":250 + }, + { + "participantId":{ + "name":"name1", + "version":"1.001" + }, + "id": "709c62b3-8918-41b9-a747-d21eb79c6c20", + "timeStamp": "2021-01-10T15:45:00.000Z", + "controlLoopState": "UNINITIALISED", + "clElementUptime":450 + }, + { + "participantId":{ + "name":"name2", + "version":"1.001" + }, + "id": "709c62b3-8918-41b9-a747-d21eb79c6c21", + "timeStamp": "2021-01-10T14:25:00.000Z", + "controlLoopState": "UNINITIALISED", + "clElementUptime":330 + }, + { + "participantId":{ + "name":"name2", + "version":"1.001" + }, + "id": "709c62b3-8918-41b9-a747-d21eb79c6c21", + "timeStamp": "2021-01-10T16:35:00.000Z", + "controlLoopState": "UNINITIALISED", + "clElementUptime":650 + } + ] +}
\ No newline at end of file diff --git a/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 index 000000000..2cf2619bf --- /dev/null +++ b/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestClElementStatistics_Invalid.json @@ -0,0 +1,13 @@ +{ + "clElementStatisticsList":[ + { + "participantId":{ + "name":"name1", + "version":"1.001" + }, + "id": "709c62b3-8918-41b9-a747-d21eb79c6c20", + "controlLoopState": "UNINITIALISED", + "clElementUptime":250 + } + ] +}
\ No newline at end of file diff --git a/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 index 000000000..acd88e24b --- /dev/null +++ b/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestParticipantStatistics.json @@ -0,0 +1,46 @@ +{ + "statisticsList":[ + { + "participantId":{ + "name":"name1", + "version":"1.001" + }, + "timeStamp": "2021-01-10T13:45:00.000Z", + "state": "PASSIVE", + "healthStatus": "HEALTHY", + "eventCount":250, + "lastExecutionTime":100, + "averageExecutionTime":90, + "upTime":1000, + "lastStart":3000 + }, + { + "participantId":{ + "name":"name1", + "version":"1.001" + }, + "timeStamp": "2021-01-10T15:45:00.000Z", + "state": "PASSIVE", + "healthStatus": "HEALTHY", + "eventCount":262, + "lastExecutionTime":100, + "averageExecutionTime":90, + "upTime":2000, + "lastStart":3000 + }, + { + "participantId":{ + "name":"name2", + "version":"1.001" + }, + "timeStamp": "2021-01-27T14:25:00.000Z", + "state": "PASSIVE", + "healthStatus": "HEALTHY", + "eventCount":245, + "lastExecutionTime":1020, + "averageExecutionTime":85, + "upTime":1050, + "lastStart":3100 + } + ] +}
\ No newline at end of file diff --git a/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 index 000000000..7281822f0 --- /dev/null +++ b/tosca-controlloop/runtime/src/test/resources/rest/monitoring/TestParticipantStatistics_Invalid.json @@ -0,0 +1,16 @@ +{ + "participantStatisticsList":[ + { + "participantId":{ + "name":"name3", + "version":"1.001" + }, + "state": "PASSIVE", + "eventCount":250, + "lastExecutionTime":100, + "averageExecutionTime":90, + "upTime":1000, + "lastStart":3000 + } + ] +}
\ No newline at end of file |