X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=rapp-manager-acm%2Fsrc%2Ftest%2Fjava%2Fcom%2Foransc%2Frappmanager%2Facm%2Fservice%2FAcmDeployerTest.java;h=5f6b509ef624ea7fa05ed9df72bb2c4f684881e8;hb=0c011a73756fbba6db7d8e0267ca1e7d17cc1e23;hp=f3016b06cb67ee81382e5988e48e0227ab5838f9;hpb=b45f4856cd283f8b9e3e3372a80767145db6b554;p=nonrtric%2Fplt%2Frappmanager.git diff --git a/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/AcmDeployerTest.java b/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/AcmDeployerTest.java index f3016b0..5f6b509 100755 --- a/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/AcmDeployerTest.java +++ b/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/AcmDeployerTest.java @@ -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,33 +29,43 @@ 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.models.rapp.Rapp; +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; -import com.oransc.rappmanager.models.rappinstance.RappInstance; import com.oransc.rappmanager.models.rapp.RappResourceBuilder; import com.oransc.rappmanager.models.rapp.RappResources; import com.oransc.rappmanager.models.rapp.RappState; -import com.oransc.rappmanager.models.cache.RappCacheService; +import com.oransc.rappmanager.models.rappinstance.RappInstance; 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,24 +178,64 @@ 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 testDeployRappInstanceFailure() throws Exception { + void testDeployRappInstanceWithoutDmeInjection() 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(); + 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(); + } + + @Test + void testDeployRappInstanceFailureWithNoInstanceId() throws JsonProcessingException { + UUID compositionId = UUID.randomUUID(); + 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(); + 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))); + + boolean rappDeployStateActual = acmDeployer.deployRappInstance(rapp, rappInstance); + mockServer.verify(); + assertFalse(rappDeployStateActual); + } + + @Test + void testDeployRappInstanceFailure() { + UUID compositionId = UUID.randomUUID(); + Rapp rapp = Rapp.builder().name("").packageName(validRappFile).compositionId(compositionId) + .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build(); + RappInstance rappInstance = rappResourceBuilder.getRappInstance(); + rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId()); mockServer.expect(ExpectedCount.once(), requestTo(String.format(URI_ACM_INSTANCES, compositionId))) .andExpect(method(HttpMethod.POST)).andRespond(withStatus(HttpStatus.BAD_GATEWAY)); - boolean rappDeployStateActual = acmDeployer.deployRappInstance(rapp, rappResourceBuilder.getRappInstance()); + boolean rappDeployStateActual = acmDeployer.deployRappInstance(rapp, rappInstance); mockServer.verify(); assertFalse(rappDeployStateActual); } @@ -240,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 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 @@ -310,6 +394,23 @@ class AcmDeployerTest { assertEquals(RappState.COMMISSIONED, rapp.getState()); } + @Test + void testPrimeRappFailureWithoutCompositionId() 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(); + mockServer.expect(ExpectedCount.once(), requestTo(URI_ACM_COMPOSITIONS)).andExpect(method(HttpMethod.POST)) + .andRespond(withStatus(HttpStatus.OK).contentType(MediaType.APPLICATION_JSON) + .body(objectMapper.writeValueAsString(commissioningResponseExpected))); + boolean primeRapp = acmDeployer.primeRapp(rapp); + mockServer.verify(); + assertFalse(primeRapp); + } + @Test void testDeprimeRapp() throws JsonProcessingException { UUID compositionId = UUID.randomUUID(); @@ -322,6 +423,12 @@ 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) @@ -333,15 +440,54 @@ class AcmDeployerTest { } @Test - void testDeprimeFailureRapp() { + 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) + .body(objectMapper.writeValueAsString(commissioningResponseExpected))); + + boolean deprimeRapp = acmDeployer.deprimeRapp(rapp); + mockServer.verify(); + assertTrue(deprimeRapp); + } + + @Test + void testDeprimeFailureRapp() 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.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)); @@ -350,6 +496,53 @@ 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) + .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED).build(); + boolean deprimeRapp = acmDeployer.deprimeRapp(rapp); + assertFalse(deprimeRapp); + } + @Test void testDeleteComposition() throws JsonProcessingException { UUID compositionId = UUID.randomUUID(); @@ -389,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; + } }