From 20c7487f77d0728d270b2bed34c2c798d17cc12d Mon Sep 17 00:00:00 2001 From: liamfallon Date: Wed, 26 May 2021 11:02:07 +0100 Subject: Transfer tosca-poc onto master This is the third if three commits, this commit makes the content of the master branch the same as the tosca-poc branch. This commit adds the "src" files for TOSCA control loops to the modules in master. Difference between this commit and the current master: ------------------------------------------------------ diff -qr clamp clamp-master |diff_filter.sh Only in clamp/common: src Only in clamp/models: src Files clamp/participant/participant-impl/participant-impl-dcae/pom.xml and clamp-master/participant/participant-impl/participant-impl-dcae/pom.xml differ Only in clamp/participant/participant-impl/participant-impl-dcae: src Only in clamp/participant/participant-impl/participant-impl-policy: src Only in clamp/participant/participant-impl/participant-impl-simulator: src Files clamp/participant/participant-impl/pom.xml and clamp-master/participant/participant-impl/pom.xml differ Only in clamp/participant/participant-intermediary: src Files clamp/participant/pom.xml and clamp-master/participant/pom.xml differ Files clamp/pom.xml and clamp-master/pom.xml differ Files clamp/runtime/pom.xml and clamp-master/runtime/pom.xml differ Only in clamp: runtime-controlloop Difference between this commit and the current tosca-poc branch: ---------------------------------------------------------------- diff -qr clamp clamp-tp |diff_filter.sh Files clamp/INFO.yaml and clamp-tp/INFO.yaml differ Only in clamp/releases: 6.0.1-container.yaml Only in clamp/releases: 6.0.1.yaml Only in clamp/releases: 6.0.2-container.yaml Only in clamp/releases: 6.0.2.yaml Only in clamp/releases: 6.1.0-container.yaml Only in clamp/releases: 6.1.0.yaml Only in clamp/releases: 6.1.1-container.yaml Only in clamp/releases: 6.1.1.yaml Files clamp/runtime/src/main/resources/META-INF/resources/swagger.html and clamp-tp/runtime/src/main/resources/META-INF/resources/swagger.html differ Issue-ID: POLICY-3215 Change-Id: Ica1aa3fe5d6110df2396ea856703102e800fa770 Signed-off-by: liamfallon --- .../commissioning/CommissioningProviderTest.java | 216 ++++++++++++ .../rest/CommissioningControllerTest.java | 202 +++++++++++ .../ControlLoopInstantiationProviderTest.java | 370 +++++++++++++++++++++ .../runtime/instantiation/InstantiationUtils.java | 149 +++++++++ .../rest/InstantiationControllerTest.java | 322 ++++++++++++++++++ .../runtime/main/rest/RestControllerTest.java | 71 ++++ .../main/startstop/ClRuntimeActivatorTest.java | 82 +++++ .../runtime/main/startstop/MainTest.java | 157 +++++++++ .../runtime/monitoring/TestMonitoringProvider.java | 264 +++++++++++++++ .../rest/MonitoringQueryControllerTest.java | 237 +++++++++++++ .../controlloop/runtime/util/CommonTestData.java | 63 ++++ .../runtime/util/rest/CommonRestController.java | 263 +++++++++++++++ 12 files changed, 2396 insertions(+) create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProviderTest.java create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningControllerTest.java create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestControllerTest.java create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivatorTest.java create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/MainTest.java create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/TestMonitoringProvider.java create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryControllerTest.java create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java create mode 100644 runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/rest/CommonRestController.java (limited to 'runtime-controlloop/src/test/java/org') diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProviderTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProviderTest.java new file mode 100644 index 000000000..956b5e911 --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/CommissioningProviderTest.java @@ -0,0 +1,216 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.commissioning; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import org.junit.Before; +import org.junit.Test; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.YamlJsonTranslator; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeType; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +public class CommissioningProviderTest { + private static final String TOSCA_SERVICE_TEMPLATE_YAML = + "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml"; + private static final String TEMPLATE_IS_NULL = ".*serviceTemplate is marked non-null but is null"; + private static final Coder CODER = new StandardCoder(); + private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); + private static int dbNum = 0; + private static final Object lockit = new Object(); + private PolicyModelsProviderParameters databaseProviderParameters; + + private static String getParameterGroupAsString() { + dbNum++; + return ResourceUtils.getResourceAsString("src/test/resources/parameters/TestParameters.json") + .replace("jdbc:h2:mem:testdb", "jdbc:h2:mem:commissioningdb" + dbNum); + } + + /** + * Sets up db provider parameters before each test. + * + * @throws CoderException . + */ + @Before + public void setupDbProviderParameters() throws CoderException { + synchronized (lockit) { + databaseProviderParameters = CODER.decode(getParameterGroupAsString(), ClRuntimeParameterGroup.class) + .getDatabaseProviderParameters(); + } + } + + /** + * Test the fetching of control loop definitions (ToscaServiceTemplates). + * + * @throws Exception . + */ + @Test + public void testGetControlLoopDefinitions() throws Exception { + List listOfTemplates; + + try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) { + ToscaServiceTemplate serviceTemplate = yamlTranslator + .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), + ToscaServiceTemplate.class); + + + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).isEmpty(); + + provider.createControlLoopDefinitions(serviceTemplate); + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).hasSize(2); + + //Test Filtering + listOfTemplates = provider.getControlLoopDefinitions("org.onap.domain.pmsh.PMSHControlLoopDefinition", + "1.2.3"); + assertThat(listOfTemplates).hasSize(1); + for (ToscaNodeTemplate template : listOfTemplates) { + //Other CL elements contain PMSD instead of PMSH in their name + assertFalse(template.getName().contains("PMSD")); + } + + //Test Wrong Name + listOfTemplates = provider.getControlLoopDefinitions("WrongControlLoopName", "0.0.0"); + assertThat(listOfTemplates).isEmpty(); + } + } + + /** + * Test the creation of control loop definitions (ToscaServiceTemplates). + * + * @throws Exception . + */ + @Test + public void testCreateControlLoopDefinitions() throws Exception { + List listOfTemplates; + + try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) { + //Test Service template is null + assertThatThrownBy(() -> provider.createControlLoopDefinitions(null)).hasMessageMatching(TEMPLATE_IS_NULL); + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).isEmpty(); + + ToscaServiceTemplate serviceTemplate = yamlTranslator + .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), + ToscaServiceTemplate.class); + + // Response should return the number of node templates present in the service template + List affectedDefinitions = + provider.createControlLoopDefinitions(serviceTemplate).getAffectedControlLoopDefinitions(); + assertThat(affectedDefinitions).hasSize(13); + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).hasSize(2); + } + } + + /** + * Test the deletion of control loop definitions (ToscaServiceTemplate). + * + * @throws Exception . + */ + @Test + public void testDeleteControlLoopDefinitions() throws Exception { + List listOfTemplates; + + try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) { + ToscaServiceTemplate serviceTemplate = yamlTranslator + .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), + ToscaServiceTemplate.class); + + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).isEmpty(); + + provider.createControlLoopDefinitions(serviceTemplate); + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).hasSize(2); + + provider.deleteControlLoopDefinition(serviceTemplate.getName(), serviceTemplate.getVersion()); + listOfTemplates = provider.getControlLoopDefinitions(null, null); + assertThat(listOfTemplates).isEmpty(); + } + } + + /** + * Test the fetching of control loop element definitions. + * + * @throws Exception . + */ + @Test + public void testGetControlLoopElementDefinitions() throws Exception { + try (CommissioningProvider provider = new CommissioningProvider(databaseProviderParameters)) { + ToscaServiceTemplate serviceTemplate = yamlTranslator + .fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), + ToscaServiceTemplate.class); + + provider.getControlLoopDefinitions(null, null); + + provider.createControlLoopDefinitions(serviceTemplate); + List controlLoopDefinitionList = provider.getControlLoopDefinitions( + "org.onap.domain.pmsh.PMSHControlLoopDefinition", "1.2.3"); + + List controlLoopElementNodeTemplates = + provider.getControlLoopElementDefinitions(controlLoopDefinitionList.get(0)); + + // 4 PMSH control loop elements definitions. + assertThat(controlLoopElementNodeTemplates).hasSize(4); + + List derivedTypes = getDerivedNodeTypes(serviceTemplate); + for (ToscaNodeTemplate template : controlLoopElementNodeTemplates) { + assertTrue(checkNodeType(template, derivedTypes)); + } + } + } + + private boolean checkNodeType(ToscaNodeTemplate template, List derivedNodeTypes) { + String controlLoopElementType = "org.onap.policy.clamp.controlloop.ControlLoopElement"; + for (ToscaNodeType derivedType : derivedNodeTypes) { + if (template.getType().equals(derivedType.getName()) || template.getType().equals(controlLoopElementType)) { + return true; + } + } + return false; + } + + private List getDerivedNodeTypes(ToscaServiceTemplate serviceTemplate) { + String type = "org.onap.policy.clamp.controlloop.ControlLoopElement"; + List nodeTypes = new ArrayList<>(); + for (ToscaNodeType nodeType : serviceTemplate.getNodeTypes().values()) { + if (nodeType.getDerivedFrom().equals(type)) { + nodeTypes.add(nodeType); + } + } + return nodeTypes; + } +} diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningControllerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningControllerTest.java new file mode 100644 index 000000000..4dbb3ea02 --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/commissioning/rest/CommissioningControllerTest.java @@ -0,0 +1,202 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.commissioning.rest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.util.List; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.core.Response; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.policy.clamp.controlloop.models.messages.rest.commissioning.CommissioningResponse; +import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController; +import org.onap.policy.common.utils.coder.YamlJsonTranslator; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.provider.PolicyModelsProvider; +import org.onap.policy.models.provider.PolicyModelsProviderFactory; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +public class CommissioningControllerTest extends CommonRestController { + + private static final String TOSCA_SERVICE_TEMPLATE_YAML = + "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml"; + private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); + private static final String COMMISSIONING_ENDPOINT = "commission"; + private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate(); + + /** + * starts Main and inserts a commissioning template. + * + * @throws Exception if an error occurs + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + CommonRestController.setUpBeforeClass("CommissioningApi"); + + serviceTemplate = yamlTranslator.fromYaml(ResourceUtils.getResourceAsString(TOSCA_SERVICE_TEMPLATE_YAML), + ToscaServiceTemplate.class); + } + + @AfterClass + public static void teardownAfterClass() { + CommonRestController.teardownAfterClass(); + } + + @Test + public void testSwagger() throws Exception { + super.testSwagger(COMMISSIONING_ENDPOINT); + } + + @Test + public void testUnauthorizedCreate() throws Exception { + assertUnauthorizedPost(COMMISSIONING_ENDPOINT, Entity.json(serviceTemplate)); + } + + @Test + public void testUnauthorizedQuery() throws Exception { + assertUnauthorizedGet(COMMISSIONING_ENDPOINT); + } + + @Test + public void testUnauthorizedQueryElements() throws Exception { + assertUnauthorizedGet(COMMISSIONING_ENDPOINT + "/elements"); + } + + @Test + public void testUnauthorizedDelete() throws Exception { + assertUnauthorizedDelete(COMMISSIONING_ENDPOINT); + } + + @Test + public void testCreateBadRequest() throws Exception { + Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT); + Response resp = invocationBuilder.post(Entity.json("NotToscaServiceTempalte")); + + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus()); + CommissioningResponse commissioningResponse = resp.readEntity(CommissioningResponse.class); + assertNotNull(commissioningResponse.getErrorDetails()); + assertNull(commissioningResponse.getAffectedControlLoopDefinitions()); + } + + @Test + public void testCreate() throws Exception { + Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT); + Response resp = invocationBuilder.post(Entity.json(serviceTemplate)); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + CommissioningResponse commissioningResponse = resp.readEntity(CommissioningResponse.class); + + assertNotNull(commissioningResponse); + assertNull(commissioningResponse.getErrorDetails()); + // Response should return the number of node templates present in the service template + assertThat(commissioningResponse.getAffectedControlLoopDefinitions()).hasSize(13); + for (String nodeTemplateName : serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().keySet()) { + assertTrue(commissioningResponse.getAffectedControlLoopDefinitions().stream() + .anyMatch(ac -> ac.getName().equals(nodeTemplateName))); + } + } + + @Test + public void testQuery_NoResultWithThisName() throws Exception { + createEntryInDB(); + + Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "?name=noResultWithThisName"); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + List entityList = rawresp.readEntity(List.class); + assertThat(entityList).isEmpty(); + } + + @Test + public void testQuery() throws Exception { + createEntryInDB(); + + Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + List entityList = rawresp.readEntity(List.class); + assertNotNull(entityList); + assertThat(entityList).hasSize(2); + } + + @Test + public void testQueryElementsBadRequest() throws Exception { + createEntryInDB(); + + //Call get elements with no info + Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "/elements"); + Response resp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.NOT_ACCEPTABLE.getStatusCode(), resp.getStatus()); + } + + @Test + public void testQueryElements() throws Exception { + createEntryInDB(); + + Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "/elements" + + "?name=org.onap.domain.pmsh.PMSHControlLoopDefinition"); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + List entityList = rawresp.readEntity(List.class); + assertNotNull(entityList); + assertThat(entityList).hasSize(4); + } + + @Test + public void testDeleteBadRequest() throws Exception { + createEntryInDB(); + + Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT); + //Call delete with no info + Response resp = invocationBuilder.delete(); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), resp.getStatus()); + } + + @Test + public void testDelete() throws Exception { + createEntryInDB(); + + Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "?name=" + + serviceTemplate.getName() + "&version=" + serviceTemplate.getVersion()); + //Call delete with no info + Response resp = invocationBuilder.delete(); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + + try (PolicyModelsProvider modelsProvider = new PolicyModelsProviderFactory() + .createPolicyModelsProvider(CommonRestController.getParameters())) { + List templatesInDB = modelsProvider.getServiceTemplateList(null, null); + assertThat(templatesInDB).isEmpty(); + } + } + + private synchronized void createEntryInDB() throws Exception { + try (PolicyModelsProvider modelsProvider = new PolicyModelsProviderFactory() + .createPolicyModelsProvider(CommonRestController.getParameters())) { + modelsProvider.createServiceTemplate(serviceTemplate); + } + } +} diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java new file mode 100644 index 000000000..ccc54b93f --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/ControlLoopInstantiationProviderTest.java @@ -0,0 +1,370 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.instantiation; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mockito; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopState; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; +import org.onap.policy.clamp.controlloop.runtime.commissioning.CommissioningHandler; +import org.onap.policy.clamp.controlloop.runtime.supervision.SupervisionHandler; +import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData; +import org.onap.policy.common.endpoints.event.comm.TopicSink; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Class to perform unit test of {@link ControlLoopInstantiationProvider}}. + * + */ +public class ControlLoopInstantiationProviderTest { + + private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json"; + private static final String CL_INSTANTIATION_UPDATE_JSON = + "src/test/resources/rest/controlloops/ControlLoopsUpdate.json"; + private static final String CL_INSTANTIATION_CHANGE_STATE_JSON = + "src/test/resources/rest/controlloops/PassiveCommand.json"; + private static final String CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON = + "src/test/resources/rest/controlloops/ControlLoopElementsNotFound.json"; + private static final String CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON = + "src/test/resources/rest/controlloops/ControlLoopsNotFound.json"; + private static final String TOSCA_TEMPLATE_YAML = + "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml"; + private static final String CONTROL_LOOP_NOT_FOUND = "Control Loop not found"; + private static final String DELETE_BAD_REQUEST = "Control Loop State is still %s"; + private static final String ORDERED_STATE_INVALID = "ordered state invalid or not specified on command"; + private static final String CONTROLLOOP_ELEMENT_NAME_NOT_FOUND = + "\"ControlLoops\" INVALID, item has status INVALID\n" + + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n" + + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n" + + " \"entry org.onap.domain.pmsh.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n" + + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not FOUND\n"; + + private static final String CONTROLLOOP_DEFINITION_NOT_FOUND = "\"ControlLoops\" INVALID, item has status INVALID\n" + + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n" + + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID," + + " Commissioned control loop definition not FOUND\n" + + " \"entry org.onap.domain.PMSHControlLoopDefinition\" INVALID, item has status INVALID\n" + + " item \"ControlLoop\" value \"org.onap.domain.PMSHControlLoopDefinition\" INVALID," + + " Commissioned control loop definition not FOUND\n"; + + private static PolicyModelsProviderParameters databaseProviderParameters; + private static SupervisionHandler supervisionHandler; + private static CommissioningHandler commissioningHandler; + + /** + * setup Db Provider Parameters. + * + * @throws PfModelException if an error occurs + */ + @BeforeClass + public static void setupDbProviderParameters() throws PfModelException { + databaseProviderParameters = + CommonTestData.geParameterGroup(0, "instantproviderdb").getDatabaseProviderParameters(); + commissioningHandler = new CommissioningHandler(CommonTestData.geParameterGroup(0, "instantproviderdb")); + commissioningHandler.startProviders(); + supervisionHandler = new SupervisionHandler(CommonTestData.geParameterGroup(0, "instantproviderdb")); + supervisionHandler.startProviders(); + supervisionHandler.startAndRegisterPublishers(Collections.singletonList(Mockito.mock(TopicSink.class))); + } + + @Test + public void testInstantiationCrud() throws Exception { + ControlLoops controlLoopsCreate = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Crud"); + ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate); + assertThat(controlLoopsDb.getControlLoopList()).isEmpty(); + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(databaseProviderParameters)) { + + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters); + + InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate); + InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate); + + controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate); + assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty(); + Assert.assertEquals(controlLoopsCreate, controlLoopsDb); + + for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) { + ControlLoops controlLoopsGet = + instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion()); + assertThat(controlLoopsGet.getControlLoopList()).hasSize(1); + Assert.assertEquals(controlLoop, controlLoopsGet.getControlLoopList().get(0)); + } + + ControlLoops controlLoopsUpdate = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Crud"); + Assert.assertNotEquals(controlLoopsUpdate, controlLoopsDb); + + instantiationResponse = instantiationProvider.updateControlLoops(controlLoopsUpdate); + InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsUpdate); + + controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate); + assertThat(controlLoopsDb.getControlLoopList()).isNotEmpty(); + Assert.assertEquals(controlLoopsUpdate, controlLoopsDb); + + InstantiationCommand instantiationCommand = + InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Crud"); + instantiationResponse = instantiationProvider.issueControlLoopCommand(instantiationCommand); + InstantiationUtils.assertInstantiationResponse(instantiationResponse, instantiationCommand); + + for (ToscaConceptIdentifier toscaConceptIdentifier : instantiationCommand.getControlLoopIdentifierList()) { + ControlLoops controlLoopsGet = instantiationProvider.getControlLoops(toscaConceptIdentifier.getName(), + toscaConceptIdentifier.getVersion()); + assertThat(controlLoopsGet.getControlLoopList()).hasSize(1); + Assert.assertEquals(instantiationCommand.getOrderedState(), + controlLoopsGet.getControlLoopList().get(0).getOrderedState()); + } + + // in order to delete a controlLoop the state must be UNINITIALISED + controlLoopsCreate.getControlLoopList().forEach(cl -> cl.setState(ControlLoopState.UNINITIALISED)); + instantiationProvider.updateControlLoops(controlLoopsCreate); + + for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) { + instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()); + } + + controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate); + assertThat(controlLoopsDb.getControlLoopList()).isEmpty(); + } + } + + private ControlLoops getControlLoopsFromDb(ControlLoops controlLoopsSource) throws Exception { + ControlLoops controlLoopsDb = new ControlLoops(); + controlLoopsDb.setControlLoopList(new ArrayList<>()); + + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(databaseProviderParameters)) { + + for (ControlLoop controlLoop : controlLoopsSource.getControlLoopList()) { + ControlLoops controlLoopsFromDb = + instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion()); + controlLoopsDb.getControlLoopList().addAll(controlLoopsFromDb.getControlLoopList()); + } + return controlLoopsDb; + } + } + + @Test + public void testInstantiationDelete() throws Exception { + ControlLoops controlLoops = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Delete"); + assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty(); + + ControlLoop controlLoop0 = controlLoops.getControlLoopList().get(0); + + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(databaseProviderParameters)) { + + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters); + + assertThatThrownBy( + () -> instantiationProvider.deleteControlLoop(controlLoop0.getName(), controlLoop0.getVersion())) + .hasMessageMatching(CONTROL_LOOP_NOT_FOUND); + + InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoops), + controlLoops); + + for (ControlLoopState state : ControlLoopState.values()) { + if (!ControlLoopState.UNINITIALISED.equals(state)) { + assertThatDeleteThrownBy(controlLoops, state); + } + } + + controlLoop0.setState(ControlLoopState.UNINITIALISED); + instantiationProvider.updateControlLoops(controlLoops); + + for (ControlLoop controlLoop : controlLoops.getControlLoopList()) { + instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()); + } + + for (ControlLoop controlLoop : controlLoops.getControlLoopList()) { + ControlLoops controlLoopsGet = + instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion()); + assertThat(controlLoopsGet.getControlLoopList()).isEmpty(); + } + } + } + + private void assertThatDeleteThrownBy(ControlLoops controlLoops, ControlLoopState state) throws Exception { + ControlLoop controlLoop = controlLoops.getControlLoopList().get(0); + + controlLoop.setState(state); + + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(databaseProviderParameters)) { + + instantiationProvider.updateControlLoops(controlLoops); + assertThatThrownBy( + () -> instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion())) + .hasMessageMatching(String.format(DELETE_BAD_REQUEST, state)); + } + } + + @Test + public void testCreateControlLoops_NoDuplicates() throws Exception { + ControlLoops controlLoopsCreate = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "NoDuplicates"); + + ControlLoops controlLoopsDb = getControlLoopsFromDb(controlLoopsCreate); + assertThat(controlLoopsDb.getControlLoopList()).isEmpty(); + + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(databaseProviderParameters)) { + + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters); + + InstantiationResponse instantiationResponse = instantiationProvider.createControlLoops(controlLoopsCreate); + InstantiationUtils.assertInstantiationResponse(instantiationResponse, controlLoopsCreate); + + assertThatThrownBy(() -> instantiationProvider.createControlLoops(controlLoopsCreate)).hasMessageMatching( + controlLoopsCreate.getControlLoopList().get(0).getKey().asIdentifier() + " already defined"); + + for (ControlLoop controlLoop : controlLoopsCreate.getControlLoopList()) { + instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()); + } + } + } + + @Test + public void testCreateControlLoops_CommissionedClElementNotFound() throws Exception { + ControlLoops controlLoops = InstantiationUtils + .getControlLoopsFromResource(CL_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "ClElementNotFound"); + + try (ControlLoopInstantiationProvider provider = + new ControlLoopInstantiationProvider(databaseProviderParameters)) { + + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters); + + assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty(); + + assertThatThrownBy(() -> provider.createControlLoops(controlLoops)) + .hasMessageMatching(CONTROLLOOP_ELEMENT_NAME_NOT_FOUND); + } + } + + @Test + public void testCreateControlLoops_CommissionedClNotFound() throws Exception { + ControlLoops controlLoops = InstantiationUtils + .getControlLoopsFromResource(CL_INSTANTIATION_CONTROLLOOP_DEFINITION_NOT_FOUND_JSON, "ClNotFound"); + + assertThat(getControlLoopsFromDb(controlLoops).getControlLoopList()).isEmpty(); + + try (ControlLoopInstantiationProvider provider = + new ControlLoopInstantiationProvider(databaseProviderParameters)) { + assertThatThrownBy(() -> provider.createControlLoops(controlLoops)) + .hasMessageMatching(CONTROLLOOP_DEFINITION_NOT_FOUND); + } + } + + @Test + public void testIssueControlLoopCommand_OrderedStateInvalid() throws ControlLoopRuntimeException, IOException { + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(databaseProviderParameters)) { + assertThatThrownBy(() -> instantiationProvider.issueControlLoopCommand(new InstantiationCommand())) + .hasMessageMatching(ORDERED_STATE_INVALID); + } + } + + @Test + public void testInstantiationVersions() throws Exception { + + // create controlLoops V1 + ControlLoops controlLoopsV1 = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V1"); + assertThat(getControlLoopsFromDb(controlLoopsV1).getControlLoopList()).isEmpty(); + + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(databaseProviderParameters)) { + + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, databaseProviderParameters); + + InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV1), + controlLoopsV1); + + // create controlLoops V2 + ControlLoops controlLoopsV2 = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "V2"); + assertThat(getControlLoopsFromDb(controlLoopsV2).getControlLoopList()).isEmpty(); + InstantiationUtils.assertInstantiationResponse(instantiationProvider.createControlLoops(controlLoopsV2), + controlLoopsV2); + + // GET controlLoops V2 + for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) { + ControlLoops controlLoopsGet = + instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion()); + assertThat(controlLoopsGet.getControlLoopList()).hasSize(1); + Assert.assertEquals(controlLoop, controlLoopsGet.getControlLoopList().get(0)); + } + + // DELETE controlLoops V1 + for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) { + instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()); + } + + // GET controlLoops V1 is not available + for (ControlLoop controlLoop : controlLoopsV1.getControlLoopList()) { + ControlLoops controlLoopsGet = + instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion()); + assertThat(controlLoopsGet.getControlLoopList()).isEmpty(); + } + + // GET controlLoops V2 is still available + for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) { + ControlLoops controlLoopsGet = + instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion()); + assertThat(controlLoopsGet.getControlLoopList()).hasSize(1); + Assert.assertEquals(controlLoop, controlLoopsGet.getControlLoopList().get(0)); + } + + // DELETE controlLoops V2 + for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) { + instantiationProvider.deleteControlLoop(controlLoop.getName(), controlLoop.getVersion()); + } + + // GET controlLoops V2 is not available + for (ControlLoop controlLoop : controlLoopsV2.getControlLoopList()) { + ControlLoops controlLoopsGet = + instantiationProvider.getControlLoops(controlLoop.getName(), controlLoop.getVersion()); + assertThat(controlLoopsGet.getControlLoopList()).isEmpty(); + } + } + } +} diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java new file mode 100644 index 000000000..958d91dff --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/InstantiationUtils.java @@ -0,0 +1,149 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.instantiation; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import org.junit.Assert; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.coder.YamlJsonTranslator; +import org.onap.policy.common.utils.resources.ResourceUtils; +import org.onap.policy.models.base.PfModelException; +import org.onap.policy.models.provider.PolicyModelsProvider; +import org.onap.policy.models.provider.PolicyModelsProviderFactory; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; + +/** + * Utility methods supporting tests for Instantiation. + */ +public class InstantiationUtils { + + private static final Coder CODER = new StandardCoder(); + private static final YamlJsonTranslator yamlTranslator = new YamlJsonTranslator(); + + /** + * Gets the ControlLoops from Resource. + * + * @param path path of the resource + * @param suffix suffix to add to all names in ControlLoops + * @return the ControlLoops from Resource + * @throws CoderException if an error occurs + */ + public static ControlLoops getControlLoopsFromResource(final String path, final String suffix) + throws CoderException { + ControlLoops controlLoops = CODER.decode(new File(path), ControlLoops.class); + + // add suffix to all names + controlLoops.getControlLoopList().forEach(controlLoop -> controlLoop.setName(controlLoop.getName() + suffix)); + return controlLoops; + } + + /** + * Gets InstantiationCommand from Resource. + * + * @param path path of the resource + * @param suffix suffix to add to all names in ControlLoops + * @return the InstantiationCommand + * @throws CoderException if an error occurs + */ + public static InstantiationCommand getInstantiationCommandFromResource(final String path, final String suffix) + throws CoderException { + InstantiationCommand instantiationCommand = CODER.decode(new File(path), InstantiationCommand.class); + + // add suffix to all names + instantiationCommand.getControlLoopIdentifierList().forEach(cl -> cl.setName(cl.getName() + suffix)); + return instantiationCommand; + } + + /** + * Assert that Instantiation Response contains proper ControlLoops. + * + * @param response InstantiationResponse + * @param controlLoops ControlLoops + */ + public static void assertInstantiationResponse(InstantiationResponse response, ControlLoops controlLoops) { + assertNotNull(response); + Assert.assertNull(response.getErrorDetails()); + assertEquals(response.getAffectedControlLoops().size(), controlLoops.getControlLoopList().size()); + for (ControlLoop controlLoop : controlLoops.getControlLoopList()) { + assertTrue(response.getAffectedControlLoops().stream() + .filter(ac -> ac.equals(controlLoop.getKey().asIdentifier())).findAny().isPresent()); + } + } + + /** + * Assert that Instantiation Response contains proper ControlLoops. + * + * @param response InstantiationResponse + * @param command InstantiationCommand + */ + public static void assertInstantiationResponse(InstantiationResponse response, InstantiationCommand command) { + assertNotNull(response); + assertEquals(response.getAffectedControlLoops().size(), command.getControlLoopIdentifierList().size()); + for (ToscaConceptIdentifier toscaConceptIdentifier : command.getControlLoopIdentifierList()) { + assertTrue(response.getAffectedControlLoops().stream() + .filter(ac -> ac.compareTo(toscaConceptIdentifier) == 0).findAny().isPresent()); + } + } + + /** + * Assert that Instantiation Response contains ControlLoop equals to controlLoop. + * + * @param response InstantiationResponse + * @param controlLoop ControlLoop + */ + public static void assertInstantiationResponse(InstantiationResponse response, ControlLoop controlLoop) { + assertNotNull(response); + Assert.assertNull(response.getErrorDetails()); + assertEquals(1, response.getAffectedControlLoops().size()); + assertEquals(0, response.getAffectedControlLoops().get(0).compareTo(controlLoop.getKey().asIdentifier())); + } + + /** + * Store ToscaServiceTemplate from resource to DB. + * + * @param path path of the resource + * @param parameters The parameters for the implementation of the PolicyModelProvider + * @throws PfModelException if an error occurs + */ + public static void storeToscaServiceTemplate(String path, PolicyModelsProviderParameters parameters) + throws PfModelException { + + ToscaServiceTemplate template = + yamlTranslator.fromYaml(ResourceUtils.getResourceAsString(path), ToscaServiceTemplate.class); + + try (PolicyModelsProvider modelsProvider = + new PolicyModelsProviderFactory().createPolicyModelsProvider(parameters)) { + modelsProvider.createServiceTemplate(template); + } + } +} diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java new file mode 100644 index 000000000..71e762455 --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/instantiation/rest/InstantiationControllerTest.java @@ -0,0 +1,322 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.instantiation.rest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; + +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.core.Response; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoops; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationCommand; +import org.onap.policy.clamp.controlloop.models.messages.rest.instantiation.InstantiationResponse; +import org.onap.policy.clamp.controlloop.runtime.instantiation.ControlLoopInstantiationProvider; +import org.onap.policy.clamp.controlloop.runtime.instantiation.InstantiationUtils; +import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +/** + * Class to perform unit test of {@link InstantiationController}}. + * + */ +public class InstantiationControllerTest extends CommonRestController { + + private static final String CL_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/controlloops/ControlLoops.json"; + + private static final String CL_INSTANTIATION_UPDATE_JSON = + "src/test/resources/rest/controlloops/ControlLoopsUpdate.json"; + + private static final String CL_INSTANTIATION_CHANGE_STATE_JSON = + "src/test/resources/rest/controlloops/PassiveCommand.json"; + + private static final String TOSCA_TEMPLATE_YAML = + "src/test/resources/rest/servicetemplates/pmsh_multiple_cl_tosca.yaml"; + + private static final String INSTANTIATION_ENDPOINT = "instantiation"; + + private static final String INSTANTIATION_COMMAND_ENDPOINT = "instantiation/command"; + + /** + * starts Main and inserts a commissioning template. + * + * @throws Exception if an error occurs + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + CommonRestController.setUpBeforeClass("InstApi"); + + // to validate control Loop, it needs to define ToscaServiceTemplate + InstantiationUtils.storeToscaServiceTemplate(TOSCA_TEMPLATE_YAML, getParameters()); + + ControlLoops controlLoops = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Command"); + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(getParameters())) { + instantiationProvider.createControlLoops(controlLoops); + } + } + + @AfterClass + public static void teardownAfterClass() { + CommonRestController.teardownAfterClass(); + } + + @Test + public void testSwagger() throws Exception { + super.testSwagger(INSTANTIATION_ENDPOINT); + } + + @Test + public void testCreate_Unauthorized() throws Exception { + ControlLoops controlLoops = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Unauthorized"); + + assertUnauthorizedPost(INSTANTIATION_ENDPOINT, Entity.json(controlLoops)); + } + + @Test + public void testQuery_Unauthorized() throws Exception { + assertUnauthorizedGet(INSTANTIATION_ENDPOINT); + } + + @Test + public void testUpdate_Unauthorized() throws Exception { + ControlLoops controlLoops = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Unauthorized"); + + assertUnauthorizedPut(INSTANTIATION_ENDPOINT, Entity.json(controlLoops)); + } + + @Test + public void testDelete_Unauthorized() throws Exception { + assertUnauthorizedDelete(INSTANTIATION_ENDPOINT); + } + + @Test + public void testCommand_Unauthorized() throws Exception { + InstantiationCommand instantiationCommand = InstantiationUtils + .getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Unauthorized"); + + assertUnauthorizedPut(INSTANTIATION_COMMAND_ENDPOINT, Entity.json(instantiationCommand)); + } + + @Test + public void testCreate() throws Exception { + ControlLoops controlLoopsFromRsc = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Create"); + + Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT); + Response resp = invocationBuilder.post(Entity.json(controlLoopsFromRsc)); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class); + InstantiationUtils.assertInstantiationResponse(instResponse, controlLoopsFromRsc); + + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(getParameters())) { + for (ControlLoop controlLoopFromRsc : controlLoopsFromRsc.getControlLoopList()) { + ControlLoops controlLoopsFromDb = instantiationProvider.getControlLoops( + controlLoopFromRsc.getKey().getName(), controlLoopFromRsc.getKey().getVersion()); + + assertNotNull(controlLoopsFromDb); + assertThat(controlLoopsFromDb.getControlLoopList()).hasSize(1); + assertEquals(controlLoopFromRsc, controlLoopsFromDb.getControlLoopList().get(0)); + } + } + } + + @Test + public void testCreateBadRequest() throws Exception { + ControlLoops controlLoopsFromRsc = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "CreateBadRequest"); + + Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT); + Response resp = invocationBuilder.post(Entity.json(controlLoopsFromRsc)); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + + // testing Bad Request: CL already defined + resp = invocationBuilder.post(Entity.json(controlLoopsFromRsc)); + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus()); + InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class); + assertNotNull(instResponse.getErrorDetails()); + assertNull(instResponse.getAffectedControlLoops()); + } + + @Test + public void testQuery_NoResultWithThisName() throws Exception { + Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT + "?name=noResultWithThisName"); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + ControlLoops resp = rawresp.readEntity(ControlLoops.class); + assertThat(resp.getControlLoopList()).isEmpty(); + } + + @Test + public void testQuery() throws Exception { + // inserts a ControlLoops to DB + ControlLoops controlLoops = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Query"); + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(getParameters())) { + instantiationProvider.createControlLoops(controlLoops); + } + + for (ControlLoop controlLoopFromRsc : controlLoops.getControlLoopList()) { + Invocation.Builder invocationBuilder = + super.sendRequest(INSTANTIATION_ENDPOINT + "?name=" + controlLoopFromRsc.getKey().getName()); + Response rawresp = invocationBuilder.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus()); + ControlLoops controlLoopsQuery = rawresp.readEntity(ControlLoops.class); + assertNotNull(controlLoopsQuery); + assertThat(controlLoopsQuery.getControlLoopList()).hasSize(1); + assertEquals(controlLoopFromRsc, controlLoopsQuery.getControlLoopList().get(0)); + } + } + + @Test + public void testUpdate() throws Exception { + ControlLoops controlLoopsCreate = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Update"); + + ControlLoops controlLoops = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_UPDATE_JSON, "Update"); + + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(getParameters())) { + instantiationProvider.createControlLoops(controlLoopsCreate); + + Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT); + Response resp = invocationBuilder.put(Entity.json(controlLoops)); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + + InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class); + InstantiationUtils.assertInstantiationResponse(instResponse, controlLoops); + + for (ControlLoop controlLoopUpdate : controlLoops.getControlLoopList()) { + ControlLoops controlLoopsFromDb = instantiationProvider + .getControlLoops(controlLoopUpdate.getKey().getName(), controlLoopUpdate.getKey().getVersion()); + + assertNotNull(controlLoopsFromDb); + assertThat(controlLoopsFromDb.getControlLoopList()).hasSize(1); + assertEquals(controlLoopUpdate, controlLoopsFromDb.getControlLoopList().get(0)); + } + } + } + + @Test + public void testDelete_NoResultWithThisName() throws Exception { + Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT + "?name=noResultWithThisName"); + Response resp = invocationBuilder.delete(); + assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus()); + InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class); + assertNotNull(instResponse.getErrorDetails()); + assertNull(instResponse.getAffectedControlLoops()); + } + + @Test + public void testDelete() throws Exception { + ControlLoops controlLoopsFromRsc = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "Delete"); + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(getParameters())) { + instantiationProvider.createControlLoops(controlLoopsFromRsc); + + for (ControlLoop controlLoopFromRsc : controlLoopsFromRsc.getControlLoopList()) { + Invocation.Builder invocationBuilder = + super.sendRequest(INSTANTIATION_ENDPOINT + "?name=" + controlLoopFromRsc.getKey().getName() + + "&version=" + controlLoopFromRsc.getKey().getVersion()); + Response resp = invocationBuilder.delete(); + assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus()); + InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class); + InstantiationUtils.assertInstantiationResponse(instResponse, controlLoopFromRsc); + + ControlLoops controlLoopsFromDb = instantiationProvider.getControlLoops( + controlLoopFromRsc.getKey().getName(), controlLoopFromRsc.getKey().getVersion()); + assertThat(controlLoopsFromDb.getControlLoopList()).isEmpty(); + } + } + } + + @Test + public void testDeleteBadRequest() throws Exception { + ControlLoops controlLoopsFromRsc = + InstantiationUtils.getControlLoopsFromResource(CL_INSTANTIATION_CREATE_JSON, "DelBadRequest"); + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(getParameters())) { + instantiationProvider.createControlLoops(controlLoopsFromRsc); + + for (ControlLoop controlLoopFromRsc : controlLoopsFromRsc.getControlLoopList()) { + Invocation.Builder invocationBuilder = + super.sendRequest(INSTANTIATION_ENDPOINT + "?name=" + controlLoopFromRsc.getKey().getName()); + Response resp = invocationBuilder.delete(); + // should be BAD_REQUEST + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), resp.getStatus()); + } + } + } + + @Test + public void testCommand_NotFound1() throws Exception { + Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_COMMAND_ENDPOINT); + Response resp = invocationBuilder.put(Entity.json(new InstantiationCommand())); + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus()); + } + + @Test + public void testCommand_NotFound2() throws Exception { + InstantiationCommand command = + InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Command"); + command.setOrderedState(null); + + Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_COMMAND_ENDPOINT); + Response resp = invocationBuilder.put(Entity.json(command)); + assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus()); + } + + @Test + public void testCommand() throws Exception { + InstantiationCommand command = + InstantiationUtils.getInstantiationCommandFromResource(CL_INSTANTIATION_CHANGE_STATE_JSON, "Command"); + + Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_COMMAND_ENDPOINT); + Response resp = invocationBuilder.put(Entity.json(command)); + assertEquals(Response.Status.ACCEPTED.getStatusCode(), resp.getStatus()); + InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class); + InstantiationUtils.assertInstantiationResponse(instResponse, command); + + // check passive state on DB + try (ControlLoopInstantiationProvider instantiationProvider = + new ControlLoopInstantiationProvider(getParameters())) { + for (ToscaConceptIdentifier toscaConceptIdentifier : command.getControlLoopIdentifierList()) { + ControlLoops controlLoopsGet = instantiationProvider.getControlLoops(toscaConceptIdentifier.getName(), + toscaConceptIdentifier.getVersion()); + assertThat(controlLoopsGet.getControlLoopList()).hasSize(1); + assertEquals(command.getOrderedState(), controlLoopsGet.getControlLoopList().get(0).getOrderedState()); + } + } + } +} diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestControllerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestControllerTest.java new file mode 100644 index 000000000..4f68b4f8c --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/rest/RestControllerTest.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.main.rest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.util.UUID; +import javax.ws.rs.Produces; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.junit.Test; + +/** + * Class to perform unit test of {@link RestController}}. + * + */ +public class RestControllerTest { + + @Test + public void testProduces() { + Produces annotation = RestController.class.getAnnotation(Produces.class); + assertNotNull(annotation); + assertThat(annotation.value()).contains(MediaType.APPLICATION_JSON) + .contains(RestController.APPLICATION_YAML); + } + + @Test + public void testAddVersionControlHeaders() { + RestController ctlr = new RestController(); + Response resp = ctlr.addVersionControlHeaders(Response.status(Response.Status.OK)).build(); + assertEquals("0", resp.getHeaderString(RestController.VERSION_MINOR_NAME)); + assertEquals("0", resp.getHeaderString(RestController.VERSION_PATCH_NAME)); + assertEquals("1.0.0", resp.getHeaderString(RestController.VERSION_LATEST_NAME)); + } + + @Test + public void testAddLoggingHeaders_Null() { + RestController ctlr = new RestController(); + Response resp = ctlr.addLoggingHeaders(Response.status(Response.Status.OK), null).build(); + assertNotNull(resp.getHeaderString(RestController.REQUEST_ID_NAME)); + } + + @Test + public void testAddLoggingHeaders_NonNull() { + UUID uuid = UUID.randomUUID(); + RestController ctlr = new RestController(); + Response resp = ctlr.addLoggingHeaders(Response.status(Response.Status.OK), uuid).build(); + assertEquals(uuid.toString(), resp.getHeaderString(RestController.REQUEST_ID_NAME)); + } + +} diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivatorTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivatorTest.java new file mode 100644 index 000000000..da71c239d --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/ClRuntimeActivatorTest.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.main.startstop; + +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; +import static org.assertj.core.api.Assertions.assertThatIllegalStateException; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterHandler; +import org.onap.policy.common.utils.services.Registry; + +/** + * Class to perform unit test of {@link ClRuntimeActivator}}. + * + */ +public class ClRuntimeActivatorTest { + + @Test + public void testStartAndStop() throws Exception { + Registry.newRegistry(); + final String[] configParameters = {"-c", "src/test/resources/parameters/TestParameters.json"}; + final ClRuntimeCommandLineArguments arguments = new ClRuntimeCommandLineArguments(); + arguments.parse(configParameters); + ClRuntimeParameterGroup parameterGroup = new ClRuntimeParameterHandler().getParameters(arguments); + ClRuntimeActivator activator = new ClRuntimeActivator(parameterGroup); + activator.isAlive(); + + assertFalse(activator.isAlive()); + activator.start(); + assertTrue(activator.isAlive()); + assertTrue(activator.getParameterGroup().isValid()); + assertEquals(activator.getParameterGroup().getName(), + activator.getParameterGroup().getRestServerParameters().getName()); + + // repeat start - should throw an exception + assertThatIllegalStateException().isThrownBy(() -> activator.start()); + assertTrue(activator.isAlive()); + assertTrue(activator.getParameterGroup().isValid()); + + activator.stop(); + assertFalse(activator.isAlive()); + + // repeat stop - should throw an exception + assertThatIllegalStateException().isThrownBy(() -> activator.stop()); + assertFalse(activator.isAlive()); + } + + @Test + public void testNull() { + assertThatExceptionOfType(ControlLoopRuntimeException.class).isThrownBy(() -> new ClRuntimeActivator(null)); + } + + @Test + public void testNotValid() { + ClRuntimeParameterGroup parameterGroup = new ClRuntimeParameterGroup("name"); + assertThatExceptionOfType(ControlLoopRuntimeException.class) + .isThrownBy(() -> new ClRuntimeActivator(parameterGroup)); + } +} diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/MainTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/MainTest.java new file mode 100644 index 000000000..b06383c68 --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/main/startstop/MainTest.java @@ -0,0 +1,157 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.main.startstop; + +import static org.assertj.core.api.Assertions.assertThatCode; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.onap.policy.clamp.controlloop.common.ControlLoopConstants; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopRuntimeException; +import org.onap.policy.common.utils.resources.MessageConstants; +import org.onap.policy.common.utils.services.Registry; + +/** + * Class to perform unit test of {@link Main}}. + * + */ +public class MainTest { + + public static final String POLICY_CLAMP_FAILURE_MSG = + String.format(MessageConstants.START_FAILURE_MSG, MessageConstants.POLICY_CLAMP); + + /** + * Set up. + */ + @BeforeClass + public static void setUp() { + Registry.newRegistry(); + } + + /** + * Shuts "main" down. + * + * @throws Exception if an error occurs + */ + @AfterClass + public static void tearDown() throws Exception { + // shut down activator + final ClRuntimeActivator activator = + Registry.getOrDefault(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR, ClRuntimeActivator.class, null); + if (activator != null && activator.isAlive()) { + activator.shutdown(); + } + } + + @Test + public void testMain_Help() { + final String[] configParameters = {"-h"}; + Main main = new Main(configParameters); + assertFalse(main.isRunning()); + } + + @Test + public void testMain_Version() { + final String[] configParameters = {"-v"}; + Main main = new Main(configParameters); + assertFalse(main.isRunning()); + } + + @Test + public void testMain_Valid() { + final String[] configParameters = {"-c", "src/test/resources/parameters/TestParameters.json"}; + Main main = new Main(configParameters); + assertTrue(main.isRunning()); + + // ensure items were added to the registry + assertNotNull(Registry.get(ControlLoopConstants.REG_CLRUNTIME_ACTIVATOR, ClRuntimeActivator.class)); + + assertThatCode(() -> main.shutdown()).doesNotThrowAnyException(); + + assertFalse(main.isRunning()); + } + + @Test + public void testMain_NoParameter() { + assertThatConfigParameterThrownException(new String[] {}); + } + + @Test + public void testMain_FilePathNotDefined() { + assertThatConfigParameterThrownException(new String[] {"-c"}); + } + + @Test + public void testMain_TooManyCommand() { + assertThatConfigParameterThrownException(new String[] {"-h", "d"}); + } + + @Test + public void testMain_WrongParameter() { + assertThatConfigParameterThrownException(new String[] {"-d"}); + } + + private void assertThatConfigParameterThrownException(final String[] configParameters) { + assertThatThrownBy(() -> Main.main(configParameters)).isInstanceOf(ControlLoopRuntimeException.class) + .hasMessage(POLICY_CLAMP_FAILURE_MSG); + } + + @Test + public void testParticipant_NoFileWithThisName() { + assertThatConfigFileThrownException("src/test/resources/parameters/NoFileWithThisName.json"); + } + + @Test + public void testParticipant_NotValidFile() { + assertThatConfigFileThrownException("src/test/resources/parameters"); + } + + @Test + public void testParticipant_FileEmpty() { + assertThatConfigFileThrownException("src/test/resources/parameters/EmptyParameters.json"); + } + + @Test + public void testParticipant_NoParameters() { + assertThatConfigFileThrownException("src/test/resources/parameters/NoParameters.json"); + } + + @Test + public void testParticipant_InvalidParameters() { + assertThatConfigFileThrownException("src/test/resources/parameters/InvalidParameters.json"); + } + + @Test + public void testParticipant_WrongJsonFormat() { + assertThatConfigFileThrownException("src/test/resources/parameters/Unreadable.json"); + } + + private void assertThatConfigFileThrownException(final String configFilePath) { + final String[] configParameters = new String[] {"-c", configFilePath}; + assertThatThrownBy(() -> new Main(configParameters)).isInstanceOf(ControlLoopRuntimeException.class) + .hasMessage(String.format(POLICY_CLAMP_FAILURE_MSG)); + } +} diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/TestMonitoringProvider.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/TestMonitoringProvider.java new file mode 100644 index 000000000..44096eecd --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/TestMonitoringProvider.java @@ -0,0 +1,264 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.monitoring; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.lang.reflect.Field; +import java.time.Instant; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.junit.BeforeClass; +import org.junit.Test; +import org.mockito.Mockito; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoop; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ControlLoopElement; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatisticsList; +import org.onap.policy.clamp.controlloop.models.controlloop.persistence.provider.ControlLoopProvider; +import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + + +public class TestMonitoringProvider { + + private static final String CL_PARTICIPANT_STATISTICS_JSON = + "src/test/resources/rest/monitoring/TestParticipantStatistics.json"; + private static final String INVALID_PARTICIPANT_JSON_INPUT = + "src/test/resources/rest/monitoring/TestParticipantStatistics_Invalid.json"; + private static final String CL_ELEMENT_STATISTICS_JSON = + "src/test/resources/rest/monitoring/TestClElementStatistics.json"; + private static final String INVALID_CL_ELEMENT_JSON_INPUT = + "src/test/resources/rest/monitoring/TestClElementStatistics_Invalid.json"; + private static final Coder CODER = new StandardCoder(); + + private static final String CL_PROVIDER_FIELD = "controlLoopProvider"; + + private static final String LIST_IS_NULL = ".*StatisticsList is marked .*ull but is null"; + private static ParticipantStatisticsList inputParticipantStatistics; + private static ParticipantStatisticsList invalidParticipantInput; + private static ClElementStatisticsList inputClElementStatistics; + private static ClElementStatisticsList invalidClElementInput; + + + + @BeforeClass + public static void beforeSetupStatistics() throws CoderException { + // Reading input json for statistics data + inputParticipantStatistics = + CODER.decode(new File(CL_PARTICIPANT_STATISTICS_JSON), ParticipantStatisticsList.class); + invalidParticipantInput = + CODER.decode(new File(INVALID_PARTICIPANT_JSON_INPUT), ParticipantStatisticsList.class); + inputClElementStatistics = CODER.decode(new File(CL_ELEMENT_STATISTICS_JSON), ClElementStatisticsList.class); + invalidClElementInput = CODER.decode(new File(INVALID_CL_ELEMENT_JSON_INPUT), ClElementStatisticsList.class); + } + + + @Test + public void testCreateParticipantStatistics() throws Exception { + PolicyModelsProviderParameters parameters = + CommonTestData.geParameterGroup(0, "createparStat").getDatabaseProviderParameters(); + + try (MonitoringProvider provider = new MonitoringProvider(parameters)) { + // Creating statistics data in db with null input + assertThatThrownBy(() -> { + provider.createParticipantStatistics(null); + }).hasMessageMatching(LIST_IS_NULL); + + assertThatThrownBy(() -> { + provider.createParticipantStatistics(invalidParticipantInput.getStatisticsList()); + }).hasMessageMatching("participantStatisticsList is marked .*null but is null"); + + // Creating statistics data from input json + ParticipantStatisticsList createResponse = + provider.createParticipantStatistics(inputParticipantStatistics.getStatisticsList()); + + assertThat(createResponse.getStatisticsList()).hasSize(3); + assertEquals(createResponse.getStatisticsList().toString().replaceAll("\\s+", ""), + inputParticipantStatistics.getStatisticsList().toString().replaceAll("\\s+", "")); + } + } + + @Test + public void testGetParticipantStatistics() throws Exception { + PolicyModelsProviderParameters parameters = + CommonTestData.geParameterGroup(0, "getparStat").getDatabaseProviderParameters(); + try (MonitoringProvider provider = new MonitoringProvider(parameters)) { + ParticipantStatisticsList getResponse; + + provider.createParticipantStatistics(inputParticipantStatistics.getStatisticsList()); + + assertThatThrownBy(() -> { + provider.fetchFilteredParticipantStatistics(null, null, 0, null, null); + }).hasMessageMatching("name is marked .*null but is null"); + + // Fetch specific statistics record with name, version and record count + getResponse = provider.fetchFilteredParticipantStatistics("name2", "1.001", 1, + null, null); + assertThat(getResponse.getStatisticsList()).hasSize(1); + assertEquals(getResponse.getStatisticsList().get(0).toString().replaceAll("\\s+", ""), + inputParticipantStatistics.getStatisticsList().get(2).toString().replaceAll("\\s+", "")); + + // Fetch statistics using timestamp + getResponse = provider.fetchFilteredParticipantStatistics("name1", "1.001", 0, + null, Instant.parse("2021-01-10T15:00:00.000Z")); + assertThat(getResponse.getStatisticsList()).hasSize(1); + + getResponse = provider.fetchFilteredParticipantStatistics("name1", "1.001", 0, + Instant.parse("2021-01-11T12:00:00.000Z"), Instant.parse("2021-01-11T16:00:00.000Z")); + + assertThat(getResponse.getStatisticsList()).isEmpty(); + } + } + + @Test + public void testCreateClElementStatistics() throws Exception { + PolicyModelsProviderParameters parameters = + CommonTestData.geParameterGroup(0, "createelemstat").getDatabaseProviderParameters(); + try (MonitoringProvider provider = new MonitoringProvider(parameters)) { + // Creating statistics data in db with null input + assertThatThrownBy(() -> { + provider.createClElementStatistics(null); + }).hasMessageMatching(LIST_IS_NULL); + + assertThatThrownBy(() -> { + provider.createClElementStatistics(invalidClElementInput.getClElementStatistics()); + }).hasMessageMatching("clElementStatisticsList is marked .*null but is null"); + + // Creating clElement statistics data from input json + ClElementStatisticsList createResponse = + provider.createClElementStatistics(inputClElementStatistics.getClElementStatistics()); + + assertThat(createResponse.getClElementStatistics()).hasSize(4); + assertEquals(createResponse.getClElementStatistics().toString().replaceAll("\\s+", ""), + inputClElementStatistics.getClElementStatistics().toString().replaceAll("\\s+", "")); + } + } + + @Test + public void testGetClElementStatistics() throws Exception { + PolicyModelsProviderParameters parameters = + CommonTestData.geParameterGroup(0, "getelemstat").getDatabaseProviderParameters(); + try (MonitoringProvider provider = new MonitoringProvider(parameters)) { + ClElementStatisticsList getResponse; + + assertThatThrownBy(() -> { + provider.fetchFilteredClElementStatistics(null, null, null, null, + null, 0); + }).hasMessageMatching("name is marked .*null but is null"); + + ClElementStatisticsList lists = provider.createClElementStatistics(inputClElementStatistics + .getClElementStatistics()); + + getResponse = provider.fetchFilteredClElementStatistics("name1", null, null, null, + null, 0); + + assertThat(getResponse.getClElementStatistics()).hasSize(2); + assertEquals(getResponse.getClElementStatistics().get(0).toString().replaceAll("\\s+", ""), + inputClElementStatistics.getClElementStatistics().get(0).toString().replaceAll("\\s+", "")); + + // Fetch specific statistics record with name, id and record count + getResponse = provider.fetchFilteredClElementStatistics("name1", "1.001", + "709c62b3-8918-41b9-a747-d21eb79c6c20", null, null, 0); + assertThat(getResponse.getClElementStatistics()).hasSize(2); + + // Fetch statistics using timestamp + getResponse = provider.fetchFilteredClElementStatistics("name1", "1.001", null, + Instant.parse("2021-01-10T13:45:00.000Z"), null, 0); + assertThat(getResponse.getClElementStatistics()).hasSize(2); + } + } + + @Test + public void testGetParticipantStatsPerCL() throws Exception { + PolicyModelsProviderParameters parameters = + CommonTestData.geParameterGroup(0, "getparStatCL").getDatabaseProviderParameters(); + try (MonitoringProvider provider = Mockito.spy(new MonitoringProvider(parameters))) { + + provider.createParticipantStatistics(inputParticipantStatistics.getStatisticsList()); + //Mock the response for fetching participant conceptIdentifiers per control loop + List conceptIdentifiers = new ArrayList<>(); + conceptIdentifiers.add(new ToscaConceptIdentifier("name1", "1.001")); + when(provider.getAllParticipantIdsPerControlLoop("testName", "1.001")) + .thenReturn(conceptIdentifiers); + ParticipantStatisticsList getResponse; + getResponse = provider.fetchParticipantStatsPerControlLoop("testName", "1.001"); + assertThat(getResponse.getStatisticsList()).hasSize(2); + assertEquals(getResponse.getStatisticsList().get(0).toString().replaceAll("\\s+", ""), + inputParticipantStatistics.getStatisticsList().get(0).toString().replaceAll("\\s+", "")); + assertThat(provider.fetchParticipantStatsPerControlLoop("invalidCLName", "1.002") + .getStatisticsList()).isEmpty(); + } + + } + + @Test + public void testClElementStatsPerCL() throws Exception { + PolicyModelsProviderParameters parameters = + CommonTestData.geParameterGroup(0, "getelemstatPerCL").getDatabaseProviderParameters(); + //Setup a dummy Control loop data + ControlLoopElement mockClElement = new ControlLoopElement(); + mockClElement.setId(inputClElementStatistics.getClElementStatistics().get(0).getId()); + mockClElement.setParticipantId(new ToscaConceptIdentifier(inputClElementStatistics.getClElementStatistics() + .get(0).getParticipantId().getName(), inputClElementStatistics.getClElementStatistics().get(0) + .getParticipantId().getVersion())); + ControlLoop mockCL = new ControlLoop(); + mockCL.setElements(new LinkedHashMap<>()); + mockCL.getElements().put(mockClElement.getId(), mockClElement); + + //Mock controlloop data to be returned for the given CL Id + ControlLoopProvider mockClProvider = Mockito.mock(ControlLoopProvider.class); + when(mockClProvider.getControlLoop(new ToscaConceptIdentifier("testCLName", "1.001"))) + .thenReturn(mockCL); + + try (MonitoringProvider monitoringProvider = new MonitoringProvider(parameters)) { + monitoringProvider.createClElementStatistics(inputClElementStatistics.getClElementStatistics()); + Field controlLoopProviderField = monitoringProvider.getClass().getDeclaredField(CL_PROVIDER_FIELD); + controlLoopProviderField.setAccessible(true); + controlLoopProviderField.set(monitoringProvider, mockClProvider); + + ClElementStatisticsList getResponse; + getResponse = monitoringProvider.fetchClElementStatsPerControlLoop("testCLName", "1.001"); + + assertThat(getResponse.getClElementStatistics()).hasSize(2); + assertEquals(getResponse.getClElementStatistics().get(1).toString().replaceAll("\\s+", ""), + inputClElementStatistics.getClElementStatistics().get(1).toString().replaceAll("\\s+", "")); + + assertThat(monitoringProvider.fetchClElementStatsPerControlLoop("invalidCLName", "1.002") + .getClElementStatistics()).isEmpty(); + + Map clElementIds = monitoringProvider + .getAllClElementsIdPerControlLoop("testCLName", "1.001"); + assertThat(clElementIds).containsKey(inputClElementStatistics.getClElementStatistics().get(0).getId() + .toString()); + } + } +} diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryControllerTest.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryControllerTest.java new file mode 100644 index 000000000..118199a2d --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/monitoring/rest/MonitoringQueryControllerTest.java @@ -0,0 +1,237 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.monitoring.rest; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import java.io.File; +import java.time.Instant; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.core.Response; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ClElementStatisticsList; +import org.onap.policy.clamp.controlloop.models.controlloop.concepts.ParticipantStatisticsList; +import org.onap.policy.clamp.controlloop.runtime.monitoring.MonitoringProvider; +import org.onap.policy.clamp.controlloop.runtime.util.rest.CommonRestController; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.StandardCoder; + +public class MonitoringQueryControllerTest extends CommonRestController { + + private static final String CL_PARTICIPANT_STATISTICS_JSON = + "src/test/resources/rest/monitoring/TestParticipantStatistics.json"; + private static final String CL_ELEMENT_STATISTICS_JSON = + "src/test/resources/rest/monitoring/TestClElementStatistics.json"; + + private static final Coder CODER = new StandardCoder(); + + private static ParticipantStatisticsList inputParticipantStatistics; + private static ClElementStatisticsList inputClElementStatistics; + + private static ParticipantStatisticsList participantStatisticsList; + private static ClElementStatisticsList clElementStatisticsList; + + private static final String CLELEMENT_STATS_ENDPOINT = "monitoring/clelement"; + private static final String PARTICIPANT_STATS_ENDPOINT = "monitoring/participant"; + private static final String PARTICIPANT_STATS_PER_CL_ENDPOINT = "monitoring/participants/controlloop"; + private static final String CLELEMENT_STATS_PER_CL_ENDPOINT = "monitoring/clelements/controlloop"; + + + /** + * starts Main. + * + * @throws Exception if an error occurs + */ + @BeforeClass + public static void setUpBeforeClass() throws Exception { + CommonRestController.setUpBeforeClass("testStatisticsQuery"); + inputParticipantStatistics = CODER.decode(new File(CL_PARTICIPANT_STATISTICS_JSON), + ParticipantStatisticsList.class); + inputClElementStatistics = CODER.decode(new File(CL_ELEMENT_STATISTICS_JSON), + ClElementStatisticsList.class); + + try (MonitoringProvider monitoringProvider = new MonitoringProvider(getParameters())) { + // Insert Participant statistics to DB + participantStatisticsList = monitoringProvider.createParticipantStatistics(inputParticipantStatistics + .getStatisticsList()); + // Insert CL Element statistics to DB + clElementStatisticsList = monitoringProvider.createClElementStatistics(inputClElementStatistics + .getClElementStatistics()); + } + } + + @AfterClass + public static void teardownAfterClass() { + CommonRestController.teardownAfterClass(); + } + + @Test + public void testQuery_Unauthorized_for_ClElementStats() throws Exception { + assertUnauthorizedGet(CLELEMENT_STATS_ENDPOINT); + } + + @Test + public void testQuery_Unauthorized_for_ClParticipantStats() throws Exception { + assertUnauthorizedGet(PARTICIPANT_STATS_ENDPOINT); + } + + @Test + public void testQuery_Unauthorized_for_ParticipantStatsPerCl() throws Exception { + assertUnauthorizedGet(PARTICIPANT_STATS_PER_CL_ENDPOINT); + } + + @Test + public void testQuery_Unauthorized_for_ClElementStatsPerCl() throws Exception { + assertUnauthorizedGet(CLELEMENT_STATS_PER_CL_ENDPOINT); + } + + @Test + public void testSwagger_ClStats() throws Exception { + super.testSwagger(CLELEMENT_STATS_ENDPOINT); + super.testSwagger(PARTICIPANT_STATS_ENDPOINT); + super.testSwagger(CLELEMENT_STATS_PER_CL_ENDPOINT); + super.testSwagger(PARTICIPANT_STATS_PER_CL_ENDPOINT); + } + + @Test + public void testClElementStatisticsEndpoint() throws Exception { + // Filter statistics only based on participant Id and UUID + Invocation.Builder invokeRequest1 = + super.sendRequest(CLELEMENT_STATS_ENDPOINT + "?name=" + clElementStatisticsList + .getClElementStatistics().get(0).getParticipantId().getName() + "&version=" + clElementStatisticsList + .getClElementStatistics().get(0).getParticipantId().getVersion() + "&id=" + clElementStatisticsList + .getClElementStatistics().get(0).getId().toString()); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus()); + + ClElementStatisticsList result1 = response1.readEntity(ClElementStatisticsList.class); + + assertNotNull(result1); + assertThat(result1.getClElementStatistics()).hasSize(2); + assertEquals(result1.getClElementStatistics().get(0), clElementStatisticsList + .getClElementStatistics().get(0)); + + // Filter statistics based on timestamp + Invocation.Builder invokeRequest2 = + super.sendRequest(CLELEMENT_STATS_ENDPOINT + "?name=" + clElementStatisticsList + .getClElementStatistics().get(1).getParticipantId().getName() + "&version=" + clElementStatisticsList + .getClElementStatistics().get(1).getParticipantId().getVersion() + "&startTime=" + + Instant.parse("2021-01-10T13:00:00.000Z") + "&endTime=" + Instant.parse("2021-01-10T14:00:00.000Z")); + Response response2 = invokeRequest2.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response2.getStatus()); + ClElementStatisticsList result2 = response2.readEntity(ClElementStatisticsList.class); + + assertNotNull(result2); + assertThat(result2.getClElementStatistics()).hasSize(1); + assertEquals(result1.getClElementStatistics().get(0), clElementStatisticsList + .getClElementStatistics().get(0)); + } + + @Test + public void testClElementStats_BadRequest() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(CLELEMENT_STATS_ENDPOINT + "?version=1.0.0"); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus()); + } + + @Test + public void testParticipantStatisticsEndpoint() throws Exception { + + // Filter statistics only based on participant Id + Invocation.Builder invokeRequest1 = + super.sendRequest(PARTICIPANT_STATS_ENDPOINT + "?name=" + participantStatisticsList + .getStatisticsList().get(0).getParticipantId().getName() + "&version=" + participantStatisticsList + .getStatisticsList().get(0).getParticipantId().getVersion()); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus()); + ParticipantStatisticsList result1 = response1.readEntity(ParticipantStatisticsList.class); + + assertNotNull(result1); + assertThat(result1.getStatisticsList()).hasSize(2); + assertEquals(result1.getStatisticsList().get(0), participantStatisticsList + .getStatisticsList().get(0)); + + // Filter statistics based on timestamp + Invocation.Builder invokeRequest2 = + super.sendRequest(PARTICIPANT_STATS_ENDPOINT + "?name=" + participantStatisticsList + .getStatisticsList().get(1).getParticipantId().getName() + "&version=" + participantStatisticsList + .getStatisticsList().get(1).getParticipantId().getVersion() + "&startTime=" + + Instant.parse("2021-01-10T13:00:00.000Z") + "&endTime=" + Instant.parse("2021-01-10T14:00:00.000Z")); + Response response2 = invokeRequest2.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response2.getStatus()); + ParticipantStatisticsList result2 = response2.readEntity(ParticipantStatisticsList.class); + + assertNotNull(result2); + assertThat(result2.getStatisticsList()).hasSize(1); + assertEquals(result1.getStatisticsList().get(0), participantStatisticsList + .getStatisticsList().get(0)); + } + + @Test + public void testParticipantStats_BadRequest() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(PARTICIPANT_STATS_ENDPOINT + "?version=0.0"); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus()); + } + + @Test + public void testParticipantStatsPerClEndpoint() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(PARTICIPANT_STATS_PER_CL_ENDPOINT + "?name=dummyName&version=1.001"); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus()); + ParticipantStatisticsList result1 = response1.readEntity(ParticipantStatisticsList.class); + assertThat(result1.getStatisticsList()).isEmpty(); + } + + @Test + public void testParticipantStatsPerCl_BadRequest() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(PARTICIPANT_STATS_PER_CL_ENDPOINT); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus()); + } + + @Test + public void testClElementStatisticsPerClEndpoint() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(CLELEMENT_STATS_PER_CL_ENDPOINT + "?name=dummyName&version=1.001"); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus()); + ClElementStatisticsList result1 = response1.readEntity(ClElementStatisticsList.class); + assertThat(result1.getClElementStatistics()).isEmpty(); + } + + @Test + public void testClElementStatsPerCl_BadRequest() throws Exception { + Invocation.Builder invokeRequest1 = + super.sendRequest(CLELEMENT_STATS_PER_CL_ENDPOINT); + Response response1 = invokeRequest1.buildGet().invoke(); + assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus()); + } +} diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java new file mode 100644 index 000000000..77f802d61 --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/CommonTestData.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.util; + +import org.onap.policy.clamp.controlloop.runtime.main.parameters.ClRuntimeParameterGroup; +import org.onap.policy.common.utils.coder.Coder; +import org.onap.policy.common.utils.coder.CoderException; +import org.onap.policy.common.utils.coder.StandardCoder; +import org.onap.policy.common.utils.resources.ResourceUtils; + +/** + * Class to hold/create all parameters for test cases. + * + */ +public class CommonTestData { + private static final Coder coder = new StandardCoder(); + + /** + * Gets the standard Control Loop parameters. + * + * @param port port to be inserted into the parameters + * @param dbName the database name + * @return the standard Control Loop parameters + */ + public static ClRuntimeParameterGroup geParameterGroup(final int port, final String dbName) { + try { + return coder.decode(getParameterGroupAsString(port, dbName), ClRuntimeParameterGroup.class); + + } catch (CoderException e) { + throw new RuntimeException("cannot read Control Loop parameters", e); + } + } + + /** + * Gets the standard Control Loop parameters, as a String. + * + * @param port port to be inserted into the parameters + * @param dbName the database name + * @return the standard Control Loop parameters as string + */ + public static String getParameterGroupAsString(final int port, final String dbName) { + return ResourceUtils.getResourceAsString("src/test/resources/parameters/InstantiationConfigParametersStd.json") + .replace("${port}", String.valueOf(port)).replace("${dbName}", "jdbc:h2:mem:" + dbName); + } +} diff --git a/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/rest/CommonRestController.java b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/rest/CommonRestController.java new file mode 100644 index 000000000..0d668f139 --- /dev/null +++ b/runtime-controlloop/src/test/java/org/onap/policy/clamp/controlloop/runtime/util/rest/CommonRestController.java @@ -0,0 +1,263 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nordix Foundation. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.clamp.controlloop.runtime.util.rest; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Entity; +import javax.ws.rs.client.Invocation; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import org.glassfish.jersey.client.ClientProperties; +import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature; +import org.onap.policy.clamp.controlloop.common.exception.ControlLoopException; +import org.onap.policy.clamp.controlloop.runtime.main.startstop.Main; +import org.onap.policy.clamp.controlloop.runtime.util.CommonTestData; +import org.onap.policy.common.gson.GsonMessageBodyHandler; +import org.onap.policy.common.utils.network.NetworkUtil; +import org.onap.policy.common.utils.services.Registry; +import org.onap.policy.models.provider.PolicyModelsProviderParameters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Class to perform Rest unit tests. + * + */ +public class CommonRestController { + + private static final String CONFIG_FILE = "src/test/resources/parameters/RuntimeConfigParameters%d.json"; + + private static final Logger LOGGER = LoggerFactory.getLogger(CommonRestController.class); + + public static final String SELF = NetworkUtil.getHostname(); + public static final String ENDPOINT_PREFIX = "onap/controlloop/v2/"; + + private static int port; + private static String httpPrefix; + private static Main main; + + /** + * Allocates a port for the server, writes a config file, and then starts Main. + * + * @param dbName database name + * @throws Exception if an error occurs + */ + public static void setUpBeforeClass(final String dbName) throws Exception { + port = NetworkUtil.allocPort(); + + httpPrefix = "http://" + SELF + ":" + port + "/"; + + makeConfigFile(dbName); + startMain(); + } + + /** + * Stops Main. + */ + public static void teardownAfterClass() { + try { + stopMain(); + } catch (Exception ex) { + LOGGER.error("cannot stop main", ex); + } + } + + protected static PolicyModelsProviderParameters getParameters() { + return main.getParameters().getDatabaseProviderParameters(); + } + + /** + * Verifies that an endpoint appears within the swagger response. + * + * @param endpoint the endpoint of interest + * @throws Exception if an error occurs + */ + protected void testSwagger(final String endpoint) throws Exception { + final Invocation.Builder invocationBuilder = sendFqeRequest(httpPrefix + "swagger.yaml", true); + final String resp = invocationBuilder.get(String.class); + + assertTrue(resp.contains(ENDPOINT_PREFIX + endpoint + ":")); + } + + /** + * Makes a parameter configuration file. + * + * @param dbName database name + * @throws IOException if an error occurs writing the configuration file + * @throws FileNotFoundException if an error occurs writing the configuration file + */ + private static void makeConfigFile(final String dbName) throws FileNotFoundException, IOException { + String json = CommonTestData.getParameterGroupAsString(port, dbName); + + File file = new File(String.format(CONFIG_FILE, port)); + file.deleteOnExit(); + + try (FileOutputStream output = new FileOutputStream(file)) { + output.write(json.getBytes(StandardCharsets.UTF_8)); + } + } + + /** + * Starts the "Main". + * + * @throws InterruptedException + * + * @throws Exception if an error occurs + */ + protected static void startMain() throws InterruptedException { + Registry.newRegistry(); + + // make sure port is available + if (NetworkUtil.isTcpPortOpen(SELF, port, 1, 1L)) { + throw new IllegalStateException("port " + port + " is not available"); + } + + final String[] configParameters = {"-c", String.format(CONFIG_FILE, port)}; + + main = new Main(configParameters); + + if (!NetworkUtil.isTcpPortOpen(SELF, port, 40, 250L)) { + throw new IllegalStateException("server is not listening on port " + port); + } + } + + /** + * Stops the "Main". + * + * @throws ControlLoopException + * + * @throws Exception if an error occurs + */ + private static void stopMain() throws Exception { + if (main != null) { + Main main2 = main; + main = null; + + main2.shutdown(); + } + // make sure port is close + if (NetworkUtil.isTcpPortOpen(SELF, port, 1, 1L)) { + throw new IllegalStateException("port " + port + " is still in use"); + } + } + + /** + * Sends a request to an endpoint. + * + * @param endpoint the target endpoint + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendRequest(final String endpoint) throws Exception { + return sendFqeRequest(httpPrefix + ENDPOINT_PREFIX + endpoint, true); + } + + /** + * Sends a request to an endpoint, without any authorization header. + * + * @param endpoint the target endpoint + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendNoAuthRequest(final String endpoint) throws Exception { + return sendFqeRequest(httpPrefix + ENDPOINT_PREFIX + endpoint, false); + } + + /** + * Sends a request to a fully qualified endpoint. + * + * @param fullyQualifiedEndpoint the fully qualified target endpoint + * @param includeAuth if authorization header should be included + * @return a request builder + * @throws Exception if an error occurs + */ + protected Invocation.Builder sendFqeRequest(final String fullyQualifiedEndpoint, boolean includeAuth) + throws Exception { + final Client client = ClientBuilder.newBuilder().build(); + + client.property(ClientProperties.METAINF_SERVICES_LOOKUP_DISABLE, "true"); + client.register(GsonMessageBodyHandler.class); + + if (includeAuth) { + client.register(HttpAuthenticationFeature.basic("healthcheck", "zb!XztG34")); + } + + final WebTarget webTarget = client.target(fullyQualifiedEndpoint); + + return webTarget.request(MediaType.APPLICATION_JSON); + } + + /** + * Assert that POST call is Unauthorized. + * + * @param endPoint the endpoint + * @param entity the entity ofthe body + * @throws Exception if an error occurs + */ + protected void assertUnauthorizedPost(final String endPoint, final Entity entity) throws Exception { + Response rawresp = sendNoAuthRequest(endPoint).post(entity); + assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + } + + /** + * Assert that PUT call is Unauthorized. + * + * @param endPoint the endpoint + * @param entity the entity ofthe body + * @throws Exception if an error occurs + */ + protected void assertUnauthorizedPut(final String endPoint, final Entity entity) throws Exception { + Response rawresp = sendNoAuthRequest(endPoint).put(entity); + assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + } + + /** + * Assert that GET call is Unauthorized. + * + * @param endPoint the endpoint + * @throws Exception if an error occurs + */ + protected void assertUnauthorizedGet(final String endPoint) throws Exception { + Response rawresp = sendNoAuthRequest(endPoint).buildGet().invoke(); + assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + } + + /** + * Assert that DELETE call is Unauthorized. + * + * @param endPoint the endpoint + * @throws Exception if an error occurs + */ + protected void assertUnauthorizedDelete(final String endPoint) throws Exception { + Response rawresp = sendNoAuthRequest(endPoint).delete(); + assertEquals(Response.Status.UNAUTHORIZED.getStatusCode(), rawresp.getStatus()); + } +} \ No newline at end of file -- cgit 1.2.3-korg