summaryrefslogtreecommitdiffstats
path: root/runtime-acm/src/test/java
diff options
context:
space:
mode:
Diffstat (limited to 'runtime-acm/src/test/java')
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java221
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java303
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivatorTest.java102
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java394
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/InstantiationUtils.java147
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java543
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/ActuatorControllerTest.java91
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/monitoring/TestMonitoringProvider.java321
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/monitoring/rest/MonitoringQueryControllerTest.java242
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/HandleCounterTest.java84
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspectTest.java66
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java319
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java214
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java225
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java125
-rw-r--r--runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/rest/CommonRestController.java201
16 files changed, 3598 insertions, 0 deletions
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java
new file mode 100644
index 000000000..35731d0e0
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/CommissioningProviderTest.java
@@ -0,0 +1,221 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.acm.runtime.commissioning;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.PropertyNamingStrategies;
+import com.fasterxml.jackson.module.jsonSchema.factories.SchemaFactoryWrapper;
+import java.util.List;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ServiceTemplateProvider;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaCapabilityType;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaDataType;
+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.ToscaPolicyType;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaRelationshipType;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate;
+
+class CommissioningProviderTest {
+ private static final String TOSCA_SERVICE_TEMPLATE_YAML =
+ "src/test/resources/rest/servicetemplates/pmsh_multiple_ac_tosca.yaml";
+ private static final String COMMON_TOSCA_SERVICE_TEMPLATE_YAML =
+ "src/test/resources/rest/servicetemplates/full-tosca-with-common-properties.yaml";
+
+ private static final Coder CODER = new StandardCoder();
+ private final ObjectMapper mapper = new ObjectMapper();
+
+ /**
+ * Test the fetching of automation composition definitions (ToscaServiceTemplates).
+ *
+ * @throws Exception .
+ */
+ @Test
+ void testGetAutomationCompositionDefinitions() throws Exception {
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var participantProvider = mock(ParticipantProvider.class);
+ var serviceTemplateProvider = mock(ServiceTemplateProvider.class);
+
+ CommissioningProvider provider =
+ new CommissioningProvider(serviceTemplateProvider, acProvider, null, participantProvider);
+
+ List<ToscaNodeTemplate> listOfTemplates = provider.getAutomationCompositionDefinitions(null, null);
+ assertThat(listOfTemplates).isEmpty();
+
+ when(acProvider.getFilteredNodeTemplates(any()))
+ .thenReturn(List.of(new ToscaNodeTemplate(), new ToscaNodeTemplate()));
+ listOfTemplates = provider.getAutomationCompositionDefinitions(null, null);
+ assertThat(listOfTemplates).hasSize(2);
+ }
+
+ /**
+ * Test the creation of automation composition definitions (ToscaServiceTemplates).
+ *
+ * @throws Exception .
+ */
+ @Test
+ void testCreateAutomationCompositionDefinitions() throws Exception {
+ var serviceTemplateProvider = mock(ServiceTemplateProvider.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var participantProvider = mock(ParticipantProvider.class);
+
+ CommissioningProvider provider =
+ new CommissioningProvider(serviceTemplateProvider, acProvider, null, participantProvider);
+
+ List<ToscaNodeTemplate> listOfTemplates = provider.getAutomationCompositionDefinitions(null, null);
+ assertThat(listOfTemplates).isEmpty();
+
+ ToscaServiceTemplate serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
+ when(serviceTemplateProvider.createServiceTemplate(serviceTemplate)).thenReturn(serviceTemplate);
+
+ // Response should return the number of node templates present in the service template
+ List<ToscaConceptIdentifier> affectedDefinitions = provider
+ .createAutomationCompositionDefinitions(serviceTemplate).getAffectedAutomationCompositionDefinitions();
+ assertThat(affectedDefinitions).hasSize(13);
+
+ when(acProvider.getFilteredNodeTemplates(any()))
+ .thenReturn(List.of(new ToscaNodeTemplate(), new ToscaNodeTemplate()));
+
+ listOfTemplates = provider.getAutomationCompositionDefinitions(null, null);
+ assertThat(listOfTemplates).hasSize(2);
+ }
+
+ /**
+ * Test the fetching of a full ToscaServiceTemplate object - as opposed to the reduced template that is being
+ * tested in the testGetToscaServiceTemplateReduced() test.
+ *
+ */
+ @Test
+ void testGetToscaServiceTemplate() throws Exception {
+ var serviceTemplateProvider = mock(ServiceTemplateProvider.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var participantProvider = mock(ParticipantProvider.class);
+
+ CommissioningProvider provider =
+ new CommissioningProvider(serviceTemplateProvider, acProvider, null, participantProvider);
+ ToscaServiceTemplate serviceTemplate =
+ InstantiationUtils.getToscaServiceTemplate(COMMON_TOSCA_SERVICE_TEMPLATE_YAML);
+ when(serviceTemplateProvider.createServiceTemplate(serviceTemplate)).thenReturn(serviceTemplate);
+
+ provider.createAutomationCompositionDefinitions(serviceTemplate);
+ verify(serviceTemplateProvider).createServiceTemplate(serviceTemplate);
+
+ when(serviceTemplateProvider.getToscaServiceTemplate(eq(null), eq(null))).thenReturn(serviceTemplate);
+
+ ToscaServiceTemplate returnedServiceTemplate = provider.getToscaServiceTemplate(null, null);
+ assertThat(returnedServiceTemplate).isNotNull();
+
+ Map<String, ToscaNodeTemplate> nodeTemplates =
+ returnedServiceTemplate.getToscaTopologyTemplate().getNodeTemplates();
+
+ assertThat(nodeTemplates).hasSize(8);
+ }
+
+ /**
+ * Test the fetching of a reduced ToscaServiceTemplate with only some of the objects from the full template.
+ * The reduced template does not contain: DataTypesAsMap or PolicyTypesAsMap.
+ *
+ */
+ @Test
+ void testGetToscaServiceTemplateReduced() throws Exception {
+ var serviceTemplateProvider = mock(ServiceTemplateProvider.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var participantProvider = mock(ParticipantProvider.class);
+
+ CommissioningProvider provider =
+ new CommissioningProvider(serviceTemplateProvider, acProvider, null, participantProvider);
+ ToscaServiceTemplate serviceTemplate =
+ InstantiationUtils.getToscaServiceTemplate(COMMON_TOSCA_SERVICE_TEMPLATE_YAML);
+ when(serviceTemplateProvider.createServiceTemplate(serviceTemplate)).thenReturn(serviceTemplate);
+
+ provider.createAutomationCompositionDefinitions(serviceTemplate);
+
+ when(serviceTemplateProvider.getServiceTemplateList(any(), any())).thenReturn(List.of(serviceTemplate));
+
+ String returnedServiceTemplate = provider.getToscaServiceTemplateReduced(null, null);
+ assertThat(returnedServiceTemplate).isNotNull();
+ ToscaServiceTemplate parsedServiceTemplate = CODER.decode(returnedServiceTemplate, ToscaServiceTemplate.class);
+
+ assertThat(parsedServiceTemplate.getToscaTopologyTemplate().getNodeTemplates()).hasSize(8);
+ }
+
+ /**
+ * Tests the different schemas being returned from the schema endpoint. As schemas of the different
+ * sections of the Tosca Service Templates can be returned by the API, this test must cover all of the
+ * different sections.
+ *
+ */
+ @Test
+ void testGetToscaServiceTemplateSchema() throws Exception {
+ var serviceTemplateProvider = mock(ServiceTemplateProvider.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var participantProvider = mock(ParticipantProvider.class);
+
+ CommissioningProvider provider =
+ new CommissioningProvider(serviceTemplateProvider, acProvider, null, participantProvider);
+ ToscaServiceTemplate serviceTemplate =
+ InstantiationUtils.getToscaServiceTemplate(COMMON_TOSCA_SERVICE_TEMPLATE_YAML);
+ when(serviceTemplateProvider.createServiceTemplate(serviceTemplate)).thenReturn(serviceTemplate);
+
+ provider.createAutomationCompositionDefinitions(serviceTemplate);
+
+ mapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
+
+ Map<String, Class<?>> sections = Map.of("all", ToscaServiceTemplate.class, "data_types", ToscaDataType.class,
+ "capability_types", ToscaCapabilityType.class, "node_types", ToscaNodeType.class, "relationship_types",
+ ToscaRelationshipType.class, "policy_types", ToscaPolicyType.class, "topology_template",
+ ToscaTopologyTemplate.class, "node_templates", List.class);
+
+ for (Map.Entry<String, Class<?>> entry : sections.entrySet()) {
+ String returnedServiceTemplateSchema = provider.getToscaServiceTemplateSchema(entry.getKey());
+ assertThat(returnedServiceTemplateSchema).isNotNull();
+
+ var visitor = new SchemaFactoryWrapper();
+
+ if (entry.getKey().equals("node_templates")) {
+ mapper.acceptJsonFormatVisitor(
+ mapper.getTypeFactory().constructCollectionType(List.class, ToscaNodeTemplate.class), visitor);
+ } else {
+ mapper.acceptJsonFormatVisitor(mapper.constructType(entry.getValue()), visitor);
+ }
+
+ var jsonSchema = visitor.finalSchema();
+ String localServiceTemplateSchema = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonSchema);
+ assertThat(localServiceTemplateSchema).isEqualTo(returnedServiceTemplateSchema);
+ }
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java
new file mode 100644
index 000000000..2a49e04c1
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/commissioning/rest/CommissioningControllerTest.java
@@ -0,0 +1,303 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.acm.runtime.commissioning.rest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.List;
+import java.util.Map;
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.parallel.Execution;
+import org.junit.jupiter.api.parallel.ExecutionMode;
+import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController;
+import org.onap.policy.clamp.models.acm.messages.rest.commissioning.CommissioningResponse;
+import org.onap.policy.clamp.models.acm.persistence.provider.ServiceTemplateProvider;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaNodeTemplate;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@TestPropertySource(locations = {"classpath:application_test.properties"})
+@Execution(ExecutionMode.SAME_THREAD)
+class CommissioningControllerTest extends CommonRestController {
+
+ private static final String TOSCA_SERVICE_TEMPLATE_YAML =
+ "src/test/resources/rest/servicetemplates/pmsh_multiple_ac_tosca.yaml";
+ private static final String COMMON_TOSCA_SERVICE_TEMPLATE_YAML =
+ "src/test/resources/rest/servicetemplates/full-tosca-with-common-properties.yaml";
+
+ private static final String COMMISSIONING_ENDPOINT = "commission";
+ private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
+ private static ToscaServiceTemplate commonPropertiesServiceTemplate = new ToscaServiceTemplate();
+
+ @Autowired
+ private ServiceTemplateProvider serviceTemplateProvider;
+
+ @LocalServerPort
+ private int randomServerPort;
+
+ /**
+ * starts Main and inserts a commissioning template.
+ *
+ * @throws Exception if an error occurs
+ */
+ @BeforeAll
+ public static void setUpBeforeClass() throws Exception {
+
+ serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
+ commonPropertiesServiceTemplate =
+ InstantiationUtils.getToscaServiceTemplate(COMMON_TOSCA_SERVICE_TEMPLATE_YAML);
+ }
+
+ @BeforeEach
+ public void setUpPort() {
+ super.setHttpPrefix(randomServerPort);
+ }
+
+ @AfterEach
+ public void cleanDatabase() throws Exception {
+ deleteEntryInDB();
+ }
+
+ @Test
+ void testSwagger() throws Exception {
+ super.testSwagger(COMMISSIONING_ENDPOINT);
+ }
+
+ @Test
+ void testUnauthorizedCreate() throws Exception {
+ assertUnauthorizedPost(COMMISSIONING_ENDPOINT, Entity.json(serviceTemplate));
+ }
+
+ @Test
+ void testUnauthorizedQuery() throws Exception {
+ assertUnauthorizedGet(COMMISSIONING_ENDPOINT);
+ }
+
+ @Test
+ void testUnauthorizedQueryElements() throws Exception {
+ assertUnauthorizedGet(COMMISSIONING_ENDPOINT + "/elements");
+ }
+
+ @Test
+ void testUnauthorizedDelete() throws Exception {
+ assertUnauthorizedDelete(COMMISSIONING_ENDPOINT);
+ }
+
+ @Test
+ void testUnauthorizedQueryToscaServiceTemplate() throws Exception {
+ assertUnauthorizedGet(COMMISSIONING_ENDPOINT + "/toscaservicetemplate");
+ }
+
+ @Test
+ void testUnauthorizedQueryToscaServiceTemplateSchema() throws Exception {
+ assertUnauthorizedGet(COMMISSIONING_ENDPOINT + "/toscaServiceTemplateSchema");
+ }
+
+ @Test
+ void testUnauthorizedQueryToscaServiceCommonOrInstanceProperties() throws Exception {
+ assertUnauthorizedGet(COMMISSIONING_ENDPOINT + "/getCommonOrInstanceProperties");
+ }
+
+ @Test
+ void testQueryToscaServiceTemplate() throws Exception {
+ createFullEntryInDbWithCommonProps();
+
+ Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "/toscaservicetemplate");
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+ ToscaServiceTemplate template = rawresp.readEntity(ToscaServiceTemplate.class);
+ assertNotNull(template);
+ assertThat(template.getNodeTypes()).hasSize(8);
+
+ }
+
+ @Test
+ void testQueryToscaServiceTemplateSchema() throws Exception {
+ createFullEntryInDbWithCommonProps();
+
+ Invocation.Builder invocationBuilder =
+ super.sendRequest(COMMISSIONING_ENDPOINT + "/toscaServiceTemplateSchema");
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+ String schema = rawresp.readEntity(String.class);
+ assertNotNull(schema);
+
+ }
+
+ @Test
+ void testQueryCommonOrInstanceProperties() throws Exception {
+ createFullEntryInDbWithCommonProps();
+
+ Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT
+ + "/getCommonOrInstanceProperties" + "?common=true&name=ToscaServiceTemplateSimple&version=1.0.0");
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+
+ @SuppressWarnings("unchecked")
+ Map<String, ToscaNodeTemplate> commonProperties = rawresp.readEntity(Map.class);
+
+ assertNotNull(commonProperties);
+ assertThat(commonProperties).hasSize(6);
+
+ }
+
+ @Test
+ void testCreateBadRequest() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT);
+ Response resp = invocationBuilder.post(Entity.json("NotToscaServiceTempalte"));
+
+ assertThat(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()).isEqualTo(resp.getStatus());
+ CommissioningResponse commissioningResponse = resp.readEntity(CommissioningResponse.class);
+ assertThat(commissioningResponse.getErrorDetails()).isNotNull();
+ assertThat(commissioningResponse.getAffectedAutomationCompositionDefinitions()).isNull();
+ }
+
+ @Test
+ 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.getAffectedAutomationCompositionDefinitions()).hasSize(13);
+ for (String nodeTemplateName : serviceTemplate.getToscaTopologyTemplate().getNodeTemplates().keySet()) {
+ assertTrue(commissioningResponse.getAffectedAutomationCompositionDefinitions().stream()
+ .anyMatch(ac -> ac.getName().equals(nodeTemplateName)));
+ }
+
+ }
+
+ @Test
+ 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
+ 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
+ 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
+ void testQueryElements() throws Exception {
+ createEntryInDB();
+
+ Invocation.Builder invocationBuilder = super.sendRequest(
+ COMMISSIONING_ENDPOINT + "/elements" + "?name=org.onap.domain.pmsh.PMSHAutomationCompositionDefinition");
+ 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
+ void testDeleteBadRequest() throws Exception {
+ createEntryInDB();
+
+ Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT);
+ // Call delete with no info
+ Response resp = invocationBuilder.delete();
+ assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+
+ }
+
+ @Test
+ void testDelete() throws Exception {
+ var serviceTemplateCreated = createEntryInDB();
+
+ Invocation.Builder invocationBuilder = super.sendRequest(COMMISSIONING_ENDPOINT + "?name="
+ + serviceTemplateCreated.getName() + "&version=" + serviceTemplateCreated.getVersion());
+ // Call delete with no info
+ Response resp = invocationBuilder.delete();
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+ List<ToscaServiceTemplate> templatesInDB = serviceTemplateProvider.getAllServiceTemplates();
+ assertThat(templatesInDB).isEmpty();
+ }
+
+ private synchronized ToscaServiceTemplate createEntryInDB() throws Exception {
+ deleteEntryInDB();
+ return serviceTemplateProvider.createServiceTemplate(serviceTemplate);
+ }
+
+ // Delete entries from the DB after relevant tests
+ private synchronized void deleteEntryInDB() throws Exception {
+ var list = serviceTemplateProvider.getAllServiceTemplates();
+ if (!list.isEmpty()) {
+ serviceTemplateProvider.deleteServiceTemplate(list.get(0).getName(), list.get(0).getVersion());
+ }
+ }
+
+ private synchronized void createFullEntryInDbWithCommonProps() throws Exception {
+ deleteEntryInDB();
+ serviceTemplateProvider.createServiceTemplate(commonPropertiesServiceTemplate);
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivatorTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivatorTest.java
new file mode 100644
index 000000000..dd070fc0b
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/config/messaging/MessageDispatcherActivatorTest.java
@@ -0,0 +1,102 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.acm.runtime.config.messaging;
+
+import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantStatusListener;
+import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.onap.policy.common.utils.coder.StandardCoderObject;
+
+/**
+ * Class to perform unit test of {@link MessageDispatcherActivator}}.
+ *
+ */
+class MessageDispatcherActivatorTest {
+
+ private static final Coder CODER = new StandardCoder();
+
+ private static final String TOPIC_FIRST = "TOPIC1";
+ private static final String TOPIC_SECOND = "TOPIC2";
+
+ @Test
+ void testStartAndStop() throws Exception {
+ AcRuntimeParameterGroup parameterGroup = CommonTestData.geParameterGroup("dbtest");
+
+ var publisherFirst = spy(mock(Publisher.class));
+ var publisherSecond = spy(mock(Publisher.class));
+ var publishers = List.of(publisherFirst, publisherSecond);
+
+ var listenerFirst = spy(mock(ParticipantStatusListener.class));
+ when(listenerFirst.getType()).thenReturn(TOPIC_FIRST);
+ when(listenerFirst.getScoListener()).thenReturn(listenerFirst);
+
+ var listenerSecond = spy(mock(ParticipantStatusListener.class));
+ when(listenerSecond.getType()).thenReturn(TOPIC_SECOND);
+ when(listenerSecond.getScoListener()).thenReturn(listenerSecond);
+
+ List<Listener<ParticipantStatus>> listeners = List.of(listenerFirst, listenerSecond);
+
+ try (var activator = new MessageDispatcherActivator(parameterGroup, publishers, listeners)) {
+
+ assertFalse(activator.isAlive());
+ activator.start();
+ assertTrue(activator.isAlive());
+
+ // repeat start - should throw an exception
+ assertThatIllegalStateException().isThrownBy(() -> activator.start());
+ assertTrue(activator.isAlive());
+ verify(publisherFirst, times(1)).active(anyList());
+ verify(publisherSecond, times(1)).active(anyList());
+
+ StandardCoderObject sco = CODER.decode("{messageType:" + TOPIC_FIRST + "}", StandardCoderObject.class);
+ activator.getMsgDispatcher().onTopicEvent(null, "msg", sco);
+ verify(listenerFirst, times(1)).onTopicEvent(any(), any(), any());
+
+ sco = CODER.decode("{messageType:" + TOPIC_SECOND + "}", StandardCoderObject.class);
+ activator.getMsgDispatcher().onTopicEvent(null, "msg", sco);
+ verify(listenerSecond, times(1)).onTopicEvent(any(), any(), any());
+
+ activator.stop();
+ assertFalse(activator.isAlive());
+
+ // repeat stop - should throw an exception
+ assertThatIllegalStateException().isThrownBy(() -> activator.stop());
+ assertFalse(activator.isAlive());
+ }
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
new file mode 100644
index 000000000..30ed89eac
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/AutomationCompositionInstantiationProviderTest.java
@@ -0,0 +1,394 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.acm.runtime.instantiation;
+
+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.junit.Assert.assertNull;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Optional;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import org.onap.policy.clamp.acm.runtime.commissioning.CommissioningProvider;
+import org.onap.policy.clamp.acm.runtime.supervision.SupervisionHandler;
+import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
+import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationCommand;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
+import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
+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.ToscaServiceTemplate;
+
+/**
+ * Class to perform unit test of {@link AutomationCompositionInstantiationProvider}}.
+ *
+ */
+class AutomationCompositionInstantiationProviderTest {
+ private static final String ID_NAME = "PMSH_Instance1";
+ private static final String ID_VERSION = "1.2.3";
+ private static final String AC_INSTANTIATION_CREATE_JSON =
+ "src/test/resources/rest/acm/AutomationCompositions.json";
+ private static final String AC_INSTANTIATION_UPDATE_JSON =
+ "src/test/resources/rest/acm/AutomationCompositionsUpdate.json";
+ private static final String AC_INSTANTIATION_CHANGE_STATE_JSON = "src/test/resources/rest/acm/PassiveCommand.json";
+ private static final String AC_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON =
+ "src/test/resources/rest/acm/AutomationCompositionElementsNotFound.json";
+ private static final String AC_INSTANTIATION_AC_DEFINITION_NOT_FOUND_JSON =
+ "src/test/resources/rest/acm/AutomationCompositionsNotFound.json";
+ private static final String TOSCA_TEMPLATE_YAML =
+ "src/test/resources/rest/servicetemplates/pmsh_multiple_ac_tosca.yaml";
+ private static final String AUTOMATION_COMPOSITION_NOT_FOUND = "Automation composition not found";
+ private static final String DELETE_BAD_REQUEST = "Automation composition state is still %s";
+ private static final String ORDERED_STATE_INVALID = "ordered state invalid or not specified on command";
+ private static final String AC_ELEMENT_NAME_NOT_FOUND =
+ "\"AutomationCompositions\" INVALID, item has status INVALID\n"
+ + " \"entry org.onap.domain.pmsh.PMSHAutomationCompositionDefinition\" INVALID, item has status INVALID\n"
+ + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not found\n"
+ + " \"entry org.onap.domain.pmsh.PMSHAutomationCompositionDefinition\" INVALID, item has status INVALID\n"
+ + " \"entry org.onap.domain.pmsh.DCAEMicroservice\" INVALID, Not found\n";
+
+ private static final String AC_DEFINITION_NOT_FOUND =
+ "\"AutomationCompositions\" INVALID, item has status INVALID\n"
+ + " \"entry org.onap.domain.PMSHAutomationCompositionDefinition\" INVALID, item has status INVALID\n"
+ + " item \"AutomationComposition\" value \"org.onap.domain.PMSHAutomationCompositionDefinition\""
+ + " INVALID, Commissioned automation composition definition not found\n"
+ + " \"entry org.onap.domain.PMSHAutomationCompositionDefinition\" INVALID, item has status INVALID\n"
+ + " item \"AutomationComposition\" value \"org.onap.domain.PMSHAutomationCompositionDefinition\""
+ + " INVALID, Commissioned automation composition definition not found\n";
+
+ private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
+
+ @BeforeAll
+ public static void setUpBeforeClass() throws Exception {
+ serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML);
+ }
+
+ @Test
+ void testIntanceResponses() throws Exception {
+ var participantProvider = Mockito.mock(ParticipantProvider.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var supervisionHandler = mock(SupervisionHandler.class);
+ var commissioningProvider = mock(CommissioningProvider.class);
+
+ when(commissioningProvider.getAllToscaServiceTemplate()).thenReturn(List.of(serviceTemplate));
+ when(commissioningProvider.getToscaServiceTemplate(ID_NAME, ID_VERSION)).thenReturn(serviceTemplate);
+
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, commissioningProvider,
+ supervisionHandler, participantProvider);
+ var instancePropertyList = instantiationProvider.createInstanceProperties(serviceTemplate);
+ assertNull(instancePropertyList.getErrorDetails());
+ var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION);
+ assertEquals(id, instancePropertyList.getAffectedInstanceProperties().get(0));
+
+ AutomationCompositions automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
+ var automationComposition = automationCompositions.getAutomationCompositionList().get(0);
+ automationComposition.setName(ID_NAME);
+ automationComposition.setVersion(ID_VERSION);
+ when(acProvider.getAutomationCompositions(ID_NAME, ID_VERSION)).thenReturn(List.of(automationComposition));
+
+ var instanceOrderState = instantiationProvider.getInstantiationOrderState(ID_NAME, ID_VERSION);
+ assertEquals(AutomationCompositionOrderedState.UNINITIALISED, instanceOrderState.getOrderedState());
+ assertEquals(ID_NAME, instanceOrderState.getAutomationCompositionIdentifierList().get(0).getName());
+
+ when(acProvider.findAutomationComposition(ID_NAME, ID_VERSION)).thenReturn(Optional.of(automationComposition));
+ when(acProvider.deleteAutomationComposition(ID_NAME, ID_VERSION)).thenReturn(automationComposition);
+
+ var instanceResponse = instantiationProvider.deleteInstanceProperties(ID_NAME, ID_VERSION);
+ assertEquals(ID_NAME, instanceResponse.getAffectedAutomationCompositions().get(0).getName());
+
+ }
+
+ @Test
+ void testInstantiationCrud() throws Exception {
+ var participantProvider = Mockito.mock(ParticipantProvider.class);
+ var participants = CommonTestData.createParticipants();
+ when(participantProvider.getParticipants()).thenReturn(participants);
+
+ var commissioningProvider = mock(CommissioningProvider.class);
+ var toscaNodeTemplate1 = new ToscaNodeTemplate();
+ toscaNodeTemplate1.setName("org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement");
+ toscaNodeTemplate1.setVersion("1.2.3");
+ when(commissioningProvider.getAutomationCompositionDefinitions(anyString(), anyString()))
+ .thenReturn(List.of(toscaNodeTemplate1));
+
+ var toscaNodeTemplate2 = new ToscaNodeTemplate();
+ toscaNodeTemplate2.setName("org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement");
+ toscaNodeTemplate2.setVersion("1.2.3");
+ var toscaNodeTemplate3 = new ToscaNodeTemplate();
+ toscaNodeTemplate3.setName("org.onap.domain.pmsh.PMSH_CDS_AutomationCompositionElement");
+ toscaNodeTemplate3.setVersion("1.2.3");
+ var toscaNodeTemplate4 = new ToscaNodeTemplate();
+ toscaNodeTemplate4.setName("org.onap.domain.pmsh.PMSH_DCAEMicroservice");
+ toscaNodeTemplate4.setVersion("1.2.3");
+
+ when(commissioningProvider.getAutomationCompositionElementDefinitions(toscaNodeTemplate1))
+ .thenReturn(List.of(toscaNodeTemplate1, toscaNodeTemplate2, toscaNodeTemplate3, toscaNodeTemplate4));
+
+ var supervisionHandler = mock(SupervisionHandler.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, commissioningProvider,
+ supervisionHandler, participantProvider);
+ AutomationCompositions automationCompositionsCreate =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
+ InstantiationResponse instantiationResponse =
+ instantiationProvider.createAutomationCompositions(automationCompositionsCreate);
+ InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionsCreate);
+
+ verify(acProvider).saveAutomationCompositions(automationCompositionsCreate.getAutomationCompositionList());
+
+ for (var automationComposition : automationCompositionsCreate.getAutomationCompositionList()) {
+ when(acProvider.getAutomationCompositions(automationComposition.getName(),
+ automationComposition.getVersion())).thenReturn(List.of(automationComposition));
+
+ AutomationCompositions automationCompositionsGet = instantiationProvider
+ .getAutomationCompositions(automationComposition.getName(), automationComposition.getVersion());
+ assertThat(automationCompositionsGet.getAutomationCompositionList()).hasSize(1);
+ assertThat(automationComposition)
+ .isEqualTo(automationCompositionsGet.getAutomationCompositionList().get(0));
+ }
+
+ AutomationCompositions automationCompositionsUpdate =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_UPDATE_JSON, "Crud");
+
+ instantiationResponse = instantiationProvider.updateAutomationCompositions(automationCompositionsUpdate);
+ InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionsUpdate);
+
+ verify(acProvider).saveAutomationCompositions(automationCompositionsUpdate.getAutomationCompositionList());
+
+ for (var automationComposition : automationCompositionsUpdate.getAutomationCompositionList()) {
+ when(acProvider.findAutomationComposition(automationComposition.getKey().asIdentifier()))
+ .thenReturn(Optional.of(automationComposition));
+ when(acProvider.findAutomationComposition(automationComposition.getName(),
+ automationComposition.getVersion())).thenReturn(Optional.of(automationComposition));
+ when(acProvider.deleteAutomationComposition(automationComposition.getName(),
+ automationComposition.getVersion())).thenReturn(automationComposition);
+ }
+
+ InstantiationCommand instantiationCommand =
+ InstantiationUtils.getInstantiationCommandFromResource(AC_INSTANTIATION_CHANGE_STATE_JSON, "Crud");
+ instantiationResponse = instantiationProvider.issueAutomationCompositionCommand(instantiationCommand);
+ InstantiationUtils.assertInstantiationResponse(instantiationResponse, instantiationCommand);
+
+ verify(supervisionHandler)
+ .triggerAutomationCompositionSupervision(instantiationCommand.getAutomationCompositionIdentifierList());
+
+ // in order to delete a automationComposition the state must be UNINITIALISED
+ automationCompositionsCreate.getAutomationCompositionList()
+ .forEach(ac -> ac.setState(AutomationCompositionState.UNINITIALISED));
+ instantiationProvider.updateAutomationCompositions(automationCompositionsCreate);
+
+ for (AutomationComposition automationComposition : automationCompositionsCreate
+ .getAutomationCompositionList()) {
+ instantiationProvider.deleteAutomationComposition(automationComposition.getName(),
+ automationComposition.getVersion());
+
+ verify(acProvider).deleteAutomationComposition(automationComposition.getName(),
+ automationComposition.getVersion());
+ }
+ }
+
+ @Test
+ void testInstantiationDelete() throws Exception {
+
+ AutomationCompositions automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "Delete");
+
+ AutomationComposition automationComposition0 = automationCompositions.getAutomationCompositionList().get(0);
+ var participantProvider = Mockito.mock(ParticipantProvider.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var supervisionHandler = mock(SupervisionHandler.class);
+ var commissioningProvider = mock(CommissioningProvider.class);
+
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, commissioningProvider,
+ supervisionHandler, participantProvider);
+
+ assertThatThrownBy(() -> instantiationProvider.deleteAutomationComposition(automationComposition0.getName(),
+ automationComposition0.getVersion())).hasMessageMatching(AUTOMATION_COMPOSITION_NOT_FOUND);
+
+ for (AutomationCompositionState state : AutomationCompositionState.values()) {
+ if (!AutomationCompositionState.UNINITIALISED.equals(state)) {
+ assertThatDeleteThrownBy(automationCompositions, state);
+ }
+ }
+ automationComposition0.setState(AutomationCompositionState.UNINITIALISED);
+
+ for (AutomationComposition automationComposition : automationCompositions.getAutomationCompositionList()) {
+ when(acProvider.findAutomationComposition(automationComposition.getName(),
+ automationComposition.getVersion())).thenReturn(Optional.of(automationComposition));
+ when(acProvider.deleteAutomationComposition(automationComposition.getName(),
+ automationComposition.getVersion())).thenReturn(automationComposition);
+
+ instantiationProvider.deleteAutomationComposition(automationComposition.getName(),
+ automationComposition.getVersion());
+ }
+ }
+
+ private void assertThatDeleteThrownBy(AutomationCompositions automationCompositions,
+ AutomationCompositionState state) throws Exception {
+ AutomationComposition automationComposition = automationCompositions.getAutomationCompositionList().get(0);
+ automationComposition.setState(state);
+ var participantProvider = Mockito.mock(ParticipantProvider.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var supervisionHandler = mock(SupervisionHandler.class);
+ var commissioningProvider = mock(CommissioningProvider.class);
+
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, commissioningProvider,
+ supervisionHandler, participantProvider);
+
+ when(acProvider.findAutomationComposition(automationComposition.getName(), automationComposition.getVersion()))
+ .thenReturn(Optional.of(automationComposition));
+
+ assertThatThrownBy(() -> instantiationProvider.deleteAutomationComposition(automationComposition.getName(),
+ automationComposition.getVersion())).hasMessageMatching(String.format(DELETE_BAD_REQUEST, state));
+ }
+
+ @Test
+ void testCreateAutomationCompositions_NoDuplicates() throws Exception {
+ var commissioningProvider = mock(CommissioningProvider.class);
+
+ var toscaNodeTemplate1 = new ToscaNodeTemplate();
+ toscaNodeTemplate1.setName("org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement");
+ toscaNodeTemplate1.setVersion("1.2.3");
+ when(commissioningProvider.getAutomationCompositionDefinitions(anyString(), anyString()))
+ .thenReturn(List.of(toscaNodeTemplate1));
+
+ var toscaNodeTemplate2 = new ToscaNodeTemplate();
+ toscaNodeTemplate2.setName("org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement");
+ toscaNodeTemplate2.setVersion("1.2.3");
+ var toscaNodeTemplate3 = new ToscaNodeTemplate();
+ toscaNodeTemplate3.setName("org.onap.domain.pmsh.PMSH_CDS_AutomationCompositionElement");
+ toscaNodeTemplate3.setVersion("1.2.3");
+ var toscaNodeTemplate4 = new ToscaNodeTemplate();
+ toscaNodeTemplate4.setName("org.onap.domain.pmsh.PMSH_DCAEMicroservice");
+ toscaNodeTemplate4.setVersion("1.2.3");
+
+ when(commissioningProvider.getAutomationCompositionElementDefinitions(toscaNodeTemplate1))
+ .thenReturn(List.of(toscaNodeTemplate1, toscaNodeTemplate2, toscaNodeTemplate3, toscaNodeTemplate4));
+
+ AutomationCompositions automationCompositionsCreate =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "NoDuplicates");
+
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var participantProvider = Mockito.mock(ParticipantProvider.class);
+ var supervisionHandler = mock(SupervisionHandler.class);
+
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, commissioningProvider,
+ supervisionHandler, participantProvider);
+
+ InstantiationResponse instantiationResponse =
+ instantiationProvider.createAutomationCompositions(automationCompositionsCreate);
+ InstantiationUtils.assertInstantiationResponse(instantiationResponse, automationCompositionsCreate);
+
+ when(acProvider.findAutomationComposition(
+ automationCompositionsCreate.getAutomationCompositionList().get(0).getKey().asIdentifier()))
+ .thenReturn(Optional.of(automationCompositionsCreate.getAutomationCompositionList().get(0)));
+
+ assertThatThrownBy(() -> instantiationProvider.createAutomationCompositions(automationCompositionsCreate))
+ .hasMessageMatching(
+ automationCompositionsCreate.getAutomationCompositionList().get(0).getKey().asIdentifier()
+ + " already defined");
+ }
+
+ @Test
+ void testCreateAutomationCompositions_CommissionedAcElementNotFound() throws Exception {
+ var toscaNodeTemplate1 = new ToscaNodeTemplate();
+ toscaNodeTemplate1.setName("org.onap.domain.pmsh.PMSH_MonitoringPolicyAutomationCompositionElement");
+ toscaNodeTemplate1.setVersion("1.2.3");
+
+ var toscaNodeTemplate2 = new ToscaNodeTemplate();
+ toscaNodeTemplate2.setName("org.onap.domain.pmsh.PMSH_OperationalPolicyAutomationCompositionElement");
+ toscaNodeTemplate2.setVersion("1.2.3");
+ var toscaNodeTemplate3 = new ToscaNodeTemplate();
+ toscaNodeTemplate3.setName("org.onap.domain.pmsh.PMSH_CDS_AutomationCompositionElement");
+ toscaNodeTemplate3.setVersion("1.2.3");
+ var commissioningProvider = mock(CommissioningProvider.class);
+ AutomationCompositions automationCompositions = InstantiationUtils.getAutomationCompositionsFromResource(
+ AC_INSTANTIATION_DEFINITION_NAME_NOT_FOUND_JSON, "AcElementNotFound");
+
+ when(commissioningProvider.getAutomationCompositionDefinitions(
+ automationCompositions.getAutomationCompositionList().get(0).getDefinition().getName(),
+ automationCompositions.getAutomationCompositionList().get(0).getDefinition().getVersion()))
+ .thenReturn(List.of(toscaNodeTemplate1));
+
+ when(commissioningProvider.getAutomationCompositionElementDefinitions(toscaNodeTemplate1))
+ .thenReturn(List.of(toscaNodeTemplate1, toscaNodeTemplate2, toscaNodeTemplate3));
+
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var participantProvider = mock(ParticipantProvider.class);
+ var supervisionHandler = mock(SupervisionHandler.class);
+ var provider = new AutomationCompositionInstantiationProvider(acProvider, commissioningProvider,
+ supervisionHandler, participantProvider);
+
+ assertThatThrownBy(() -> provider.createAutomationCompositions(automationCompositions))
+ .hasMessageMatching(AC_ELEMENT_NAME_NOT_FOUND);
+
+ assertThatThrownBy(() -> provider.updateAutomationCompositions(automationCompositions))
+ .hasMessageMatching(AC_ELEMENT_NAME_NOT_FOUND);
+ }
+
+ @Test
+ void testCreateAutomationCompositions_CommissionedAcNotFound() throws Exception {
+ AutomationCompositions automationCompositions = InstantiationUtils
+ .getAutomationCompositionsFromResource(AC_INSTANTIATION_AC_DEFINITION_NOT_FOUND_JSON, "AcNotFound");
+
+ var participantProvider = Mockito.mock(ParticipantProvider.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var supervisionHandler = mock(SupervisionHandler.class);
+ var commissioningProvider = mock(CommissioningProvider.class);
+ var provider = new AutomationCompositionInstantiationProvider(acProvider, commissioningProvider,
+ supervisionHandler, participantProvider);
+
+ assertThatThrownBy(() -> provider.createAutomationCompositions(automationCompositions))
+ .hasMessageMatching(AC_DEFINITION_NOT_FOUND);
+
+ assertThatThrownBy(() -> provider.updateAutomationCompositions(automationCompositions))
+ .hasMessageMatching(AC_DEFINITION_NOT_FOUND);
+ }
+
+ @Test
+ void testIssueAutomationCompositionCommand_OrderedStateInvalid()
+ throws AutomationCompositionRuntimeException, IOException {
+ var participantProvider = Mockito.mock(ParticipantProvider.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var supervisionHandler = mock(SupervisionHandler.class);
+ var commissioningProvider = mock(CommissioningProvider.class);
+ var instantiationProvider = new AutomationCompositionInstantiationProvider(acProvider, commissioningProvider,
+ supervisionHandler, participantProvider);
+ assertThatThrownBy(() -> instantiationProvider.issueAutomationCompositionCommand(new InstantiationCommand()))
+ .hasMessageMatching(ORDERED_STATE_INVALID);
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/InstantiationUtils.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/InstantiationUtils.java
new file mode 100644
index 000000000..759685ad9
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/InstantiationUtils.java
@@ -0,0 +1,147 @@
+/*-
+ * ============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.acm.runtime.instantiation;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+
+import java.io.File;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationCommand;
+import org.onap.policy.clamp.models.acm.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.StandardYamlCoder;
+import org.onap.policy.common.utils.resources.ResourceUtils;
+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 StandardYamlCoder YAML_TRANSLATOR = new StandardYamlCoder();
+
+ /**
+ * Gets the AutomationCompositions from Resource.
+ *
+ * @param path path of the resource
+ * @param suffix suffix to add to all names in AutomationCompositions
+ * @return the AutomationCompositions from Resource
+ * @throws CoderException if an error occurs
+ */
+ public static AutomationCompositions getAutomationCompositionsFromResource(final String path, final String suffix)
+ throws CoderException {
+ AutomationCompositions automationCompositions = CODER.decode(new File(path), AutomationCompositions.class);
+
+ // add suffix to all names
+ automationCompositions.getAutomationCompositionList()
+ .forEach(automationComposition -> automationComposition.setName(automationComposition.getName() + suffix));
+ return automationCompositions;
+ }
+
+ /**
+ * Gets InstantiationCommand from Resource.
+ *
+ * @param path path of the resource
+ * @param suffix suffix to add to all names in AutomationCompositions
+ * @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.getAutomationCompositionIdentifierList().forEach(ac -> ac.setName(ac.getName() + suffix));
+ return instantiationCommand;
+ }
+
+ /**
+ * Assert that Instantiation Response contains proper AutomationCompositions.
+ *
+ * @param response InstantiationResponse
+ * @param automationCompositions AutomationCompositions
+ */
+ public static void assertInstantiationResponse(InstantiationResponse response,
+ AutomationCompositions automationCompositions) {
+ assertThat(response).isNotNull();
+ assertThat(response.getErrorDetails()).isNull();
+ assertThat(response.getAffectedAutomationCompositions().size())
+ .isEqualTo(automationCompositions.getAutomationCompositionList().size());
+ for (AutomationComposition automationComposition : automationCompositions.getAutomationCompositionList()) {
+ assertTrue(response.getAffectedAutomationCompositions().stream()
+ .filter(ac -> ac.equals(automationComposition.getKey().asIdentifier())).findAny().isPresent());
+ }
+ }
+
+ /**
+ * Assert that Instantiation Response contains proper AutomationCompositions.
+ *
+ * @param response InstantiationResponse
+ * @param command InstantiationCommand
+ */
+ public static void assertInstantiationResponse(InstantiationResponse response, InstantiationCommand command) {
+ assertThat(response).isNotNull();
+ assertEquals(response.getAffectedAutomationCompositions().size(),
+ command.getAutomationCompositionIdentifierList().size());
+ for (ToscaConceptIdentifier toscaConceptIdentifier : command.getAutomationCompositionIdentifierList()) {
+ assertTrue(response.getAffectedAutomationCompositions().stream()
+ .filter(ac -> ac.compareTo(toscaConceptIdentifier) == 0).findAny().isPresent());
+ }
+ }
+
+ /**
+ * Assert that Instantiation Response contains AutomationComposition equals to automationComposition.
+ *
+ * @param response InstantiationResponse
+ * @param automationComposition AutomationComposition
+ */
+ public static void assertInstantiationResponse(InstantiationResponse response,
+ AutomationComposition automationComposition) {
+ assertThat(response).isNotNull();
+ assertThat(response.getErrorDetails()).isNull();
+ assertEquals(1, response.getAffectedAutomationCompositions().size());
+ assertEquals(0, response.getAffectedAutomationCompositions().get(0)
+ .compareTo(automationComposition.getKey().asIdentifier()));
+ }
+
+ /**
+ * Get ToscaServiceTemplate from resource.
+ *
+ * @param path path of the resource
+ */
+ public static ToscaServiceTemplate getToscaServiceTemplate(String path) {
+
+ try {
+ return YAML_TRANSLATOR.decode(ResourceUtils.getResourceAsStream(path), ToscaServiceTemplate.class);
+ } catch (CoderException e) {
+ fail("Cannot read or decode " + path);
+ return null;
+ }
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java
new file mode 100644
index 000000000..2ad15bd48
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/instantiation/rest/InstantiationControllerTest.java
@@ -0,0 +1,543 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.acm.runtime.instantiation.rest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+import javax.ws.rs.client.Entity;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.onap.policy.clamp.acm.runtime.instantiation.AutomationCompositionInstantiationProvider;
+import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.acm.runtime.main.rest.InstantiationController;
+import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
+import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AutomationCompositionOrderStateResponse;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AutomationCompositionPrimedResponse;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstancePropertiesResponse;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationCommand;
+import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
+import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ServiceTemplateProvider;
+import org.onap.policy.clamp.models.acm.persistence.repository.AutomationCompositionRepository;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+/**
+ * Class to perform unit test of {@link InstantiationController}}.
+ *
+ */
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@TestPropertySource(locations = {"classpath:application_test.properties"})
+class InstantiationControllerTest extends CommonRestController {
+
+ private static final String ID_NAME = "PMSH_Instance1";
+ private static final String ID_VERSION = "1.2.3";
+
+ private static final String AC_INSTANTIATION_CREATE_JSON =
+ "src/test/resources/rest/acm/AutomationCompositions.json";
+
+ private static final String AC_INSTANTIATION_UPDATE_JSON =
+ "src/test/resources/rest/acm/AutomationCompositionsUpdate.json";
+
+ private static final String AC_INSTANTIATION_CHANGE_STATE_JSON = "src/test/resources/rest/acm/PassiveCommand.json";
+
+ private static final String TOSCA_TEMPLATE_YAML =
+ "src/test/resources/rest/servicetemplates/pmsh_multiple_ac_tosca.yaml";
+
+ private static final String INSTANTIATION_ENDPOINT = "instantiation";
+ private static final String INSTANTIATION_COMMAND_ENDPOINT = "instantiation/command";
+ private static final String PRIMING_ENDPOINT = "automationCompositionPriming";
+ private static final String INSTANTIATION_PROPERTIES = "instanceProperties";
+ private static final String INSTANTIATION_STATE = "instantiationState";
+
+ private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
+
+ @Autowired
+ private AutomationCompositionRepository automationCompositionRepository;
+
+ @Autowired
+ private ServiceTemplateProvider serviceTemplateProvider;
+
+ @Autowired
+ private AutomationCompositionInstantiationProvider instantiationProvider;
+
+ @Autowired
+ private ParticipantProvider participantProvider;
+
+ @LocalServerPort
+ private int randomServerPort;
+
+ @BeforeAll
+ public static void setUpBeforeClass() throws Exception {
+ serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML);
+ }
+
+ @BeforeEach
+ public void populateDb() throws Exception {
+ createEntryInDB();
+ }
+
+ @BeforeEach
+ public void setUpPort() {
+ super.setHttpPrefix(randomServerPort);
+ }
+
+ @AfterEach
+ public void cleanDatabase() throws Exception {
+ deleteEntryInDB();
+ }
+
+ @Test
+ void testSwagger() throws Exception {
+ super.testSwagger(INSTANTIATION_ENDPOINT);
+ }
+
+ @Test
+ void testCreate_Unauthorized() throws Exception {
+ AutomationCompositions automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "Unauthorized");
+
+ assertUnauthorizedPost(INSTANTIATION_ENDPOINT, Entity.json(automationCompositions));
+ }
+
+ @Test
+ void testQuery_Unauthorized() throws Exception {
+ assertUnauthorizedGet(INSTANTIATION_ENDPOINT);
+ }
+
+ @Test
+ void testUpdate_Unauthorized() throws Exception {
+ AutomationCompositions automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_UPDATE_JSON, "Unauthorized");
+
+ assertUnauthorizedPut(INSTANTIATION_ENDPOINT, Entity.json(automationCompositions));
+ }
+
+ @Test
+ void testDelete_Unauthorized() throws Exception {
+ assertUnauthorizedDelete(INSTANTIATION_ENDPOINT);
+ }
+
+ @Test
+ void testCommand_Unauthorized() throws Exception {
+ InstantiationCommand instantiationCommand =
+ InstantiationUtils.getInstantiationCommandFromResource(AC_INSTANTIATION_CHANGE_STATE_JSON, "Unauthorized");
+
+ assertUnauthorizedPut(INSTANTIATION_COMMAND_ENDPOINT, Entity.json(instantiationCommand));
+ }
+
+ @Test
+ void testCreate() throws Exception {
+
+ AutomationCompositions automationCompositionsFromRsc =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "Create");
+
+ Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT);
+ Response resp = invocationBuilder.post(Entity.json(automationCompositionsFromRsc));
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+ InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+ InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionsFromRsc);
+
+ for (AutomationComposition automationCompositionFromRsc : automationCompositionsFromRsc
+ .getAutomationCompositionList()) {
+ AutomationCompositions automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(
+ automationCompositionFromRsc.getKey().getName(), automationCompositionFromRsc.getKey().getVersion());
+
+ assertNotNull(automationCompositionsFromDb);
+ assertThat(automationCompositionsFromDb.getAutomationCompositionList()).hasSize(1);
+ assertEquals(automationCompositionFromRsc,
+ automationCompositionsFromDb.getAutomationCompositionList().get(0));
+ }
+
+ invocationBuilder =
+ super.sendRequest(PRIMING_ENDPOINT + "?name=" + "PMSHInstance0Create" + "&version=" + "1.0.1");
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+ AutomationCompositionPrimedResponse primResponse =
+ rawresp.readEntity(AutomationCompositionPrimedResponse.class);
+ assertEquals(false, primResponse.getPrimedAutomationCompositionsList().get(0).isPrimed());
+ }
+
+ @Test
+ void testCreateBadRequest() throws Exception {
+
+ AutomationCompositions automationCompositionsFromRsc =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "CreateBadRequest");
+
+ Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT);
+ Response resp = invocationBuilder.post(Entity.json(automationCompositionsFromRsc));
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+ // testing Bad Request: AC already defined
+ resp = invocationBuilder.post(Entity.json(automationCompositionsFromRsc));
+ assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+ InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+ assertNotNull(instResponse.getErrorDetails());
+ assertNull(instResponse.getAffectedAutomationCompositions());
+ }
+
+ @Test
+ 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());
+ AutomationCompositions resp = rawresp.readEntity(AutomationCompositions.class);
+ assertThat(resp.getAutomationCompositionList()).isEmpty();
+ }
+
+ @Test
+ void testQuery() throws Exception {
+
+ var automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "Query");
+ instantiationProvider.createAutomationCompositions(automationCompositions);
+
+ for (AutomationComposition automationCompositionFromRsc : automationCompositions
+ .getAutomationCompositionList()) {
+ Invocation.Builder invocationBuilder =
+ super.sendRequest(INSTANTIATION_ENDPOINT + "?name=" + automationCompositionFromRsc.getKey().getName());
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+ AutomationCompositions automationCompositionsQuery = rawresp.readEntity(AutomationCompositions.class);
+ assertNotNull(automationCompositionsQuery);
+ assertThat(automationCompositionsQuery.getAutomationCompositionList()).hasSize(1);
+ assertEquals(automationCompositionFromRsc,
+ automationCompositionsQuery.getAutomationCompositionList().get(0));
+ }
+ }
+
+ @Test
+ void testUpdate() throws Exception {
+
+ AutomationCompositions automationCompositionsCreate =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "Update");
+
+ var automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_UPDATE_JSON, "Update");
+ instantiationProvider.createAutomationCompositions(automationCompositionsCreate);
+
+ Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT);
+ Response resp = invocationBuilder.put(Entity.json(automationCompositions));
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+ InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+ InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositions);
+
+ for (AutomationComposition automationCompositionUpdate : automationCompositions
+ .getAutomationCompositionList()) {
+ AutomationCompositions automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(
+ automationCompositionUpdate.getKey().getName(), automationCompositionUpdate.getKey().getVersion());
+
+ assertNotNull(automationCompositionsFromDb);
+ assertThat(automationCompositionsFromDb.getAutomationCompositionList()).hasSize(1);
+ assertEquals(automationCompositionUpdate,
+ automationCompositionsFromDb.getAutomationCompositionList().get(0));
+ }
+ }
+
+ @Test
+ void testDelete_NoResultWithThisName() throws Exception {
+ Invocation.Builder invocationBuilder =
+ super.sendRequest(INSTANTIATION_ENDPOINT + "?name=noResultWithThisName&version=1.0.1");
+ Response resp = invocationBuilder.delete();
+ assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus());
+ InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+ assertNotNull(instResponse.getErrorDetails());
+ assertNull(instResponse.getAffectedAutomationCompositions());
+ }
+
+ @Test
+ void testDelete() throws Exception {
+
+ AutomationCompositions automationCompositionsFromRsc =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "Delete");
+
+ instantiationProvider.createAutomationCompositions(automationCompositionsFromRsc);
+
+ for (AutomationComposition automationCompositionFromRsc : automationCompositionsFromRsc
+ .getAutomationCompositionList()) {
+ Invocation.Builder invocationBuilder =
+ super.sendRequest(INSTANTIATION_ENDPOINT + "?name=" + automationCompositionFromRsc.getKey().getName()
+ + "&version=" + automationCompositionFromRsc.getKey().getVersion());
+ Response resp = invocationBuilder.delete();
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+ InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+ InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionFromRsc);
+
+ AutomationCompositions automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(
+ automationCompositionFromRsc.getKey().getName(), automationCompositionFromRsc.getKey().getVersion());
+ assertThat(automationCompositionsFromDb.getAutomationCompositionList()).isEmpty();
+ }
+ }
+
+ @Test
+ void testDeleteBadRequest() throws Exception {
+
+ AutomationCompositions automationCompositionsFromRsc =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "DelBadRequest");
+
+ instantiationProvider.createAutomationCompositions(automationCompositionsFromRsc);
+
+ for (AutomationComposition automationCompositionFromRsc : automationCompositionsFromRsc
+ .getAutomationCompositionList()) {
+ Invocation.Builder invocationBuilder =
+ super.sendRequest(INSTANTIATION_ENDPOINT + "?name=" + automationCompositionFromRsc.getKey().getName());
+ Response resp = invocationBuilder.delete();
+ assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+ }
+ }
+
+ @Test
+ void testCreateInstanceProperties() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_PROPERTIES);
+ Response resp = invocationBuilder.post(Entity.json(serviceTemplate));
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+ var instancePropertyList = resp.readEntity(InstancePropertiesResponse.class);
+ assertNull(instancePropertyList.getErrorDetails());
+ var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION);
+ assertEquals(id, instancePropertyList.getAffectedInstanceProperties().get(0));
+
+ invocationBuilder = super.sendRequest(INSTANTIATION_ENDPOINT);
+ resp = invocationBuilder.get();
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+ var automationCompositionsGet = resp.readEntity(AutomationCompositions.class);
+ assertThat(automationCompositionsGet.getAutomationCompositionList()).hasSize(1);
+ }
+
+ @Test
+ void testDeleteInstanceProperties() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_PROPERTIES);
+ Response resp = invocationBuilder.post(Entity.json(serviceTemplate));
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+ invocationBuilder = super.sendRequest(INSTANTIATION_PROPERTIES + "?name=" + ID_NAME + "&version=" + ID_VERSION);
+ resp = invocationBuilder.delete();
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+ var instanceResponse = resp.readEntity(InstantiationResponse.class);
+ assertEquals(ID_NAME, instanceResponse.getAffectedAutomationCompositions().get(0).getName());
+ AutomationCompositions automationCompositionsGet =
+ instantiationProvider.getAutomationCompositions(ID_NAME, ID_VERSION);
+ assertThat(automationCompositionsGet.getAutomationCompositionList()).isEmpty();
+ }
+
+ @Test
+ void testDeleteInstancePropertiesBadRequest() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_PROPERTIES);
+ Response resp = invocationBuilder.post(Entity.json(serviceTemplate));
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+ invocationBuilder = super.sendRequest(INSTANTIATION_PROPERTIES + "?name=" + ID_NAME);
+ resp = invocationBuilder.delete();
+ assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+ }
+
+ @Test
+ void testDeleteInstancePropertiesPassiveMode() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_PROPERTIES);
+ Response resp = invocationBuilder.post(Entity.json(serviceTemplate));
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+ var automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "Command");
+ instantiationProvider.createAutomationCompositions(automationCompositions);
+
+ var participants = CommonTestData.createParticipants();
+ for (var participant : participants) {
+ participantProvider.saveParticipant(participant);
+ }
+
+ InstantiationCommand command =
+ InstantiationUtils.getInstantiationCommandFromResource(AC_INSTANTIATION_CHANGE_STATE_JSON, "Command");
+
+ invocationBuilder = super.sendRequest(INSTANTIATION_COMMAND_ENDPOINT);
+ 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 and delete properties
+ for (ToscaConceptIdentifier toscaConceptIdentifier : command.getAutomationCompositionIdentifierList()) {
+ AutomationCompositions automationCompositionsGet = instantiationProvider
+ .getAutomationCompositions(toscaConceptIdentifier.getName(), toscaConceptIdentifier.getVersion());
+ assertThat(automationCompositionsGet.getAutomationCompositionList()).hasSize(1);
+ assertEquals(command.getOrderedState(),
+ automationCompositionsGet.getAutomationCompositionList().get(0).getOrderedState());
+
+ invocationBuilder = super.sendRequest(INSTANTIATION_PROPERTIES + "?name=" + toscaConceptIdentifier.getName()
+ + "&version=" + toscaConceptIdentifier.getVersion());
+ resp = invocationBuilder.delete();
+ assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+ }
+ }
+
+ @Test
+ 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
+ void testCommand_NotFound2() throws Exception {
+ InstantiationCommand command =
+ InstantiationUtils.getInstantiationCommandFromResource(AC_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
+ void testCommand() throws Exception {
+ var automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "Command");
+ instantiationProvider.createAutomationCompositions(automationCompositions);
+
+ var participants = CommonTestData.createParticipants();
+ for (var participant : participants) {
+ participantProvider.saveParticipant(participant);
+ }
+
+ InstantiationCommand command =
+ InstantiationUtils.getInstantiationCommandFromResource(AC_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
+ for (ToscaConceptIdentifier toscaConceptIdentifier : command.getAutomationCompositionIdentifierList()) {
+ AutomationCompositions automationCompositionsGet = instantiationProvider
+ .getAutomationCompositions(toscaConceptIdentifier.getName(), toscaConceptIdentifier.getVersion());
+ assertThat(automationCompositionsGet.getAutomationCompositionList()).hasSize(1);
+ assertEquals(command.getOrderedState(),
+ automationCompositionsGet.getAutomationCompositionList().get(0).getOrderedState());
+ }
+ }
+
+ @Test
+ void testIntanceProperties() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_PROPERTIES);
+ Response resp = invocationBuilder.post(Entity.json(serviceTemplate));
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+ var instancePropertyList = resp.readEntity(InstancePropertiesResponse.class);
+ assertNull(instancePropertyList.getErrorDetails());
+ var id = new ToscaConceptIdentifier(ID_NAME, ID_VERSION);
+ assertEquals(id, instancePropertyList.getAffectedInstanceProperties().get(0));
+
+ invocationBuilder = super.sendRequest(INSTANTIATION_STATE + "?name=" + ID_NAME + "&version=" + ID_VERSION);
+ resp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+ var instanceOrderState = resp.readEntity(AutomationCompositionOrderStateResponse.class);
+ assertEquals(AutomationCompositionOrderedState.UNINITIALISED, instanceOrderState.getOrderedState());
+ assertEquals(ID_NAME, instanceOrderState.getAutomationCompositionIdentifierList().get(0).getName());
+ AutomationCompositions automationCompositionsGet =
+ instantiationProvider.getAutomationCompositions(ID_NAME, ID_VERSION);
+ assertThat(automationCompositionsGet.getAutomationCompositionList()).hasSize(1);
+
+ invocationBuilder = super.sendRequest(INSTANTIATION_PROPERTIES + "?name=" + ID_NAME + "&version=" + ID_VERSION);
+ resp = invocationBuilder.delete();
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+ var instanceResponse = resp.readEntity(InstantiationResponse.class);
+ assertEquals(ID_NAME, instanceResponse.getAffectedAutomationCompositions().get(0).getName());
+ automationCompositionsGet = instantiationProvider.getAutomationCompositions(ID_NAME, ID_VERSION);
+ assertThat(automationCompositionsGet.getAutomationCompositionList()).isEmpty();
+ }
+
+ @Test
+ void testChangeOrderStateFromUninitializedPassiveMode() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_PROPERTIES);
+ Response resp = invocationBuilder.post(Entity.json(serviceTemplate));
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+ var automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "CommandPassive");
+ instantiationProvider.createAutomationCompositions(automationCompositions);
+
+ var participants = CommonTestData.createParticipants();
+ for (var participant : participants) {
+ participantProvider.saveParticipant(participant);
+ }
+
+ InstantiationCommand command = InstantiationUtils
+ .getInstantiationCommandFromResource(AC_INSTANTIATION_CHANGE_STATE_JSON, "CommandPassive");
+
+ invocationBuilder = super.sendRequest(INSTANTIATION_COMMAND_ENDPOINT);
+ resp = invocationBuilder.put(Entity.json(command));
+ assertEquals(Response.Status.ACCEPTED.getStatusCode(), resp.getStatus());
+ InstantiationResponse instResponse = resp.readEntity(InstantiationResponse.class);
+ InstantiationUtils.assertInstantiationResponse(instResponse, command);
+ }
+
+ @Test
+ void testChangeOrderStateWithoutRegisteredParticipants() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendRequest(INSTANTIATION_PROPERTIES);
+ Response resp = invocationBuilder.post(Entity.json(serviceTemplate));
+ assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
+
+ var automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "CommandPassive");
+ instantiationProvider.createAutomationCompositions(automationCompositions);
+
+ InstantiationCommand command = InstantiationUtils
+ .getInstantiationCommandFromResource(AC_INSTANTIATION_CHANGE_STATE_JSON, "CommandPassive");
+
+ invocationBuilder = super.sendRequest(INSTANTIATION_COMMAND_ENDPOINT);
+ resp = invocationBuilder.put(Entity.json(command));
+ assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
+ }
+
+ private synchronized void deleteEntryInDB() throws Exception {
+ automationCompositionRepository.deleteAll();
+ var list = serviceTemplateProvider.getAllServiceTemplates();
+ if (!list.isEmpty()) {
+ serviceTemplateProvider.deleteServiceTemplate(list.get(0).getName(), list.get(0).getVersion());
+ }
+ }
+
+ private synchronized void createEntryInDB() throws Exception {
+ deleteEntryInDB();
+ serviceTemplateProvider.createServiceTemplate(serviceTemplate);
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/ActuatorControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/ActuatorControllerTest.java
new file mode 100644
index 000000000..553a4721b
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/main/rest/ActuatorControllerTest.java
@@ -0,0 +1,91 @@
+/*-
+ * ============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.acm.runtime.main.rest;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController;
+import org.springframework.boot.test.autoconfigure.actuate.metrics.AutoConfigureMetrics;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@AutoConfigureMetrics
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@TestPropertySource(locations = {"classpath:application_test.properties"})
+class ActuatorControllerTest extends CommonRestController {
+
+ private static final String HEALTH_ENDPOINT = "health";
+ private static final String METRICS_ENDPOINT = "metrics";
+ private static final String PROMETHEUS_ENDPOINT = "prometheus";
+
+ @LocalServerPort
+ private int randomServerPort;
+
+ @BeforeEach
+ public void setUpPort() {
+ super.setHttpPrefix(randomServerPort);
+ }
+
+ @Test
+ void testGetHealth_Unauthorized() throws Exception {
+ assertUnauthorizedActGet(HEALTH_ENDPOINT);
+ }
+
+ @Test
+ void testGetMetrics_Unauthorized() throws Exception {
+ assertUnauthorizedActGet(METRICS_ENDPOINT);
+ }
+
+ @Test
+ void testGetPrometheus_Unauthorized() throws Exception {
+ assertUnauthorizedActGet(PROMETHEUS_ENDPOINT);
+ }
+
+ @Test
+ void testGetHealth() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendActRequest(HEALTH_ENDPOINT);
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+ }
+
+ @Test
+ void testGetMetrics() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendActRequest(METRICS_ENDPOINT);
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+ }
+
+ @Test
+ void testGePrometheus() throws Exception {
+ Invocation.Builder invocationBuilder = super.sendActRequest(PROMETHEUS_ENDPOINT);
+ Response rawresp = invocationBuilder.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/monitoring/TestMonitoringProvider.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/monitoring/TestMonitoringProvider.java
new file mode 100644
index 000000000..aabc254c1
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/monitoring/TestMonitoringProvider.java
@@ -0,0 +1,321 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.acm.runtime.monitoring;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyMap;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.time.Instant;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import javax.ws.rs.core.Response;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import org.onap.policy.clamp.models.acm.concepts.AcElementStatisticsList;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantStatisticsList;
+import org.onap.policy.clamp.models.acm.persistence.provider.AcElementStatisticsProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantStatisticsProvider;
+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.base.PfModelRuntimeException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+class TestMonitoringProvider {
+
+ private static final String AC_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 AC_ELEMENT_STATISTICS_JSON =
+ "src/test/resources/rest/monitoring/TestAcElementStatistics.json";
+ private static final String INVALID_AC_ELEMENT_JSON_INPUT =
+ "src/test/resources/rest/monitoring/TestAcElementStatistics_Invalid.json";
+ private static final Coder CODER = new StandardCoder();
+
+ private static final String STAT_LIST_IS_NULL = ".*StatisticsList is marked .*ull but is null";
+ private static final String PARTICIPANT_STAT_LIST_IS_NULL =
+ "participantStatisticsList is marked .*null but is null";
+ private static final String NAME_IS_NULL = "name is marked .*null but is null";
+ private static final String AC_LIST_IS_NULL = "acElementStatisticsList is marked .*null but is null";
+ private static final String ID_VERSION1 = "1.001";
+ private static final String ID_VERSION2 = "1.002";
+ private static final String ID_NAME1 = "name1";
+ private static final String ID_NAME2 = "name2";
+ private static final String SORT_DESC = "DESC";
+ private static final String ID_NAME3 = "testACName";
+ private static final String ID_INVALID_NAME = "invalidACName";
+ private static ParticipantStatisticsList inputParticipantStatistics;
+ private static ParticipantStatisticsList invalidParticipantInput;
+ private static AcElementStatisticsList inputAcElementStatistics;
+ private static AcElementStatisticsList invalidAcElementInput;
+
+ @BeforeAll
+ public static void beforeSetupStatistics() throws CoderException {
+ // Reading input json for statistics data
+ inputParticipantStatistics =
+ CODER.decode(new File(AC_PARTICIPANT_STATISTICS_JSON), ParticipantStatisticsList.class);
+ invalidParticipantInput =
+ CODER.decode(new File(INVALID_PARTICIPANT_JSON_INPUT), ParticipantStatisticsList.class);
+ inputAcElementStatistics = CODER.decode(new File(AC_ELEMENT_STATISTICS_JSON), AcElementStatisticsList.class);
+ invalidAcElementInput = CODER.decode(new File(INVALID_AC_ELEMENT_JSON_INPUT), AcElementStatisticsList.class);
+ }
+
+ @Test
+ void testCreateParticipantStatistics() throws Exception {
+ var participantStatisticsProvider = mock(ParticipantStatisticsProvider.class);
+ var acElementStatisticsProvider = mock(AcElementStatisticsProvider.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+ MonitoringProvider provider =
+ new MonitoringProvider(participantStatisticsProvider, acElementStatisticsProvider, acProvider);
+
+ when(participantStatisticsProvider.createParticipantStatistics(any()))
+ .thenReturn(inputParticipantStatistics.getStatisticsList());
+
+ when(participantStatisticsProvider.createParticipantStatistics(eq(null)))
+ .thenThrow(new PfModelRuntimeException(Response.Status.BAD_REQUEST, PARTICIPANT_STAT_LIST_IS_NULL));
+
+ // Creating statistics data in db with null input
+
+ assertThatThrownBy(() -> {
+ provider.createParticipantStatistics(null);
+ }).hasMessageMatching(STAT_LIST_IS_NULL);
+
+ assertThatThrownBy(() -> {
+ provider.createParticipantStatistics(invalidParticipantInput.getStatisticsList());
+ }).hasMessageMatching(PARTICIPANT_STAT_LIST_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
+ void testGetParticipantStatistics() throws Exception {
+ var participantStatisticsProvider = mock(ParticipantStatisticsProvider.class);
+ when(participantStatisticsProvider.getFilteredParticipantStatistics(eq(ID_NAME1), any(), any(), any(), eq(null),
+ eq(SORT_DESC), eq(0))).thenReturn(List.of(inputParticipantStatistics.getStatisticsList().get(0)));
+
+ when(participantStatisticsProvider.getFilteredParticipantStatistics(eq(ID_NAME1), any(),
+ eq(Instant.parse("2021-01-11T12:00:00.000Z")), eq(Instant.parse("2021-01-11T16:00:00.000Z")), eq(null),
+ eq(SORT_DESC), eq(0))).thenReturn(List.of());
+
+ when(participantStatisticsProvider.getFilteredParticipantStatistics(eq(ID_NAME2), any(), any(), any(), eq(null),
+ eq(SORT_DESC), eq(1))).thenReturn(List.of(inputParticipantStatistics.getStatisticsList().get(2)));
+
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var acElementStatisticsProvider = mock(AcElementStatisticsProvider.class);
+ MonitoringProvider provider =
+ new MonitoringProvider(participantStatisticsProvider, acElementStatisticsProvider, acProvider);
+ provider.createParticipantStatistics(inputParticipantStatistics.getStatisticsList());
+
+ assertThatThrownBy(() -> {
+ provider.fetchFilteredParticipantStatistics(null, null, 0, null, null);
+ }).hasMessageMatching(NAME_IS_NULL);
+
+ // Fetch specific statistics record with name, version and record count
+ ParticipantStatisticsList getResponse =
+ provider.fetchFilteredParticipantStatistics(ID_NAME2, ID_VERSION1, 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(ID_NAME1, ID_VERSION1, 0, null,
+ Instant.parse("2021-01-10T15:00:00.000Z"));
+ assertThat(getResponse.getStatisticsList()).hasSize(1);
+
+ getResponse = provider.fetchFilteredParticipantStatistics(ID_NAME1, ID_VERSION1, 0,
+ Instant.parse("2021-01-11T12:00:00.000Z"), Instant.parse("2021-01-11T16:00:00.000Z"));
+
+ assertThat(getResponse.getStatisticsList()).isEmpty();
+ }
+
+ @Test
+ void testCreateAcElementStatistics() throws Exception {
+ var acElementStatisticsProvider = mock(AcElementStatisticsProvider.class);
+ when(acElementStatisticsProvider.createAcElementStatistics(any()))
+ .thenReturn(inputAcElementStatistics.getAcElementStatistics());
+
+ when(acElementStatisticsProvider.createAcElementStatistics(eq(null)))
+ .thenThrow(new PfModelRuntimeException(Response.Status.BAD_REQUEST, AC_LIST_IS_NULL));
+
+ var acProvider = mock(AutomationCompositionProvider.class);
+
+ var participantStatisticsProvider = mock(ParticipantStatisticsProvider.class);
+ MonitoringProvider provider =
+ new MonitoringProvider(participantStatisticsProvider, acElementStatisticsProvider, acProvider);
+ // Creating statistics data in db with null input
+ assertThatThrownBy(() -> {
+ provider.createAcElementStatistics(null);
+ }).hasMessageMatching(STAT_LIST_IS_NULL);
+
+ assertThatThrownBy(() -> {
+ provider.createAcElementStatistics(invalidAcElementInput.getAcElementStatistics());
+ }).hasMessageMatching(AC_LIST_IS_NULL);
+
+ // Creating acElement statistics data from input json
+ AcElementStatisticsList createResponse =
+ provider.createAcElementStatistics(inputAcElementStatistics.getAcElementStatistics());
+
+ assertThat(createResponse.getAcElementStatistics()).hasSize(4);
+ assertEquals(createResponse.getAcElementStatistics().toString().replaceAll("\\s+", ""),
+ inputAcElementStatistics.getAcElementStatistics().toString().replaceAll("\\s+", ""));
+ }
+
+ @Test
+ void testGetAcElementStatistics() throws Exception {
+ var participantStatisticsProvider = mock(ParticipantStatisticsProvider.class);
+ var acElementStatisticsProvider = mock(AcElementStatisticsProvider.class);
+ var acProvider = mock(AutomationCompositionProvider.class);
+
+ when(acElementStatisticsProvider.getFilteredAcElementStatistics(eq(ID_NAME1), any(), any(), any(), anyMap(),
+ eq(SORT_DESC), eq(0)))
+ .thenReturn(List.of(inputAcElementStatistics.getAcElementStatistics().get(0),
+ inputAcElementStatistics.getAcElementStatistics().get(1)));
+
+ when(acElementStatisticsProvider.getFilteredAcElementStatistics(eq(ID_NAME1), any(), any(), any(), anyMap(),
+ eq(SORT_DESC), eq(0)))
+ .thenReturn(List.of(inputAcElementStatistics.getAcElementStatistics().get(0),
+ inputAcElementStatistics.getAcElementStatistics().get(1)));
+
+ MonitoringProvider provider =
+ new MonitoringProvider(participantStatisticsProvider, acElementStatisticsProvider, acProvider);
+ assertThatThrownBy(() -> {
+ provider.fetchFilteredAcElementStatistics(null, null, null, null, null, 0);
+ }).hasMessageMatching(NAME_IS_NULL);
+
+ provider.createAcElementStatistics(inputAcElementStatistics.getAcElementStatistics());
+
+ AcElementStatisticsList getResponse =
+ provider.fetchFilteredAcElementStatistics(ID_NAME1, null, null, null, null, 0);
+
+ assertThat(getResponse.getAcElementStatistics()).hasSize(2);
+ assertEquals(getResponse.getAcElementStatistics().get(0).toString().replaceAll("\\s+", ""),
+ inputAcElementStatistics.getAcElementStatistics().get(0).toString().replaceAll("\\s+", ""));
+
+ // Fetch specific statistics record with name, id and record count
+ getResponse = provider.fetchFilteredAcElementStatistics(ID_NAME1, ID_VERSION1,
+ "709c62b3-8918-41b9-a747-d21eb79c6c20", null, null, 0);
+ assertThat(getResponse.getAcElementStatistics()).hasSize(2);
+
+ // Fetch statistics using timestamp
+ getResponse = provider.fetchFilteredAcElementStatistics(ID_NAME1, ID_VERSION1, null,
+ Instant.parse("2021-01-10T13:45:00.000Z"), null, 0);
+ assertThat(getResponse.getAcElementStatistics()).hasSize(2);
+ }
+
+ @Test
+ void testGetParticipantStatsPerAc() throws Exception {
+ var participantStatisticsProvider = mock(ParticipantStatisticsProvider.class);
+ var acElementStatisticsProvider = mock(AcElementStatisticsProvider.class);
+ var mockAcProvider = Mockito.mock(AutomationCompositionProvider.class);
+ var provider =
+ new MonitoringProvider(participantStatisticsProvider, acElementStatisticsProvider, mockAcProvider);
+
+ provider.createParticipantStatistics(inputParticipantStatistics.getStatisticsList());
+
+ var automationComposition = new AutomationComposition();
+ var element = new AutomationCompositionElement();
+ element.setParticipantId(new ToscaConceptIdentifier(ID_NAME1, ID_VERSION1));
+ automationComposition.setElements(Map.of(UUID.randomUUID(), element));
+ when(mockAcProvider.findAutomationComposition(new ToscaConceptIdentifier(ID_NAME2, ID_VERSION1)))
+ .thenReturn(Optional.of(automationComposition));
+
+ when(participantStatisticsProvider.getFilteredParticipantStatistics(eq(ID_NAME1), eq(ID_VERSION1), any(), any(),
+ eq(null), eq(SORT_DESC), eq(0)))
+ .thenReturn(List.of(inputParticipantStatistics.getStatisticsList().get(0),
+ inputParticipantStatistics.getStatisticsList().get(1)));
+
+ ParticipantStatisticsList getResponse =
+ provider.fetchParticipantStatsPerAutomationComposition(ID_NAME2, ID_VERSION1);
+ assertThat(getResponse.getStatisticsList()).hasSize(2);
+ assertEquals(getResponse.getStatisticsList().get(0).toString().replaceAll("\\s+", ""),
+ inputParticipantStatistics.getStatisticsList().get(0).toString().replaceAll("\\s+", ""));
+ assertThat(
+ provider.fetchParticipantStatsPerAutomationComposition(ID_INVALID_NAME, ID_VERSION2).getStatisticsList())
+ .isEmpty();
+ }
+
+ @Test
+ void testAcElementStatsPerAc() throws Exception {
+ // Setup a dummy automation composition data
+ var mockAcElement = new AutomationCompositionElement();
+ mockAcElement.setId(inputAcElementStatistics.getAcElementStatistics().get(0).getId());
+ mockAcElement.setParticipantId(new ToscaConceptIdentifier(
+ inputAcElementStatistics.getAcElementStatistics().get(0).getParticipantId().getName(),
+ inputAcElementStatistics.getAcElementStatistics().get(0).getParticipantId().getVersion()));
+ var mockAc = new AutomationComposition();
+ mockAc.setElements(new LinkedHashMap<>());
+ mockAc.getElements().put(mockAcElement.getId(), mockAcElement);
+
+ var participantStatisticsProvider = mock(ParticipantStatisticsProvider.class);
+ var acElementStatisticsProvider = mock(AcElementStatisticsProvider.class);
+ var mockAcProvider = Mockito.mock(AutomationCompositionProvider.class);
+ var monitoringProvider =
+ new MonitoringProvider(participantStatisticsProvider, acElementStatisticsProvider, mockAcProvider);
+
+ // Mock automation composition data to be returned for the given AC Id
+ when(mockAcProvider.findAutomationComposition(new ToscaConceptIdentifier(ID_NAME3, ID_VERSION1)))
+ .thenReturn(Optional.of(mockAc));
+
+ when(acElementStatisticsProvider.getFilteredAcElementStatistics(eq(ID_NAME1), eq(ID_VERSION1), any(), any(),
+ anyMap(), eq(SORT_DESC), eq(0)))
+ .thenReturn(List.of(inputAcElementStatistics.getAcElementStatistics().get(0),
+ inputAcElementStatistics.getAcElementStatistics().get(1)));
+
+ monitoringProvider.createAcElementStatistics(inputAcElementStatistics.getAcElementStatistics());
+
+ AcElementStatisticsList getResponse =
+ monitoringProvider.fetchAcElementStatsPerAutomationComposition(ID_NAME3, ID_VERSION1);
+
+ assertThat(getResponse.getAcElementStatistics()).hasSize(2);
+ assertEquals(getResponse.getAcElementStatistics().get(1).toString().replaceAll("\\s+", ""),
+ inputAcElementStatistics.getAcElementStatistics().get(1).toString().replaceAll("\\s+", ""));
+
+ assertThat(monitoringProvider.fetchAcElementStatsPerAutomationComposition(ID_INVALID_NAME, ID_VERSION2)
+ .getAcElementStatistics()).isEmpty();
+
+ Map<String, ToscaConceptIdentifier> acElementIds =
+ monitoringProvider.getAllAcElementsIdPerAutomationComposition(ID_NAME3, ID_VERSION1);
+ assertThat(acElementIds)
+ .containsKey(inputAcElementStatistics.getAcElementStatistics().get(0).getId().toString());
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/monitoring/rest/MonitoringQueryControllerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/monitoring/rest/MonitoringQueryControllerTest.java
new file mode 100644
index 000000000..7630e42d2
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/monitoring/rest/MonitoringQueryControllerTest.java
@@ -0,0 +1,242 @@
+/*-
+ * ============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.acm.runtime.monitoring.rest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+import java.io.File;
+import java.time.Instant;
+import javax.ws.rs.client.Invocation;
+import javax.ws.rs.core.Response;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.onap.policy.clamp.acm.runtime.monitoring.MonitoringProvider;
+import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController;
+import org.onap.policy.clamp.models.acm.concepts.AcElementStatisticsList;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantStatisticsList;
+import org.onap.policy.common.utils.coder.Coder;
+import org.onap.policy.common.utils.coder.StandardCoder;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
+import org.springframework.boot.web.server.LocalServerPort;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.context.junit.jupiter.SpringExtension;
+
+@ExtendWith(SpringExtension.class)
+@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
+@TestPropertySource(locations = {"classpath:application_test.properties"})
+class MonitoringQueryControllerTest extends CommonRestController {
+
+ private static final String AC_PARTICIPANT_STATISTICS_JSON =
+ "src/test/resources/rest/monitoring/TestParticipantStatistics.json";
+ private static final String AC_ELEMENT_STATISTICS_JSON =
+ "src/test/resources/rest/monitoring/TestAcElementStatistics.json";
+
+ private static final Coder CODER = new StandardCoder();
+
+ private static ParticipantStatisticsList inputParticipantStatistics;
+ private static AcElementStatisticsList inputAcElementStatistics;
+
+ private static ParticipantStatisticsList participantStatisticsList;
+ private static AcElementStatisticsList acElementStatisticsList;
+
+ private static final String AC_ELEMENT_STATS_ENDPOINT = "monitoring/acelement";
+ private static final String PARTICIPANT_STATS_ENDPOINT = "monitoring/participant";
+ private static final String PARTICIPANT_STATS_PER_AC_ENDPOINT = "monitoring/participants/automationcomposition";
+ private static final String AC_ELEMENT_STATS_PER_AC_ENDPOINT = "monitoring/acelements/automationcomposition";
+
+ @Autowired
+ private MonitoringProvider monitoringProvider;
+
+ @LocalServerPort
+ private int randomServerPort;
+
+ /**
+ * starts Main.
+ *
+ * @throws Exception if an error occurs
+ */
+ @BeforeAll
+ public static void setUpBeforeAll() throws Exception {
+
+ inputParticipantStatistics =
+ CODER.decode(new File(AC_PARTICIPANT_STATISTICS_JSON), ParticipantStatisticsList.class);
+ inputAcElementStatistics = CODER.decode(new File(AC_ELEMENT_STATISTICS_JSON), AcElementStatisticsList.class);
+ }
+
+ @BeforeEach
+ public void setUpBeforeEach() throws Exception {
+ super.setHttpPrefix(randomServerPort);
+
+ // Insert Participant statistics to DB
+ participantStatisticsList =
+ monitoringProvider.createParticipantStatistics(inputParticipantStatistics.getStatisticsList());
+ // Insert AC Element statistics to DB
+ acElementStatisticsList =
+ monitoringProvider.createAcElementStatistics(inputAcElementStatistics.getAcElementStatistics());
+ }
+
+ @Test
+ void testQuery_Unauthorized_for_AcElementStats() throws Exception {
+ assertUnauthorizedGet(AC_ELEMENT_STATS_ENDPOINT);
+ }
+
+ @Test
+ void testQuery_Unauthorized_for_AcParticipantStats() throws Exception {
+ assertUnauthorizedGet(PARTICIPANT_STATS_ENDPOINT);
+ }
+
+ @Test
+ void testQuery_Unauthorized_for_ParticipantStatsPerAc() throws Exception {
+ assertUnauthorizedGet(PARTICIPANT_STATS_PER_AC_ENDPOINT);
+ }
+
+ @Test
+ void testQuery_Unauthorized_for_AcElementStatsPerAc() throws Exception {
+ assertUnauthorizedGet(AC_ELEMENT_STATS_PER_AC_ENDPOINT);
+ }
+
+ @Test
+ void testSwagger_AcStats() throws Exception {
+ super.testSwagger(AC_ELEMENT_STATS_ENDPOINT);
+ super.testSwagger(PARTICIPANT_STATS_ENDPOINT);
+ super.testSwagger(AC_ELEMENT_STATS_PER_AC_ENDPOINT);
+ super.testSwagger(PARTICIPANT_STATS_PER_AC_ENDPOINT);
+ }
+
+ @Test
+ void testAcElementStatisticsEndpoint() throws Exception {
+ // Filter statistics only based on participant Id and UUID
+ Invocation.Builder invokeRequest1 = super.sendRequest(AC_ELEMENT_STATS_ENDPOINT + "?name="
+ + acElementStatisticsList.getAcElementStatistics().get(0).getParticipantId().getName() + "&version="
+ + acElementStatisticsList.getAcElementStatistics().get(0).getParticipantId().getVersion() + "&id="
+ + acElementStatisticsList.getAcElementStatistics().get(0).getId().toString());
+ Response response1 = invokeRequest1.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus());
+
+ AcElementStatisticsList result1 = response1.readEntity(AcElementStatisticsList.class);
+
+ assertNotNull(result1);
+ assertThat(result1.getAcElementStatistics()).hasSize(2);
+
+ var acElementStat0 = acElementStatisticsList.getAcElementStatistics().get(0);
+ for (var acElement : result1.getAcElementStatistics()) {
+ assertEquals(acElement.getParticipantId().asConceptKey(), acElementStat0.getParticipantId().asConceptKey());
+ assertEquals(acElement.getId(), acElementStat0.getId());
+ }
+
+ // Filter statistics based on timestamp
+ Invocation.Builder invokeRequest2 = super.sendRequest(AC_ELEMENT_STATS_ENDPOINT + "?name="
+ + acElementStatisticsList.getAcElementStatistics().get(1).getParticipantId().getName() + "&version="
+ + acElementStatisticsList.getAcElementStatistics().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());
+ AcElementStatisticsList result2 = response2.readEntity(AcElementStatisticsList.class);
+
+ assertNotNull(result2);
+ assertThat(result2.getAcElementStatistics()).hasSize(1);
+ assertEquals(result2.getAcElementStatistics().get(0), acElementStat0);
+ }
+
+ @Test
+ void testAcElementStats_BadRequest() throws Exception {
+ Invocation.Builder invokeRequest1 = super.sendRequest(AC_ELEMENT_STATS_ENDPOINT + "?version=1.0.0");
+ Response response1 = invokeRequest1.buildGet().invoke();
+ assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus());
+ }
+
+ @Test
+ 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);
+ assertThat(result1.getStatisticsList()).contains(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(result2.getStatisticsList().get(0), participantStatisticsList.getStatisticsList().get(0));
+ }
+
+ @Test
+ 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
+ void testParticipantStatsPerAcEndpoint() throws Exception {
+ Invocation.Builder invokeRequest1 =
+ super.sendRequest(PARTICIPANT_STATS_PER_AC_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
+ void testParticipantStatsPerAc_BadRequest() throws Exception {
+ Invocation.Builder invokeRequest1 = super.sendRequest(PARTICIPANT_STATS_PER_AC_ENDPOINT);
+ Response response1 = invokeRequest1.buildGet().invoke();
+ assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus());
+ }
+
+ @Test
+ void testAcElementStatisticsPerAcEndpoint() throws Exception {
+ Invocation.Builder invokeRequest1 =
+ super.sendRequest(AC_ELEMENT_STATS_PER_AC_ENDPOINT + "?name=dummyName&version=1.001");
+ Response response1 = invokeRequest1.buildGet().invoke();
+ assertEquals(Response.Status.OK.getStatusCode(), response1.getStatus());
+ AcElementStatisticsList result1 = response1.readEntity(AcElementStatisticsList.class);
+ assertThat(result1.getAcElementStatistics()).isEmpty();
+ }
+
+ @Test
+ void testAcElementStatsPerAc_BadRequest() throws Exception {
+ Invocation.Builder invokeRequest1 = super.sendRequest(AC_ELEMENT_STATS_PER_AC_ENDPOINT);
+ Response response1 = invokeRequest1.buildGet().invoke();
+ assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response1.getStatus());
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/HandleCounterTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/HandleCounterTest.java
new file mode 100644
index 000000000..a6474c9e3
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/HandleCounterTest.java
@@ -0,0 +1,84 @@
+/*-
+ * ============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.acm.runtime.supervision;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.jupiter.api.Test;
+
+class HandleCounterTest {
+
+ private static final int ID = 1;
+
+ @Test
+ void testCount() {
+ var handleCounter = new HandleCounter<Integer>();
+ handleCounter.setMaxRetryCount(2);
+ assertThat(handleCounter.count(ID)).isTrue();
+ assertThat(handleCounter.getCounter(ID)).isEqualTo(1);
+ assertThat(handleCounter.count(ID)).isTrue();
+ assertThat(handleCounter.getCounter(ID)).isEqualTo(2);
+ assertThat(handleCounter.count(ID)).isFalse();
+ assertThat(handleCounter.getCounter(ID)).isEqualTo(2);
+
+ handleCounter.clear(ID);
+ assertThat(handleCounter.count(ID)).isTrue();
+ assertThat(handleCounter.getCounter(ID)).isEqualTo(1);
+ }
+
+ @Test
+ void testFault() {
+ var handleCounter = new HandleCounter<Integer>();
+ handleCounter.setFault(ID);
+ assertThat(handleCounter.isFault(ID)).isTrue();
+ handleCounter.clear(ID);
+ assertThat(handleCounter.isFault(ID)).isFalse();
+ }
+
+ @Test
+ void testDuration() throws InterruptedException {
+
+ var handleCounter = new HandleCounter<Integer>() {
+ long epochMilli = 0;
+
+ @Override
+ protected long getEpochMilli() {
+ return epochMilli;
+ }
+ };
+ handleCounter.epochMilli = 100;
+ var result = handleCounter.getDuration(ID);
+ assertThat(result).isZero();
+
+ handleCounter.epochMilli += 100;
+ result = handleCounter.getDuration(ID);
+ assertThat(result).isEqualTo(100);
+
+ handleCounter.epochMilli += 100;
+ result = handleCounter.getDuration(ID);
+ assertThat(result).isEqualTo(200);
+
+ handleCounter.epochMilli += 100;
+ handleCounter.clear(ID);
+ result = handleCounter.getDuration(ID);
+ assertThat(result).isZero();
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspectTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspectTest.java
new file mode 100644
index 000000000..487d41139
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionAspectTest.java
@@ -0,0 +1,66 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.acm.runtime.supervision;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.timeout;
+import static org.mockito.Mockito.verify;
+
+import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+class SupervisionAspectTest {
+
+ @Test
+ void testSchedule() throws Exception {
+ var supervisionScanner = spy(mock(SupervisionScanner.class));
+ try (var supervisionAspect = new SupervisionAspect(supervisionScanner)) {
+ supervisionAspect.schedule();
+ verify(supervisionScanner, timeout(500)).run(true);
+ }
+ }
+
+ @Test
+ void testDoCheck() throws Exception {
+ var supervisionScanner = spy(mock(SupervisionScanner.class));
+ try (var supervisionAspect = new SupervisionAspect(supervisionScanner)) {
+ supervisionAspect.doCheck();
+ supervisionAspect.doCheck();
+ verify(supervisionScanner, timeout(500).times(2)).run(false);
+ }
+ }
+
+ @Test
+ void testHandleParticipantStatus() throws Exception {
+ var supervisionScanner = spy(mock(SupervisionScanner.class));
+ var participantStatusMessage = new ParticipantStatus();
+ var identifier = new ToscaConceptIdentifier("abc", "1.0.0");
+ participantStatusMessage.setParticipantId(identifier);
+
+ try (var supervisionAspect = new SupervisionAspect(supervisionScanner)) {
+ supervisionAspect.handleParticipantStatus(participantStatusMessage);
+ verify(supervisionScanner, timeout(500)).handleParticipantStatus(identifier);
+ }
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java
new file mode 100644
index 000000000..99e509c0e
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionHandlerTest.java
@@ -0,0 +1,319 @@
+/*-
+ * ============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.acm.runtime.supervision;
+
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.acm.runtime.monitoring.MonitoringProvider;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionUpdatePublisher;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantDeregisterAckPublisher;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantRegisterAckPublisher;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantUpdatePublisher;
+import org.onap.policy.clamp.common.acm.exception.AutomationCompositionException;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState;
+import org.onap.policy.clamp.models.acm.concepts.Participant;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantHealthStatus;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantStatistics;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.AutomationCompositionAck;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregister;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantMessageType;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegister;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantStatus;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdateAck;
+import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ServiceTemplateProvider;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+class SupervisionHandlerTest {
+ private static final String TOSCA_TEMPLATE_YAML =
+ "src/test/resources/rest/servicetemplates/tosca-for-smoke-testing.yaml";
+ private static final String AC_INSTANTIATION_CREATE_JSON =
+ "src/test/resources/rest/acm/AutomationCompositions.json";
+ private static final ToscaConceptIdentifier identifier = new ToscaConceptIdentifier("PMSHInstance0Crud", "1.0.1");
+ private static final ToscaConceptIdentifier participantId = new ToscaConceptIdentifier("ParticipantId", "1.0.0");
+ private static final ToscaConceptIdentifier participantType =
+ new ToscaConceptIdentifier("ParticipantType", "1.0.0");
+
+ @Test
+ void testTriggerAutomationCompositionSupervisionEmpty()
+ throws AutomationCompositionException, PfModelException, CoderException {
+ var handler =
+ createSupervisionHandler(mock(AutomationCompositionProvider.class), mock(ParticipantProvider.class),
+ mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+ mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionUpdatePublisher.class),
+ mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE);
+
+ assertThatThrownBy(() -> handler.triggerAutomationCompositionSupervision(List.of()))
+ .hasMessageMatching("The list of automation compositions for supervision is empty");
+ }
+
+ @Test
+ void testTriggerAutomationCompositionSupervision()
+ throws AutomationCompositionException, PfModelException, CoderException {
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var automationCompositionUpdatePublisher = mock(AutomationCompositionUpdatePublisher.class);
+ var handler = createSupervisionHandler(automationCompositionProvider, mock(ParticipantProvider.class),
+ mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+ mock(ParticipantDeregisterAckPublisher.class), automationCompositionUpdatePublisher,
+ mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE);
+
+ handler.triggerAutomationCompositionSupervision(List.of(identifier));
+
+ verify(automationCompositionUpdatePublisher).send(any(AutomationComposition.class));
+ verify(automationCompositionProvider).saveAutomationComposition(any(AutomationComposition.class));
+ }
+
+ @Test
+ void testTriggerAutomationCompositionUninitialised()
+ throws AutomationCompositionException, PfModelException, CoderException {
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var automationCompositionUpdatePublisher = mock(AutomationCompositionUpdatePublisher.class);
+ var handler = createSupervisionHandler(automationCompositionProvider, mock(ParticipantProvider.class),
+ mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+ mock(ParticipantDeregisterAckPublisher.class), automationCompositionUpdatePublisher,
+ mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.UNINITIALISED);
+
+ assertThatThrownBy(() -> handler.triggerAutomationCompositionSupervision(List.of(identifier)))
+ .hasMessageMatching("Automation composition is already in state UNINITIALISED");
+ }
+
+ @Test
+ void testTriggerAutomationCompositionRunning()
+ throws AutomationCompositionException, PfModelException, CoderException {
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var automationCompositionUpdatePublisher = mock(AutomationCompositionUpdatePublisher.class);
+ var handler = createSupervisionHandler(automationCompositionProvider, mock(ParticipantProvider.class),
+ mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+ mock(ParticipantDeregisterAckPublisher.class), automationCompositionUpdatePublisher,
+ mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.RUNNING);
+
+ assertThatThrownBy(() -> handler.triggerAutomationCompositionSupervision(List.of(identifier)))
+ .hasMessageMatching("Automation composition can't transition from state UNINITIALISED to state RUNNING");
+ }
+
+ @Test
+ void testHandleAutomationCompositionStateChangeAckMessage() throws PfModelException, CoderException {
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var handler = createSupervisionHandler(automationCompositionProvider, mock(ParticipantProvider.class),
+ mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+ mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionUpdatePublisher.class),
+ mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE);
+ var automationCompositionAckMessage =
+ new AutomationCompositionAck(ParticipantMessageType.AUTOMATION_COMPOSITION_STATECHANGE_ACK);
+ automationCompositionAckMessage.setAutomationCompositionResultMap(Map.of());
+ automationCompositionAckMessage.setAutomationCompositionId(identifier);
+
+ handler.handleAutomationCompositionStateChangeAckMessage(automationCompositionAckMessage);
+
+ verify(automationCompositionProvider).saveAutomationComposition(any(AutomationComposition.class));
+ }
+
+ @Test
+ void testHandleAutomationCompositionUpdateAckMessage() throws PfModelException, CoderException {
+ var automationCompositionAckMessage =
+ new AutomationCompositionAck(ParticipantMessageType.AUTOMATION_COMPOSITION_UPDATE_ACK);
+ automationCompositionAckMessage.setParticipantId(participantId);
+ automationCompositionAckMessage.setParticipantType(participantType);
+ automationCompositionAckMessage.setAutomationCompositionResultMap(Map.of());
+ automationCompositionAckMessage.setAutomationCompositionId(identifier);
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var handler = createSupervisionHandler(automationCompositionProvider, mock(ParticipantProvider.class),
+ mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+ mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionUpdatePublisher.class),
+ mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE);
+
+ handler.handleAutomationCompositionUpdateAckMessage(automationCompositionAckMessage);
+
+ verify(automationCompositionProvider).saveAutomationComposition(any(AutomationComposition.class));
+ }
+
+ @Test
+ void testHandleParticipantDeregister() throws PfModelException, CoderException {
+ var participant = new Participant();
+ participant.setName(participantId.getName());
+ participant.setVersion(participantId.getVersion());
+ participant.setParticipantType(participantType);
+
+ var participantProvider = mock(ParticipantProvider.class);
+ when(participantProvider.findParticipant(participantId.getName(), participantId.getVersion()))
+ .thenReturn(Optional.of(participant));
+
+ var participantDeregisterMessage = new ParticipantDeregister();
+ participantDeregisterMessage.setMessageId(UUID.randomUUID());
+ participantDeregisterMessage.setParticipantId(participantId);
+ participantDeregisterMessage.setParticipantType(participantType);
+ var participantDeregisterAckPublisher = mock(ParticipantDeregisterAckPublisher.class);
+ var handler = createSupervisionHandler(mock(AutomationCompositionProvider.class), participantProvider,
+ mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+ participantDeregisterAckPublisher, mock(AutomationCompositionUpdatePublisher.class),
+ mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE);
+
+ handler.handleParticipantMessage(participantDeregisterMessage);
+
+ verify(participantProvider).saveParticipant(any());
+ verify(participantDeregisterAckPublisher).send(participantDeregisterMessage.getMessageId());
+ }
+
+ @Test
+ void testHandleParticipantRegister() throws PfModelException, CoderException {
+ var participant = new Participant();
+ participant.setName(participantId.getName());
+ participant.setVersion(participantId.getVersion());
+ participant.setParticipantType(participantType);
+
+ var participantRegisterMessage = new ParticipantRegister();
+ participantRegisterMessage.setMessageId(UUID.randomUUID());
+ participantRegisterMessage.setParticipantId(participantId);
+ participantRegisterMessage.setParticipantType(participantType);
+ var participantProvider = mock(ParticipantProvider.class);
+ var participantRegisterAckPublisher = mock(ParticipantRegisterAckPublisher.class);
+ var handler = createSupervisionHandler(mock(AutomationCompositionProvider.class), participantProvider,
+ mock(MonitoringProvider.class), participantRegisterAckPublisher,
+ mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionUpdatePublisher.class),
+ mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE);
+
+ handler.handleParticipantMessage(participantRegisterMessage);
+
+ verify(participantProvider).saveParticipant(any());
+ verify(participantRegisterAckPublisher).send(participantRegisterMessage.getMessageId(), participantId,
+ participantType);
+ }
+
+ @Test
+ void testParticipantUpdateAck() throws PfModelException, CoderException {
+ var participant = new Participant();
+ participant.setName(participantId.getName());
+ participant.setVersion(participantId.getVersion());
+ participant.setParticipantType(participantType);
+
+ var participantProvider = mock(ParticipantProvider.class);
+ when(participantProvider.findParticipant(participantId.getName(), participantId.getVersion()))
+ .thenReturn(Optional.of(participant));
+
+ var participantUpdateAckMessage = new ParticipantUpdateAck();
+ participantUpdateAckMessage.setParticipantId(participantId);
+ participantUpdateAckMessage.setParticipantType(participantType);
+ participantUpdateAckMessage.setState(ParticipantState.PASSIVE);
+ var handler = createSupervisionHandler(mock(AutomationCompositionProvider.class), participantProvider,
+ mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+ mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionUpdatePublisher.class),
+ mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE);
+
+ handler.handleParticipantMessage(participantUpdateAckMessage);
+
+ verify(participantProvider).saveParticipant(any());
+ }
+
+ @Test
+ void testHandleParticipantStatus() throws PfModelException, CoderException {
+ var participantStatusMessage = new ParticipantStatus();
+ participantStatusMessage.setParticipantId(participantId);
+ participantStatusMessage.setParticipantType(participantType);
+ participantStatusMessage.setState(ParticipantState.PASSIVE);
+ participantStatusMessage.setHealthStatus(ParticipantHealthStatus.HEALTHY);
+ participantStatusMessage.setParticipantStatistics(new ParticipantStatistics());
+
+ var participantProvider = mock(ParticipantProvider.class);
+ var monitoringProvider = mock(MonitoringProvider.class);
+ var handler = createSupervisionHandler(mock(AutomationCompositionProvider.class), participantProvider,
+ monitoringProvider, mock(ParticipantRegisterAckPublisher.class),
+ mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionUpdatePublisher.class),
+ mock(ParticipantUpdatePublisher.class), AutomationCompositionOrderedState.PASSIVE);
+ handler.handleParticipantMessage(participantStatusMessage);
+
+ verify(participantProvider).saveParticipant(any());
+ verify(monitoringProvider).createParticipantStatistics(anyList());
+ }
+
+ @Test
+ void testHandleSendCommissionMessage() throws PfModelException, CoderException {
+ var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
+ var handler =
+ createSupervisionHandler(mock(AutomationCompositionProvider.class), mock(ParticipantProvider.class),
+ mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+ mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionUpdatePublisher.class),
+ participantUpdatePublisher, AutomationCompositionOrderedState.PASSIVE);
+ handler.handleSendCommissionMessage(participantId.getName(), participantId.getVersion());
+
+ verify(participantUpdatePublisher).sendComissioningBroadcast(participantId.getName(),
+ participantId.getVersion());
+ }
+
+ @Test
+ void testHandleSendDeCommissionMessage() throws PfModelException, CoderException {
+ var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
+ var handler =
+ createSupervisionHandler(mock(AutomationCompositionProvider.class), mock(ParticipantProvider.class),
+ mock(MonitoringProvider.class), mock(ParticipantRegisterAckPublisher.class),
+ mock(ParticipantDeregisterAckPublisher.class), mock(AutomationCompositionUpdatePublisher.class),
+ participantUpdatePublisher, AutomationCompositionOrderedState.PASSIVE);
+ handler.handleSendDeCommissionMessage();
+
+ verify(participantUpdatePublisher).sendDecomisioning();
+ }
+
+ private SupervisionHandler createSupervisionHandler(AutomationCompositionProvider automationCompositionProvider,
+ ParticipantProvider participantProvider, MonitoringProvider monitoringProvider,
+ ParticipantRegisterAckPublisher participantRegisterAckPublisher,
+ ParticipantDeregisterAckPublisher participantDeregisterAckPublisher,
+ AutomationCompositionUpdatePublisher automationCompositionUpdatePublisher,
+ ParticipantUpdatePublisher participantUpdatePublisher, AutomationCompositionOrderedState orderedState)
+ throws PfModelException, CoderException {
+ var automationCompositionsCreate =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_INSTANTIATION_CREATE_JSON, "Crud");
+
+ var automationComposition = automationCompositionsCreate.getAutomationCompositionList().get(0);
+ automationComposition.setOrderedState(orderedState);
+
+ when(automationCompositionProvider.findAutomationComposition(identifier))
+ .thenReturn(Optional.of(automationComposition));
+ when(automationCompositionProvider.getAutomationComposition(identifier)).thenReturn(automationComposition);
+
+ var serviceTemplateProvider = Mockito.mock(ServiceTemplateProvider.class);
+ when(serviceTemplateProvider.getServiceTemplateList(any(), any()))
+ .thenReturn(List.of(InstantiationUtils.getToscaServiceTemplate(TOSCA_TEMPLATE_YAML)));
+
+ var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
+
+ return new SupervisionHandler(automationCompositionProvider, participantProvider, monitoringProvider,
+ serviceTemplateProvider, automationCompositionUpdatePublisher, automationCompositionStateChangePublisher,
+ participantRegisterAckPublisher, participantDeregisterAckPublisher, participantUpdatePublisher);
+
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java
new file mode 100644
index 000000000..cd1a49b46
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/SupervisionScannerTest.java
@@ -0,0 +1,214 @@
+/*-
+ * ============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.acm.runtime.supervision;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionStateChangePublisher;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.AutomationCompositionUpdatePublisher;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantStatusReqPublisher;
+import org.onap.policy.clamp.acm.runtime.supervision.comm.ParticipantUpdatePublisher;
+import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionOrderedState;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState;
+import org.onap.policy.clamp.models.acm.concepts.Participant;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantHealthStatus;
+import org.onap.policy.clamp.models.acm.concepts.ParticipantState;
+import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ServiceTemplateProvider;
+import org.onap.policy.common.utils.coder.CoderException;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
+
+class SupervisionScannerTest {
+
+ private static final String TOSCA_SERVICE_TEMPLATE_YAML =
+ "src/test/resources/rest/servicetemplates/tosca-for-smoke-testing.yaml";
+ private static final String AC_JSON = "src/test/resources/rest/acm/AutomationCompositionsSmoke.json";
+
+ private static ServiceTemplateProvider serviceTemplateProvider = mock(ServiceTemplateProvider.class);
+
+ @BeforeAll
+ public static void setUpBeforeAll() throws Exception {
+ ToscaServiceTemplate serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
+ when(serviceTemplateProvider.getAllServiceTemplates()).thenReturn(List.of(serviceTemplate));
+ }
+
+ @Test
+ void testScannerOrderedStateEqualsToState() throws PfModelException, CoderException {
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
+ var automationCompositionUpdatePublisher = mock(AutomationCompositionUpdatePublisher.class);
+ var participantProvider = mock(ParticipantProvider.class);
+ var participantStatusReqPublisher = mock(ParticipantStatusReqPublisher.class);
+ var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
+ var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+
+ var automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_JSON, "Crud").getAutomationCompositionList();
+ when(automationCompositionProvider.getAutomationCompositions()).thenReturn(automationCompositions);
+
+ var supervisionScanner = new SupervisionScanner(automationCompositionProvider, serviceTemplateProvider,
+ automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider,
+ participantStatusReqPublisher, participantUpdatePublisher, acRuntimeParameterGroup);
+ supervisionScanner.run(false);
+
+ verify(automationCompositionProvider, times(0)).saveAutomationComposition(any(AutomationComposition.class));
+ }
+
+ @Test
+ void testScannerOrderedStateDifferentToState() throws PfModelException, CoderException {
+ var automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_JSON, "Crud").getAutomationCompositionList();
+ automationCompositions.get(0).setState(AutomationCompositionState.UNINITIALISED2PASSIVE);
+ automationCompositions.get(0).setOrderedState(AutomationCompositionOrderedState.UNINITIALISED);
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ when(automationCompositionProvider.getAutomationCompositions()).thenReturn(automationCompositions);
+
+ var automationCompositionUpdatePublisher = mock(AutomationCompositionUpdatePublisher.class);
+ var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
+ var participantProvider = mock(ParticipantProvider.class);
+ var participantStatusReqPublisher = mock(ParticipantStatusReqPublisher.class);
+ var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
+ var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+
+ var supervisionScanner = new SupervisionScanner(automationCompositionProvider, serviceTemplateProvider,
+ automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider,
+ participantStatusReqPublisher, participantUpdatePublisher, acRuntimeParameterGroup);
+ supervisionScanner.run(false);
+
+ verify(automationCompositionProvider, times(1)).saveAutomationComposition(any(AutomationComposition.class));
+ }
+
+ @Test
+ void testScanner() throws PfModelException {
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var automationComposition = new AutomationComposition();
+ when(automationCompositionProvider.getAutomationCompositions()).thenReturn(List.of(automationComposition));
+
+ var participantProvider = mock(ParticipantProvider.class);
+ var participant = new Participant();
+ participant.setName("Participant0");
+ participant.setVersion("1.0.0");
+ when(participantProvider.getParticipants(null, null)).thenReturn(List.of(participant));
+
+ var automationCompositionUpdatePublisher = mock(AutomationCompositionUpdatePublisher.class);
+ var participantStatusReqPublisher = mock(ParticipantStatusReqPublisher.class);
+ var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
+ var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
+ var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+
+ var supervisionScanner = new SupervisionScanner(automationCompositionProvider, serviceTemplateProvider,
+ automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider,
+ participantStatusReqPublisher, participantUpdatePublisher, acRuntimeParameterGroup);
+
+ supervisionScanner.handleParticipantStatus(participant.getKey().asIdentifier());
+ supervisionScanner.run(true);
+ verify(automationCompositionProvider, times(0)).saveAutomationComposition(any(AutomationComposition.class));
+ verify(participantStatusReqPublisher, times(0)).send(any(ToscaConceptIdentifier.class));
+ }
+
+ @Test
+ void testSendAutomationCompositionMsgUpdate() throws PfModelException, CoderException {
+ var automationCompositions =
+ InstantiationUtils.getAutomationCompositionsFromResource(AC_JSON, "Crud").getAutomationCompositionList();
+ automationCompositions.get(0).setState(AutomationCompositionState.UNINITIALISED2PASSIVE);
+ automationCompositions.get(0).setOrderedState(AutomationCompositionOrderedState.PASSIVE);
+ for (var element : automationCompositions.get(0).getElements().values()) {
+ if ("org.onap.domain.database.Http_PMSHMicroserviceAutomationCompositionElement"
+ .equals(element.getDefinition().getName())) {
+ element.setOrderedState(AutomationCompositionOrderedState.PASSIVE);
+ element.setState(AutomationCompositionState.UNINITIALISED);
+ } else {
+ element.setOrderedState(AutomationCompositionOrderedState.PASSIVE);
+ element.setState(AutomationCompositionState.PASSIVE);
+ }
+ }
+
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ when(automationCompositionProvider.getAutomationCompositions()).thenReturn(automationCompositions);
+
+ var participantProvider = mock(ParticipantProvider.class);
+ var automationCompositionUpdatePublisher = mock(AutomationCompositionUpdatePublisher.class);
+ var participantStatusReqPublisher = mock(ParticipantStatusReqPublisher.class);
+ var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
+ var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
+ var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanner");
+
+ var supervisionScanner = new SupervisionScanner(automationCompositionProvider, serviceTemplateProvider,
+ automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider,
+ participantStatusReqPublisher, participantUpdatePublisher, acRuntimeParameterGroup);
+
+ supervisionScanner.run(false);
+
+ verify(automationCompositionUpdatePublisher).send(any(AutomationComposition.class), anyInt());
+ }
+
+ @Test
+ void testScanParticipant() throws PfModelException {
+ var automationCompositionProvider = mock(AutomationCompositionProvider.class);
+ var automationComposition = new AutomationComposition();
+ when(automationCompositionProvider.getAutomationCompositions()).thenReturn(List.of(automationComposition));
+
+ var acRuntimeParameterGroup = CommonTestData.geParameterGroup("dbScanParticipant");
+ acRuntimeParameterGroup.getParticipantParameters().getUpdateParameters().setMaxWaitMs(-1);
+ acRuntimeParameterGroup.getParticipantParameters().setMaxStatusWaitMs(-1);
+
+ var participant = new Participant();
+ participant.setName("Participant0");
+ participant.setVersion("1.0.0");
+ participant.setHealthStatus(ParticipantHealthStatus.HEALTHY);
+ participant.setParticipantState(ParticipantState.ACTIVE);
+ participant.setDefinition(new ToscaConceptIdentifier("unknown", "0.0.0"));
+ participant.setParticipantType(new ToscaConceptIdentifier("ParticipantType1", "1.0.0"));
+ var participantProvider = mock(ParticipantProvider.class);
+ when(participantProvider.getParticipants()).thenReturn(List.of(participant));
+
+ var automationCompositionUpdatePublisher = mock(AutomationCompositionUpdatePublisher.class);
+ var participantStatusReqPublisher = mock(ParticipantStatusReqPublisher.class);
+ var automationCompositionStateChangePublisher = mock(AutomationCompositionStateChangePublisher.class);
+ var participantUpdatePublisher = mock(ParticipantUpdatePublisher.class);
+
+ var supervisionScanner = new SupervisionScanner(automationCompositionProvider, serviceTemplateProvider,
+ automationCompositionStateChangePublisher, automationCompositionUpdatePublisher, participantProvider,
+ participantStatusReqPublisher, participantUpdatePublisher, acRuntimeParameterGroup);
+
+ supervisionScanner.handleParticipantStatus(participant.getKey().asIdentifier());
+ supervisionScanner.run(true);
+ verify(participantStatusReqPublisher).send(any(ToscaConceptIdentifier.class));
+ verify(participantProvider).saveParticipant(any());
+
+ supervisionScanner.run(true);
+ verify(participantProvider, times(2)).saveParticipant(any());
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java
new file mode 100644
index 000000000..6545fe395
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/supervision/comm/SupervisionMessagesTest.java
@@ -0,0 +1,225 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * Copyright (C) 2021 Nordix Foundation.
+ * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
+ * ================================================================================
+ * 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.acm.runtime.supervision.comm;
+
+import static org.assertj.core.api.Assertions.assertThatCode;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.time.Instant;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+import org.onap.policy.clamp.acm.runtime.monitoring.MonitoringProvider;
+import org.onap.policy.clamp.acm.runtime.supervision.SupervisionHandler;
+import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController;
+import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionState;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregister;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantDeregisterAck;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantRegisterAck;
+import org.onap.policy.clamp.models.acm.messages.dmaap.participant.ParticipantUpdateAck;
+import org.onap.policy.clamp.models.acm.persistence.provider.AcElementStatisticsProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.AutomationCompositionProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantStatisticsProvider;
+import org.onap.policy.clamp.models.acm.persistence.provider.ServiceTemplateProvider;
+import org.onap.policy.common.endpoints.event.comm.Topic.CommInfrastructure;
+import org.onap.policy.common.endpoints.event.comm.TopicSink;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier;
+
+class SupervisionMessagesTest extends CommonRestController {
+
+ private static final String NOT_ACTIVE = "Not Active!";
+ private static final Object lockit = new Object();
+ private static final CommInfrastructure INFRA = CommInfrastructure.NOOP;
+ private static final String TOPIC = "my-topic";
+ private static SupervisionHandler supervisionHandler;
+
+ /**
+ * setup Db Provider Parameters.
+ *
+ * @throws PfModelException if an error occurs
+ */
+ @BeforeAll
+ public static void setupDbProviderParameters() throws PfModelException {
+ var acProvider = mock(AutomationCompositionProvider.class);
+ var participantStatisticsProvider = mock(ParticipantStatisticsProvider.class);
+ var acElementStatisticsProvider = mock(AcElementStatisticsProvider.class);
+ var monitoringProvider =
+ new MonitoringProvider(participantStatisticsProvider, acElementStatisticsProvider, acProvider);
+ var participantProvider = mock(ParticipantProvider.class);
+ var serviceTemplateProvider = Mockito.mock(ServiceTemplateProvider.class);
+ var automationCompositionUpdatePublisher = Mockito.mock(AutomationCompositionUpdatePublisher.class);
+ var automationCompositionStateChangePublisher = Mockito.mock(AutomationCompositionStateChangePublisher.class);
+ var participantRegisterAckPublisher = Mockito.mock(ParticipantRegisterAckPublisher.class);
+ var participantDeregisterAckPublisher = Mockito.mock(ParticipantDeregisterAckPublisher.class);
+ var participantUpdatePublisher = Mockito.mock(ParticipantUpdatePublisher.class);
+ supervisionHandler = new SupervisionHandler(acProvider, participantProvider, monitoringProvider,
+ serviceTemplateProvider, automationCompositionUpdatePublisher, automationCompositionStateChangePublisher,
+ participantRegisterAckPublisher, participantDeregisterAckPublisher, participantUpdatePublisher);
+ }
+
+ @Test
+ void testSendParticipantRegisterAck() throws Exception {
+ final ParticipantRegisterAck participantRegisterAckMsg = new ParticipantRegisterAck();
+ participantRegisterAckMsg.setMessage("ParticipantRegisterAck message");
+ participantRegisterAckMsg.setResponseTo(UUID.randomUUID());
+ participantRegisterAckMsg.setResult(true);
+
+ synchronized (lockit) {
+ ParticipantRegisterAckPublisher acRegisterAckPublisher = new ParticipantRegisterAckPublisher();
+ acRegisterAckPublisher.active(List.of(Mockito.mock(TopicSink.class)));
+ assertThatCode(() -> acRegisterAckPublisher.send(participantRegisterAckMsg)).doesNotThrowAnyException();
+ }
+ }
+
+ @Test
+ void testReceiveParticipantDeregister() throws Exception {
+ final ParticipantDeregister participantDeregisterMsg = new ParticipantDeregister();
+ participantDeregisterMsg.setParticipantId(getParticipantId());
+ participantDeregisterMsg.setTimestamp(Instant.now());
+ participantDeregisterMsg.setParticipantType(getParticipantType());
+
+ synchronized (lockit) {
+ ParticipantDeregisterListener participantDeregisterListener =
+ new ParticipantDeregisterListener(supervisionHandler);
+ assertThatCode(
+ () -> participantDeregisterListener.onTopicEvent(INFRA, TOPIC, null, participantDeregisterMsg))
+ .doesNotThrowAnyException();
+ }
+ }
+
+ @Test
+ void testSendParticipantDeregisterAck() throws Exception {
+ final ParticipantDeregisterAck participantDeregisterAckMsg = new ParticipantDeregisterAck();
+ participantDeregisterAckMsg.setMessage("ParticipantDeregisterAck message");
+ participantDeregisterAckMsg.setResponseTo(UUID.randomUUID());
+ participantDeregisterAckMsg.setResult(true);
+
+ synchronized (lockit) {
+ ParticipantDeregisterAckPublisher acDeregisterAckPublisher = new ParticipantDeregisterAckPublisher();
+ acDeregisterAckPublisher.active(Collections.singletonList(Mockito.mock(TopicSink.class)));
+ assertThatCode(() -> acDeregisterAckPublisher.send(participantDeregisterAckMsg)).doesNotThrowAnyException();
+ }
+ }
+
+ @Test
+ void testReceiveParticipantUpdateAckMessage() throws Exception {
+ final ParticipantUpdateAck participantUpdateAckMsg = new ParticipantUpdateAck();
+ participantUpdateAckMsg.setMessage("ParticipantUpdateAck message");
+ participantUpdateAckMsg.setResponseTo(UUID.randomUUID());
+ participantUpdateAckMsg.setResult(true);
+ participantUpdateAckMsg.setParticipantId(getParticipantId());
+ participantUpdateAckMsg.setParticipantType(getParticipantType());
+
+ synchronized (lockit) {
+ ParticipantUpdateAckListener participantUpdateAckListener =
+ new ParticipantUpdateAckListener(supervisionHandler);
+ assertThatCode(() -> participantUpdateAckListener.onTopicEvent(INFRA, TOPIC, null, participantUpdateAckMsg))
+ .doesNotThrowAnyException();
+ }
+ }
+
+ @Test
+ void testSendAutomationCompositionStateChangePublisherNotActive() {
+ var publisher = new AutomationCompositionStateChangePublisher();
+ assertThatThrownBy(() -> publisher.send(getAutomationComposition(), 0)).hasMessage(NOT_ACTIVE);
+ }
+
+ @Test
+ void testSendAutomationCompositionStateChangePublisher() {
+ var publisher = new AutomationCompositionStateChangePublisher();
+ var topicSink = mock(TopicSink.class);
+ publisher.active(List.of(topicSink));
+ publisher.send(getAutomationComposition(), 0);
+ verify(topicSink).send(anyString());
+ }
+
+ @Test
+ void testParticipantUpdatePublisherDecomisioning() {
+ var publisher = new ParticipantUpdatePublisher(mock(ServiceTemplateProvider.class));
+ var topicSink = mock(TopicSink.class);
+ publisher.active(List.of(topicSink));
+ publisher.sendDecomisioning();
+ verify(topicSink).send(anyString());
+ }
+
+ @Test
+ void testParticipantUpdatePublisherComissioning() {
+ var publisher = new ParticipantUpdatePublisher(mock(ServiceTemplateProvider.class));
+ var topicSink = mock(TopicSink.class);
+ publisher.active(List.of(topicSink));
+ publisher.sendComissioningBroadcast("NAME", "1.0.0");
+ verify(topicSink, times(0)).send(anyString());
+ }
+
+ @Test
+ void testParticipantStatusReqPublisher() {
+ var publisher = new ParticipantStatusReqPublisher();
+ var topicSink = mock(TopicSink.class);
+ publisher.active(List.of(topicSink));
+ publisher.send(getParticipantId());
+ verify(topicSink).send(anyString());
+ }
+
+ @Test
+ void testParticipantRegisterAckPublisher() {
+ var publisher = new ParticipantRegisterAckPublisher();
+ var topicSink = mock(TopicSink.class);
+ publisher.active(List.of(topicSink));
+ publisher.send(UUID.randomUUID(), getParticipantId(), getParticipantType());
+ verify(topicSink).send(anyString());
+ }
+
+ @Test
+ void testParticipantDeregisterAckPublisher() {
+ var publisher = new ParticipantDeregisterAckPublisher();
+ var topicSink = mock(TopicSink.class);
+ publisher.active(List.of(topicSink));
+ publisher.send(UUID.randomUUID());
+ verify(topicSink).send(anyString());
+ }
+
+ private AutomationComposition getAutomationComposition() {
+ var automationComposition = new AutomationComposition();
+ automationComposition.setName("NAME");
+ automationComposition.setVersion("0.0.1");
+ automationComposition.setState(AutomationCompositionState.UNINITIALISED);
+ return automationComposition;
+ }
+
+ private ToscaConceptIdentifier getParticipantId() {
+ return new ToscaConceptIdentifier("org.onap.PM_Policy", "1.0.0");
+ }
+
+ private ToscaConceptIdentifier getParticipantType() {
+ return new ToscaConceptIdentifier("org.onap.policy.acm.PolicyAutomationCompositionParticipant", "2.3.1");
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java
new file mode 100644
index 000000000..33a00c21b
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/CommonTestData.java
@@ -0,0 +1,125 @@
+/*-
+ * ============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.acm.runtime.util;
+
+import java.util.List;
+import javax.ws.rs.core.Response.Status;
+import org.onap.policy.clamp.acm.runtime.main.parameters.AcRuntimeParameterGroup;
+import org.onap.policy.clamp.common.acm.exception.AutomationCompositionRuntimeException;
+import org.onap.policy.clamp.models.acm.concepts.Participant;
+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;
+import org.onap.policy.models.base.PfModelException;
+import org.onap.policy.models.base.PfModelRuntimeException;
+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;
+
+/**
+ * Class to hold/create all parameters for test cases.
+ *
+ */
+public class CommonTestData {
+ private static final Coder CODER = new StandardCoder();
+
+ /**
+ * Gets the standard automation composition parameters.
+ *
+ * @param dbName the database name
+ * @return the standard automation composition parameters
+ * @throws AutomationCompositionRuntimeException on errors reading the automation composition parameters
+ */
+ public static AcRuntimeParameterGroup geParameterGroup(final String dbName) {
+ try {
+ return CODER.convert(getParameterGroupAsString(dbName), AcRuntimeParameterGroup.class);
+
+ } catch (CoderException e) {
+ throw new AutomationCompositionRuntimeException(Status.NOT_ACCEPTABLE,
+ "cannot read automation composition parameters", e);
+ }
+ }
+
+ /**
+ * Gets the standard automation composition parameters, as a String.
+ *
+ * @param dbName the database name
+ * @return the standard automation composition parameters as string
+ */
+ public static String getParameterGroupAsString(final String dbName) {
+ return ResourceUtils.getResourceAsString("src/test/resources/parameters/TestParameters.json")
+ .replace("${dbName}", "jdbc:h2:mem:" + dbName);
+ }
+
+ /**
+ * Create a new PolicyModelsProvider.
+ *
+ * @param databaseProviderParameters the database Provider Parameters
+ * @return a new PolicyModelsProvider
+ */
+ public static PolicyModelsProvider getPolicyModelsProvider(
+ PolicyModelsProviderParameters databaseProviderParameters) {
+ try {
+ return new PolicyModelsProviderFactory().createPolicyModelsProvider(databaseProviderParameters);
+ } catch (PfModelException e) {
+ throw new PfModelRuntimeException(e);
+ }
+ }
+
+ /**
+ * Create a List of Participants.
+ *
+ * @return a List of Participants
+ */
+ public static List<Participant> createParticipants() {
+ var participant1 = createParticipant(
+ new ToscaConceptIdentifier("org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant",
+ "2.3.4"),
+ new ToscaConceptIdentifier("org.onap.dcae.acm.DCAEMicroserviceAutomationCompositionParticipant",
+ "2.3.4"));
+ var participant2 = createParticipant(
+ new ToscaConceptIdentifier("org.onap.policy.acm.PolicyAutomationCompositionParticipant", "2.3.1"),
+ new ToscaConceptIdentifier("org.onap.policy.acm.PolicyAutomationCompositionParticipant", "2.3.1"));
+ var participant3 = createParticipant(
+ new ToscaConceptIdentifier("org.onap.ccsdk.cds.acm.CdsAutomationCompositionParticipant", "2.2.1"),
+ new ToscaConceptIdentifier("org.onap.ccsdk.cds.acm.CdsAutomationCompositionParticipant", "2.2.1"));
+ return List.of(participant1, participant2, participant3);
+ }
+
+ /**
+ * Create a new Participant.
+ *
+ * @param participantType the participant Type
+ * @param participantId the participant id
+ * @return a new Participant
+ */
+ public static Participant createParticipant(ToscaConceptIdentifier participantType,
+ ToscaConceptIdentifier participantId) {
+ var participant = new Participant();
+ participant.setDefinition(participantId);
+ participant.setParticipantType(participantType);
+ participant.setName(participantId.getName());
+ participant.setVersion(participantId.getVersion());
+ return participant;
+ }
+}
diff --git a/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/rest/CommonRestController.java b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/rest/CommonRestController.java
new file mode 100644
index 000000000..0fc0a6e9f
--- /dev/null
+++ b/runtime-acm/src/test/java/org/onap/policy/clamp/acm/runtime/util/rest/CommonRestController.java
@@ -0,0 +1,201 @@
+/*-
+ * ============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.acm.runtime.util.rest;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
+
+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.common.gson.GsonMessageBodyHandler;
+import org.onap.policy.common.utils.network.NetworkUtil;
+
+/**
+ * Class to perform Rest unit tests.
+ *
+ */
+public class CommonRestController {
+
+ public static final String SELF = NetworkUtil.getHostname();
+ public static final String CONTEXT_PATH = "onap/automationcomposition";
+ public static final String ENDPOINT_PREFIX = CONTEXT_PATH + "/v2/";
+ public static final String ACTUATOR_ENDPOINT = CONTEXT_PATH + "/actuator/";
+
+ private static String httpPrefix;
+
+ /**
+ * 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 = sendRequest("api-docs");
+ final String resp = invocationBuilder.get(String.class);
+
+ assertThat(resp).contains(endpoint);
+ }
+
+ /**
+ * 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 actuator endpoint.
+ *
+ * @param endpoint the target endpoint
+ * @return a request builder
+ * @throws Exception if an error occurs
+ */
+ protected Invocation.Builder sendActRequest(final String endpoint) throws Exception {
+ return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + endpoint, true);
+ }
+
+ /**
+ * Sends a request to an Rest Api 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 an actuator endpoint, without any authorization header.
+ *
+ * @param endpoint the target endpoint
+ * @return a request builder
+ * @throws Exception if an error occurs
+ */
+ protected Invocation.Builder sendNoAuthActRequest(final String endpoint) throws Exception {
+ return sendFqeRequest(httpPrefix + ACTUATOR_ENDPOINT + 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("runtimeUser", "zb!XztG34"));
+ }
+
+ final WebTarget webTarget = client.target(fullyQualifiedEndpoint);
+
+ return webTarget.request(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN);
+ }
+
+ /**
+ * 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 GET call to actuator endpoint is Unauthorized.
+ *
+ * @param endPoint the endpoint
+ * @throws Exception if an error occurs
+ */
+ protected void assertUnauthorizedActGet(final String endPoint) throws Exception {
+ Response rawresp = sendNoAuthActRequest(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());
+ }
+
+ /**
+ * Set Up httpPrefix.
+ *
+ * @param port the port
+ */
+ protected void setHttpPrefix(int port) {
+ httpPrefix = "http://" + SELF + ":" + port + "/";
+ }
+
+ protected String getHttpPrefix() {
+ return httpPrefix;
+ }
+}