Merge "Pass rAppInstanceId to k8s participant and create the invoker with the instanc...
[nonrtric/plt/rappmanager.git] / rapp-manager-acm / src / test / java / com / oransc / rappmanager / acm / service / AcmDeployerTest.java
index b866b5a..5f6b509 100755 (executable)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START======================================================================
  * Copyright (C) 2023 Nordix Foundation. All rights reserved.
+ * Copyright (C) 2023-2024 OpenInfra Foundation Europe. 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.
@@ -28,12 +29,15 @@ import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.springframework.test.web.client.match.MockRestRequestMatchers.method;
 import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withServerError;
 import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import com.oransc.rappmanager.acm.configuration.ACMConfiguration;
+import com.oransc.rappmanager.dme.service.DmeAcmInterceptor;
 import com.oransc.rappmanager.models.cache.RappCacheService;
+import com.oransc.rappmanager.models.configuration.RappsEnvironmentConfiguration;
 import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler;
 import com.oransc.rappmanager.models.rapp.Rapp;
 import com.oransc.rappmanager.models.rapp.RappEvent;
@@ -45,16 +49,23 @@ import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachine;
 import com.oransc.rappmanager.models.statemachine.RappInstanceStateMachineConfig;
 import java.io.IOException;
 import java.util.UUID;
+import java.util.stream.Stream;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.TestInstance;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+import org.onap.policy.clamp.models.acm.concepts.AcTypeState;
 import org.onap.policy.clamp.models.acm.concepts.AutomationComposition;
+import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionDefinition;
 import org.onap.policy.clamp.models.acm.concepts.DeployState;
 import org.onap.policy.clamp.models.acm.concepts.LockState;
 import org.onap.policy.clamp.models.acm.messages.rest.commissioning.CommissioningResponse;
 import org.onap.policy.clamp.models.acm.messages.rest.commissioning.PrimeOrder;
 import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse;
+import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -66,9 +77,10 @@ import org.springframework.test.web.client.ExpectedCount;
 import org.springframework.test.web.client.MockRestServiceServer;
 import org.springframework.web.client.RestTemplate;
 
-@SpringBootTest(classes = {BeanTestConfiguration.class, ACMConfiguration.class, AcmDeployer.class,
-        RappCsarConfigurationHandler.class, RappCacheService.class, RappInstanceStateMachineConfig.class,
-        RappInstanceStateMachine.class})
+@SpringBootTest(
+        classes = {BeanTestConfiguration.class, ACMConfiguration.class, AcmDeployer.class, DmeAcmInterceptor.class,
+                RappsEnvironmentConfiguration.class, RappCsarConfigurationHandler.class, RappCacheService.class,
+                RappInstanceStateMachineConfig.class, RappInstanceStateMachine.class})
 @TestInstance(TestInstance.Lifecycle.PER_CLASS)
 @AutoConfigureMockMvc
 class AcmDeployerTest {
@@ -84,11 +96,12 @@ class AcmDeployerTest {
     RappInstanceStateMachine rappInstanceStateMachine;
     @Autowired
     RappCsarConfigurationHandler rappCsarConfigurationHandler;
+    @Autowired
+    ObjectMapper objectMapper;
 
     RappResourceBuilder rappResourceBuilder = new RappResourceBuilder();
     private final String validRappFile = "valid-rapp-package.csar";
     String validCsarFileLocation = "src/test/resources/";
-    ObjectMapper objectMapper = new ObjectMapper();
     String URI_ACM_COMPOSITIONS, URI_ACM_COMPOSITION, URI_ACM_INSTANCES, URI_ACM_INSTANCE;
 
     @BeforeAll
@@ -151,10 +164,11 @@ class AcmDeployerTest {
     void testDeployRappInstance() throws Exception {
 
         UUID compositionId = UUID.randomUUID();
-        UUID rappId = UUID.randomUUID();
         UUID instanceId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
+        Rapp rapp = Rapp.builder().name("").packageName(validRappFile).compositionId(compositionId)
                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
+        RappInstance rappInstance = rappResourceBuilder.getRappInstance();
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
         InstantiationResponse instantiationResponse = new InstantiationResponse();
         instantiationResponse.setInstanceId(instanceId);
         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCES, compositionId)))
@@ -164,7 +178,31 @@ class AcmDeployerTest {
         mockServer.expect(ExpectedCount.once(),
                         requestTo(acmConfiguration.getBaseUrl() + "compositions/" + compositionId + "/instances/" + instanceId))
                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
-        boolean rappDeployStateActual = acmDeployer.deployRappInstance(rapp, rappResourceBuilder.getRappInstance());
+        boolean rappDeployStateActual = acmDeployer.deployRappInstance(rapp, rappInstance);
+        assertTrue(rappDeployStateActual);
+        mockServer.verify();
+    }
+
+    @Test
+    void testDeployRappInstanceWithoutDmeInjection() throws Exception {
+
+        UUID compositionId = UUID.randomUUID();
+        UUID instanceId = UUID.randomUUID();
+        Rapp rapp = Rapp.builder().name("").packageName(validRappFile).compositionId(compositionId)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
+        RappInstance rappInstance = rappResourceBuilder.getRappInstance();
+        rappInstance.setDme(null);
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        InstantiationResponse instantiationResponse = new InstantiationResponse();
+        instantiationResponse.setInstanceId(instanceId);
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCES, compositionId)))
+                .andExpect(method(HttpMethod.POST)).andRespond(
+                        withStatus(HttpStatus.ACCEPTED).contentType(MediaType.APPLICATION_JSON)
+                                .body(objectMapper.writeValueAsString(instantiationResponse)));
+        mockServer.expect(ExpectedCount.once(),
+                        requestTo(acmConfiguration.getBaseUrl() + "compositions/" + compositionId + "/instances/" + instanceId))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
+        boolean rappDeployStateActual = acmDeployer.deployRappInstance(rapp, rappInstance);
         assertTrue(rappDeployStateActual);
         mockServer.verify();
     }
