2  * ============LICENSE_START=======================================================
 
   3  *  Copyright (C) 2021-2025 OpenInfra Foundation Europe. All rights reserved.
 
   4  *  Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
 
   5  * ================================================================================
 
   6  * Licensed under the Apache License, Version 2.0 (the "License");
 
   7  * you may not use this file except in compliance with the License.
 
   8  * You may obtain a copy of the License at
 
  10  *      http://www.apache.org/licenses/LICENSE-2.0
 
  12  * Unless required by applicable law or agreed to in writing, software
 
  13  * distributed under the License is distributed on an "AS IS" BASIS,
 
  14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  15  * See the License for the specific language governing permissions and
 
  16  * limitations under the License.
 
  18  * SPDX-License-Identifier: Apache-2.0
 
  19  * ============LICENSE_END=========================================================
 
  22 package org.onap.policy.clamp.acm.runtime.instantiation.rest;
 
  24 import static org.assertj.core.api.Assertions.assertThat;
 
  25 import static org.junit.jupiter.api.Assertions.assertEquals;
 
  26 import static org.junit.jupiter.api.Assertions.assertNotNull;
 
  27 import static org.junit.jupiter.api.Assertions.assertNull;
 
  28 import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_SERVICE_TEMPLATE_YAML;
 
  29 import static org.onap.policy.clamp.acm.runtime.util.CommonTestData.TOSCA_VERSIONING;
 
  31 import jakarta.ws.rs.client.Entity;
 
  32 import jakarta.ws.rs.core.Response;
 
  33 import java.util.UUID;
 
  34 import org.junit.jupiter.api.BeforeAll;
 
  35 import org.junit.jupiter.api.BeforeEach;
 
  36 import org.junit.jupiter.api.Test;
 
  37 import org.junit.jupiter.api.extension.ExtendWith;
 
  38 import org.onap.policy.clamp.acm.runtime.instantiation.AutomationCompositionInstantiationProvider;
 
  39 import org.onap.policy.clamp.acm.runtime.instantiation.InstantiationUtils;
 
  40 import org.onap.policy.clamp.acm.runtime.main.rest.InstantiationController;
 
  41 import org.onap.policy.clamp.acm.runtime.util.CommonTestData;
 
  42 import org.onap.policy.clamp.acm.runtime.util.rest.CommonRestController;
 
  43 import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 
  44 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
 
  45 import org.onap.policy.clamp.models.acm.concepts.AutomationCompositions;
 
  46 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 
  47 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate;
 
  48 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder;
 
  49 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
 
  50 import org.onap.policy.clamp.models.acm.persistence.provider.AcDefinitionProvider;
 
  51 import org.onap.policy.clamp.models.acm.persistence.provider.ParticipantProvider;
 
  52 import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 
  53 import org.springframework.beans.factory.annotation.Autowired;
 
  54 import org.springframework.boot.test.context.SpringBootTest;
 
  55 import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
 
  56 import org.springframework.boot.test.web.server.LocalServerPort;
 
  57 import org.springframework.data.domain.Pageable;
 
  58 import org.springframework.test.context.ActiveProfiles;
 
  59 import org.springframework.test.context.junit.jupiter.SpringExtension;
 
  62  * Class to perform unit test of {@link InstantiationController}}.
 
  65 @ExtendWith(SpringExtension.class)
 
  66 @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
 
  67 @ActiveProfiles({ "test", "default" })
 
  68 class InstantiationControllerTest extends CommonRestController {
 
  70     private static final int NUMBER_ISTANCES = 10;
 
  71     private static final String AC_INSTANTIATION_CREATE_JSON = "src/test/resources/rest/acm/AutomationComposition.json";
 
  72     private static final String AC_VERSIONING_YAML = "src/test/resources/rest/acm/AutomationCompositionVersioning.yaml";
 
  74     private static final String AC_INSTANTIATION_UPDATE_JSON =
 
  75             "src/test/resources/rest/acm/AutomationCompositionUpdate.json";
 
  77     private static final String INSTANTIATION_ENDPOINT = "compositions/%s/instances";
 
  79     private static ToscaServiceTemplate serviceTemplate = new ToscaServiceTemplate();
 
  81     private static final String NODE_TYPE = "org.onap.policy.clamp.acm.AutomationComposition";
 
  84     private AcDefinitionProvider acDefinitionProvider;
 
  87     private ParticipantProvider participantProvider;
 
  90     private AutomationCompositionInstantiationProvider instantiationProvider;
 
  93     private int randomServerPort;
 
  96     public static void setUpBeforeClass() {
 
  97         serviceTemplate = InstantiationUtils.getToscaServiceTemplate(TOSCA_SERVICE_TEMPLATE_YAML);
 
 101     public void setUpPort() {
 
 102         super.setHttpPrefix(randomServerPort);
 
 105     private String getInstanceEndPoint(UUID compositionId) {
 
 106         return String.format(INSTANTIATION_ENDPOINT, compositionId.toString());
 
 109     private String getInstanceEndPoint(UUID compositionId, UUID instanceId) {
 
 110         return String.format(INSTANTIATION_ENDPOINT, compositionId.toString()) + "/" + instanceId;
 
 115         super.testSwagger(String.format(INSTANTIATION_ENDPOINT, "{compositionId}"));
 
 119     void testCreate_Unauthorized() {
 
 120         var automationComposition =
 
 121                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Unauthorized");
 
 123         assertUnauthorizedPost(getInstanceEndPoint(UUID.randomUUID()), Entity.json(automationComposition));
 
 127     void testQuery_Unauthorized() {
 
 128         assertUnauthorizedGet(getInstanceEndPoint(UUID.randomUUID()));
 
 132     void testUpdate_Unauthorized() {
 
 133         var automationComposition =
 
 134                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Unauthorized");
 
 136         assertUnauthorizedPut(getInstanceEndPoint(UUID.randomUUID()), Entity.json(automationComposition));
 
 140     void testDelete_Unauthorized() {
 
 141         assertUnauthorizedDelete(getInstanceEndPoint(UUID.randomUUID()));
 
 146         var compositionId = createAcDefinitionInDB("Create");
 
 147         var automationCompositionFromRsc =
 
 148                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Create");
 
 149         automationCompositionFromRsc.setCompositionId(compositionId);
 
 151         var instResponse = createAutomationComposition(compositionId, automationCompositionFromRsc,
 
 152             Response.Status.CREATED);
 
 153         InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionFromRsc);
 
 154         automationCompositionFromRsc.setInstanceId(instResponse.getInstanceId());
 
 155         automationCompositionFromRsc.getElements().values()
 
 156                 .forEach(element -> element.setParticipantId(CommonTestData.getParticipantId()));
 
 158         var automationCompositionFromDb =
 
 159                 instantiationProvider.getAutomationComposition(compositionId, instResponse.getInstanceId());
 
 160         automationCompositionFromRsc.setLastMsg(automationCompositionFromDb.getLastMsg());
 
 162         assertNotNull(automationCompositionFromDb);
 
 163         assertEquals(automationCompositionFromRsc, automationCompositionFromDb);
 
 166     private InstantiationResponse createAutomationComposition(UUID compositionId,
 
 167         AutomationComposition automationComposition, Response.Status statusExpected) {
 
 168         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId));
 
 169         try (var resp = invocationBuilder.post(Entity.json(automationComposition))) {
 
 170             assertEquals(statusExpected.getStatusCode(), resp.getStatus());
 
 171             return resp.readEntity(InstantiationResponse.class);
 
 176     void testCreateBadRequest() {
 
 177         var compositionId = createAcDefinitionInDB("CreateBadRequest");
 
 178         var automationCompositionFromRsc = InstantiationUtils
 
 179                 .getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "CreateBadRequest");
 
 180         automationCompositionFromRsc.setCompositionId(compositionId);
 
 182         createAutomationComposition(compositionId, automationCompositionFromRsc, Response.Status.CREATED);
 
 184         // testing Bad Request: AC already defined
 
 185         var instResponse = createAutomationComposition(compositionId, automationCompositionFromRsc,
 
 186             Response.Status.BAD_REQUEST);
 
 187         assertNotNull(instResponse.getErrorDetails());
 
 188         assertNull(instResponse.getAffectedAutomationComposition());
 
 192     void testVersioning() {
 
 193         var serviceTemplateVer = InstantiationUtils.getToscaServiceTemplate(TOSCA_VERSIONING);
 
 194         var compositionId = createAcDefinitionInDB(serviceTemplateVer);
 
 195         var automationCompositionFromRsc = InstantiationUtils
 
 196             .getAutomationCompositionFromYaml(AC_VERSIONING_YAML, "Versioning");
 
 197         automationCompositionFromRsc.setCompositionId(compositionId);
 
 199             createAutomationComposition(compositionId, automationCompositionFromRsc, Response.Status.CREATED);
 
 200         InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionFromRsc);
 
 204     void testQuery_NoResultWithThisName() {
 
 205         var invocationBuilder =
 
 206                 super.sendRequest(getInstanceEndPoint(UUID.randomUUID()) + "?name=noResultWithThisName");
 
 207         try (var rawresp = invocationBuilder.buildGet().invoke()) {
 
 208             assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
 
 209             var resp = rawresp.readEntity(AutomationCompositions.class);
 
 210             assertThat(resp.getAutomationCompositionList()).isEmpty();
 
 216         var compositionId = createAcDefinitionInDB("Query");
 
 217         var automationComposition =
 
 218                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Query");
 
 219         automationComposition.setCompositionId(compositionId);
 
 221         instantiationProvider.createAutomationComposition(compositionId, automationComposition);
 
 223         var invocationBuilder = super.sendRequest(
 
 224                 getInstanceEndPoint(compositionId) + "?name=" + automationComposition.getKey().getName());
 
 225         try (var rawresp = invocationBuilder.buildGet().invoke()) {
 
 226             assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
 
 227             var automationCompositionsQuery = rawresp.readEntity(AutomationCompositions.class);
 
 228             assertNotNull(automationCompositionsQuery);
 
 229             assertThat(automationCompositionsQuery.getAutomationCompositionList()).hasSize(1);
 
 230             var automationCompositionRc = automationCompositionsQuery.getAutomationCompositionList().get(0);
 
 231             automationComposition.setLastMsg(automationCompositionRc.getLastMsg());
 
 232             assertEquals(automationComposition, automationCompositionRc);
 
 237     void testQueryPageable() {
 
 238         var compositionId = createAcDefinitionInDB("Query");
 
 239         var automationComposition =
 
 240             InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Query");
 
 241         automationComposition.setCompositionId(compositionId);
 
 242         for (var i = 0; i < NUMBER_ISTANCES; i++) {
 
 243             automationComposition.setName("acm_" + i);
 
 244             instantiationProvider.createAutomationComposition(compositionId, automationComposition);
 
 246         var endpoint = getInstanceEndPoint(compositionId);
 
 247         validateQueryPageable(endpoint + "?name=wrong_name", 0);
 
 248         validateQueryPageable(endpoint + "?name=acm_1", 1);
 
 249         validateQueryPageable(endpoint + "?page=1&size=4", 4);
 
 251         validateQueryNotPageable(endpoint + "?page=0");
 
 252         validateQueryNotPageable(endpoint + "?size=5");
 
 253         validateQueryNotPageable(endpoint);
 
 256     private void validateQueryNotPageable(String link) {
 
 257         var invocationBuilder = super.sendRequest(link);
 
 258         try (var response = invocationBuilder.buildGet().invoke()) {
 
 259             assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
 
 260             var resultList = response.readEntity(AutomationCompositions.class);
 
 261             assertNotNull(resultList);
 
 262             assertThat(resultList.getAutomationCompositionList()).hasSizeGreaterThanOrEqualTo(NUMBER_ISTANCES);
 
 266     private void validateQueryPageable(String link, int size) {
 
 267         var invocationBuilder = super.sendRequest(link);
 
 268         try (var response = invocationBuilder.buildGet().invoke()) {
 
 269             assertEquals(Response.Status.OK.getStatusCode(), response.getStatus());
 
 270             var resultList = response.readEntity(AutomationCompositions.class);
 
 271             assertNotNull(resultList);
 
 272             assertThat(resultList.getAutomationCompositionList()).hasSize(size);
 
 278         var compositionId = createAcDefinitionInDB("Get");
 
 279         var automationComposition =
 
 280                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Get");
 
 281         automationComposition.setCompositionId(compositionId);
 
 283         instantiationProvider.createAutomationComposition(compositionId, automationComposition);
 
 285         var invocationBuilder = super.sendRequest(
 
 286                 getInstanceEndPoint(compositionId, automationComposition.getInstanceId()));
 
 287         var rawresp = invocationBuilder.buildGet().invoke();
 
 288         assertEquals(Response.Status.OK.getStatusCode(), rawresp.getStatus());
 
 289         var automationCompositionGet = rawresp.readEntity(AutomationComposition.class);
 
 290         assertNotNull(automationCompositionGet);
 
 291         automationComposition.setLastMsg(automationCompositionGet.getLastMsg());
 
 292         assertEquals(automationComposition, automationCompositionGet);
 
 297         var compositionId = createAcDefinitionInDB("Update");
 
 298         var automationCompositionCreate =
 
 299                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Update");
 
 300         automationCompositionCreate.setCompositionId(compositionId);
 
 302         var response = instantiationProvider.createAutomationComposition(compositionId, automationCompositionCreate);
 
 304         var automationComposition =
 
 305                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_UPDATE_JSON, "Update");
 
 306         automationComposition.setCompositionId(compositionId);
 
 307         automationComposition.setInstanceId(response.getInstanceId());
 
 308         automationComposition.getElements().values()
 
 309                 .forEach(element -> element.setParticipantId(CommonTestData.getParticipantId()));
 
 311         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId));
 
 312         var resp = invocationBuilder.post(Entity.json(automationComposition));
 
 313         assertEquals(Response.Status.OK.getStatusCode(), resp.getStatus());
 
 315         var instResponse = resp.readEntity(InstantiationResponse.class);
 
 316         InstantiationUtils.assertInstantiationResponse(instResponse, automationComposition);
 
 318         var automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(
 
 319                 compositionId, automationComposition.getKey().getName(),
 
 320                 automationComposition.getKey().getVersion(), Pageable.unpaged());
 
 322         assertNotNull(automationCompositionsFromDb);
 
 323         assertThat(automationCompositionsFromDb.getAutomationCompositionList()).hasSize(1);
 
 324         var acFromDb = automationCompositionsFromDb.getAutomationCompositionList().get(0);
 
 325         automationComposition.setLastMsg(acFromDb.getLastMsg());
 
 326         assertEquals(automationComposition, acFromDb);
 
 331         var compositionId = createAcDefinitionInDB("Delete");
 
 332         var automationCompositionFromRsc =
 
 333                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Delete");
 
 334         automationCompositionFromRsc.setCompositionId(compositionId);
 
 337                 instantiationProvider.createAutomationComposition(compositionId, automationCompositionFromRsc);
 
 339         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, instResponse.getInstanceId()));
 
 340         var resp = invocationBuilder.delete();
 
 341         assertEquals(Response.Status.ACCEPTED.getStatusCode(), resp.getStatus());
 
 342         instResponse = resp.readEntity(InstantiationResponse.class);
 
 343         InstantiationUtils.assertInstantiationResponse(instResponse, automationCompositionFromRsc);
 
 345         var automationCompositionsFromDb = instantiationProvider.getAutomationCompositions(compositionId,
 
 346                 automationCompositionFromRsc.getKey().getName(), automationCompositionFromRsc.getKey().getVersion(),
 
 348         assertEquals(DeployState.DELETING,
 
 349                 automationCompositionsFromDb.getAutomationCompositionList().get(0).getDeployState());
 
 353     void testDeleteNotFound() {
 
 354         var compositionId = createAcDefinitionInDB("DeleteNotFound");
 
 355         var automationCompositionFromRsc =
 
 356                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "DelNotFound");
 
 357         automationCompositionFromRsc.setCompositionId(compositionId);
 
 359         instantiationProvider.createAutomationComposition(compositionId, automationCompositionFromRsc);
 
 361         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, UUID.randomUUID()));
 
 362         var resp = invocationBuilder.delete();
 
 363         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus());
 
 367     void testDeploy_NotFound() {
 
 368         var compositionId = createAcDefinitionInDB("Deploy_NotFound");
 
 369         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, UUID.randomUUID()));
 
 370         var resp = invocationBuilder.put(Entity.json(new AcInstanceStateUpdate()));
 
 371         assertEquals(Response.Status.NOT_FOUND.getStatusCode(), resp.getStatus());
 
 375     void testDeploy_BadRequest() {
 
 376         var compositionId = createAcDefinitionInDB("Deploy_BadRequest");
 
 378                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "BadRequest");
 
 379         acFromRsc.setCompositionId(compositionId);
 
 381         var instResponse = instantiationProvider.createAutomationComposition(compositionId, acFromRsc);
 
 383         var command = new AcInstanceStateUpdate();
 
 384         command.setDeployOrder(null);
 
 385         command.setLockOrder(null);
 
 387         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, instResponse.getInstanceId()));
 
 388         var resp = invocationBuilder.put(Entity.json(command));
 
 389         assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), resp.getStatus());
 
 394         var compositionId = createAcDefinitionInDB("Deploy");
 
 395         var automationComposition =
 
 396                 InstantiationUtils.getAutomationCompositionFromResource(AC_INSTANTIATION_CREATE_JSON, "Command");
 
 397         automationComposition.setCompositionId(compositionId);
 
 398         var instResponse = instantiationProvider.createAutomationComposition(compositionId, automationComposition);
 
 400         var instantiationUpdate = new AcInstanceStateUpdate();
 
 401         instantiationUpdate.setDeployOrder(DeployOrder.DEPLOY);
 
 402         instantiationUpdate.setLockOrder(null);
 
 404         var invocationBuilder = super.sendRequest(getInstanceEndPoint(compositionId, instResponse.getInstanceId()));
 
 405         var resp = invocationBuilder.put(Entity.json(instantiationUpdate));
 
 406         assertEquals(Response.Status.ACCEPTED.getStatusCode(), resp.getStatus());
 
 409     private UUID createAcDefinitionInDB(String name) {
 
 410         var serviceTemplateCreate = new ToscaServiceTemplate(serviceTemplate);
 
 411         serviceTemplateCreate.setName(name);
 
 412         return createAcDefinitionInDB(serviceTemplateCreate);
 
 415     private UUID createAcDefinitionInDB(ToscaServiceTemplate serviceTemplateCreate) {
 
 416         var acmDefinition = CommonTestData.createAcDefinition(serviceTemplateCreate, AcTypeState.PRIMED);
 
 417         acDefinitionProvider.updateAcDefinition(acmDefinition, NODE_TYPE);
 
 418         saveDummyParticipantInDb();
 
 419         return acmDefinition.getCompositionId();
 
 422     private void saveDummyParticipantInDb() {
 
 423         var participant = CommonTestData.createParticipant(CommonTestData.getParticipantId());
 
 424         var replica = CommonTestData.createParticipantReplica(CommonTestData.getReplicaId());
 
 425         participant.getReplicas().put(replica.getReplicaId(), replica);
 
 426         participantProvider.saveParticipant(participant);