@@ -172,8 +210,7 @@ class AcmDeployerTest {
     @Test
     void testDeployRappInstanceFailureWithNoInstanceId() throws JsonProcessingException {
         UUID compositionId = UUID.randomUUID();
-        UUID rappId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
+        Rapp rapp = Rapp.builder().name("").packageName(validRappFile).compositionId(compositionId)
                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
         RappInstance rappInstance = rappResourceBuilder.getRappInstance();
         rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
@@ -191,8 +228,7 @@ class AcmDeployerTest {
     @Test
     void testDeployRappInstanceFailure() {
         UUID compositionId = UUID.randomUUID();
-        UUID rappId = UUID.randomUUID();
-        Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
+        Rapp rapp = Rapp.builder().name("").packageName(validRappFile).compositionId(compositionId)
                             .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build();
         RappInstance rappInstance = rappResourceBuilder.getRappInstance();
         rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
@@ -258,17 +294,47 @@ class AcmDeployerTest {
     }
 
     @Test
-    void testSyncRappInstanceStatus() throws JsonProcessingException {
+    void testUndeployRappInstanceACMErrorFailure() throws JsonProcessingException {
         UUID compositionId = UUID.randomUUID();
+        UUID rappId = UUID.randomUUID();
         UUID instanceId = UUID.randomUUID();
-        expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.UNDEPLOYING, LockState.UNLOCKING,
+        Rapp rapp = Rapp.builder().name(rappId.toString()).packageName(validRappFile).compositionId(compositionId)
+                            .state(RappState.PRIMED).build();
+        expectAcmGetInstanceToReturnState(compositionId, instanceId, DeployState.DEPLOYED, LockState.LOCKED,
                 ExpectedCount.once());
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId)))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.ACCEPTED));
+        mockServer.expect(ExpectedCount.manyTimes(),
+                        requestTo(String.format(URI_ACM_INSTANCE, compositionId, instanceId))).andExpect(method(HttpMethod.GET))
+                .andRespond(withServerError());
+        RappInstance rappInstance = rappResourceBuilder.getRappInstance();
+        rappInstance.getAcm().setAcmInstanceId(instanceId);
+        rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
+        boolean rappUndeployStateActual = acmDeployer.undeployRappInstance(rapp, rappInstance);
+        mockServer.verify();
+        assertFalse(rappUndeployStateActual);
+    }
+
+    @ParameterizedTest
+    @MethodSource("getAcmStatusEventMap")
+    void testSyncRappInstanceStatus(DeployState deployState, LockState lockState, RappEvent rappEvent)
+            throws JsonProcessingException {
+        UUID compositionId = UUID.randomUUID();
+        UUID instanceId = UUID.randomUUID();
+        expectAcmGetInstanceToReturnState(compositionId, instanceId, deployState, lockState, ExpectedCount.once());
         RappInstance rappInstance = rappResourceBuilder.getRappInstance();
         rappInstance.getAcm().setAcmInstanceId(instanceId);
         rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId());
         acmDeployer.syncRappInstanceStatus(compositionId, rappInstance);
         mockServer.verify();
-        verify(rappInstanceStateMachine, times(1)).sendRappInstanceEvent(rappInstance, RappEvent.UNDEPLOYING);
+        verify(rappInstanceStateMachine, times(1)).sendRappInstanceEvent(rappInstance, rappEvent);
+    }
+
+    private static Stream<Arguments> getAcmStatusEventMap() {
+        return Stream.of(Arguments.of(DeployState.UNDEPLOYING, LockState.UNLOCKING, RappEvent.UNDEPLOYING),
+                Arguments.of(DeployState.DEPLOYED, LockState.LOCKED, RappEvent.ACMDEPLOYED),
+                Arguments.of(DeployState.DEPLOYING, LockState.LOCKING, RappEvent.DEPLOYING),
+                Arguments.of(DeployState.UNDEPLOYED, LockState.UNLOCKED, RappEvent.ACMUNDEPLOYED));
     }
 
     @Test
@@ -357,6 +423,45 @@ class AcmDeployerTest {
         commissioningResponseExpected.setCompositionId(compositionId);
         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
+        AutomationCompositionDefinition automationCompositionDefinition =
+                getAutomationCompositionDefinition(compositionId, AcTypeState.COMMISSIONED);
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.GET)).andRespond(
+                        withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                .body(objectMapper.writeValueAsString(automationCompositionDefinition)));
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.DELETE)).andRespond(
+                        withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                .body(objectMapper.writeValueAsString(commissioningResponseExpected)));
+
+        boolean deprimeRapp = acmDeployer.deprimeRapp(rapp);
+        mockServer.verify();
+        assertTrue(deprimeRapp);
+    }
+
+    @Test
+    void testDeprimeRappClientRetry() throws JsonProcessingException {
+        UUID compositionId = UUID.randomUUID();
+        RappResources rappResources = rappResourceBuilder.getResources();
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
+                            .compositionId(compositionId).rappResources(rappResources).build();
+
+        CommissioningResponse commissioningResponseExpected = new CommissioningResponse();
+        commissioningResponseExpected.setCompositionId(compositionId);
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
+        AutomationCompositionDefinition automationCompositionDefinition =
+                getAutomationCompositionDefinition(compositionId, AcTypeState.DEPRIMING);
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.GET)).andRespond(
+                        withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                .body(objectMapper.writeValueAsString(automationCompositionDefinition)));
+        automationCompositionDefinition = getAutomationCompositionDefinition(compositionId, AcTypeState.COMMISSIONED);
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.GET)).andRespond(
+                        withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                .body(objectMapper.writeValueAsString(automationCompositionDefinition)));
         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
                 .andExpect(method(HttpMethod.DELETE)).andRespond(
                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
@@ -368,7 +473,7 @@ class AcmDeployerTest {
     }
 
     @Test
-    void testDeprimeFailureRapp() {
+    void testDeprimeFailureRapp() throws JsonProcessingException {
         UUID compositionId = UUID.randomUUID();
         RappResources rappResources = rappResourceBuilder.getResources();
         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
@@ -377,6 +482,12 @@ class AcmDeployerTest {
 
         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
                 .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
+        AutomationCompositionDefinition automationCompositionDefinition =
+                getAutomationCompositionDefinition(compositionId, AcTypeState.COMMISSIONED);
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.GET)).andRespond(
+                        withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                .body(objectMapper.writeValueAsString(automationCompositionDefinition)));
         mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
                 .andExpect(method(HttpMethod.DELETE)).andRespond(withStatus(HttpStatus.INTERNAL_SERVER_ERROR));
 
@@ -385,6 +496,45 @@ class AcmDeployerTest {
         assertFalse(deprimeRapp);
     }
 
+    @Test
+    void testDeprimeACMStatusFailureRapp() throws JsonProcessingException {
+        UUID compositionId = UUID.randomUUID();
+        RappResources rappResources = rappResourceBuilder.getResources();
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
+                            .compositionId(compositionId).rappResources(rappResources).build();
+
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
+        AutomationCompositionDefinition automationCompositionDefinition =
+                getAutomationCompositionDefinition(compositionId, AcTypeState.DEPRIMING);
+        mockServer.expect(ExpectedCount.manyTimes(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.GET)).andRespond(
+                        withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
+                                .body(objectMapper.writeValueAsString(automationCompositionDefinition)));
+
+        boolean deprimeRapp = acmDeployer.deprimeRapp(rapp);
+        mockServer.verify();
+        assertFalse(deprimeRapp);
+    }
+
+    @Test
+    void testDeprimeACMStatusErrorRapp() {
+        UUID compositionId = UUID.randomUUID();
+        RappResources rappResources = rappResourceBuilder.getResources();
+        Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
+                            .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED)
+                            .compositionId(compositionId).rappResources(rappResources).build();
+
+        mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.PUT)).andRespond(withStatus(HttpStatus.OK));
+        mockServer.expect(ExpectedCount.manyTimes(), requestTo(String.format(URI_ACM_COMPOSITION, compositionId)))
+                .andExpect(method(HttpMethod.GET)).andRespond(withServerError());
+        boolean deprimeRapp = acmDeployer.deprimeRapp(rapp);
+        mockServer.verify();
+        assertFalse(deprimeRapp);
+    }
+
     @Test
     void testDeprimeExceptionRapp() {
         Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile)
@@ -432,4 +582,12 @@ class AcmDeployerTest {
                         withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON)
                                 .body(objectMapper.writeValueAsString(automationCompositionDeployed)));
     }
+
+    AutomationCompositionDefinition getAutomationCompositionDefinition(UUID compositionId, AcTypeState acTypeState) {
+        AutomationCompositionDefinition automationCompositionDefinition = new AutomationCompositionDefinition();
+        automationCompositionDefinition.setCompositionId(compositionId);
+        automationCompositionDefinition.setState(acTypeState);
+        automationCompositionDefinition.setServiceTemplate(new ToscaServiceTemplate());
+        return automationCompositionDefinition;
+    }
 }