From 4e0f690867551e6ff679debcc7a1fa531aa4c8e7 Mon Sep 17 00:00:00 2001 From: "aravind.est" Date: Fri, 10 Nov 2023 11:34:30 +0000 Subject: [PATCH] Add ACM interceptor for DME ACM Interceptor interface added. It should be used to inject the specific elements/configuration/values to the existing ACM definition/instantiation. DME ACM interceptor added. It injects the DME parameters from rApp package into the existing ACM definition and instantiation flow. This avoids the direct calls to DME at the time of rApp deployment. This doesn't include any change to modify the direct DME validation on priming time. Issue-ID: NONRTRIC-952 Signed-off-by: aravind.est Change-Id: Ibc624726abd34cb83fcb4b477c27a822becbe156 --- pom.xml | 3 +- rapp-manager-acm/pom.xml | 6 + .../rappmanager/acm/service/AcmDeployer.java | 21 +- .../rappmanager/acm/service/AcmDeployerTest.java | 19 +- .../acm/service/BeanTestConfiguration.java | 25 ++ .../models/rapp/RappResourceBuilder.java | 31 +++ .../oransc/rappmanager/service/RappService.java | 7 +- .../rappmanager/service/RappServiceTest.java | 44 ++- .../rappmanager/dme/models/DataConsumerEntity.java | 41 +++ .../rappmanager/dme/models/DataProducerEntity.java | 41 +++ .../rappmanager/dme/models/InfoTypeEntity.java | 41 +++ .../rappmanager/dme/service/DmeAcmInterceptor.java | 295 +++++++++++++++++++++ .../dme/service/DmeAcmInterceptorTest.java | 121 +++++++++ rapp-manager-models/pom.xml | 10 + .../oransc/rappmanager/models/AcmInterceptor.java | 88 ++++++ .../rappmanager/models/AcmInterceptorTest.java | 107 ++++++++ 16 files changed, 860 insertions(+), 40 deletions(-) create mode 100755 rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/DataConsumerEntity.java create mode 100755 rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/DataProducerEntity.java create mode 100755 rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/InfoTypeEntity.java create mode 100755 rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/service/DmeAcmInterceptor.java create mode 100755 rapp-manager-dme/src/test/java/com/oransc/rappmanager/dme/service/DmeAcmInterceptorTest.java create mode 100755 rapp-manager-models/src/main/java/com/oransc/rappmanager/models/AcmInterceptor.java create mode 100755 rapp-manager-models/src/test/java/com/oransc/rappmanager/models/AcmInterceptorTest.java diff --git a/pom.xml b/pom.xml index 079e4a5..b729099 100755 --- a/pom.xml +++ b/pom.xml @@ -4,6 +4,7 @@ * O-RAN-SC * %% * Copyright (C) 2023 Nordix Foundation +* Copyright (C) 2023 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. @@ -34,9 +35,9 @@ O-RAN SC rApp Management function. rapp-manager-models + rapp-manager-dme rapp-manager-acm rapp-manager-sme - rapp-manager-dme rapp-manager-application diff --git a/rapp-manager-acm/pom.xml b/rapp-manager-acm/pom.xml index 4e81c36..8cb14c4 100755 --- a/rapp-manager-acm/pom.xml +++ b/rapp-manager-acm/pom.xml @@ -4,6 +4,7 @@ * O-RAN-SC * %% * Copyright (C) 2023 Nordix Foundation +* Copyright (C) 2023 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. @@ -43,6 +44,11 @@ rapp-manager-models ${project.version} + + org.o-ran-sc.nonrtric.plt.rappmanager + rapp-manager-dme + ${project.version} + org.onap.policy.clamp policy-clamp-models diff --git a/rapp-manager-acm/src/main/java/com/oransc/rappmanager/acm/service/AcmDeployer.java b/rapp-manager-acm/src/main/java/com/oransc/rappmanager/acm/service/AcmDeployer.java index 26d4418..dea83a4 100755 --- a/rapp-manager-acm/src/main/java/com/oransc/rappmanager/acm/service/AcmDeployer.java +++ b/rapp-manager-acm/src/main/java/com/oransc/rappmanager/acm/service/AcmDeployer.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START====================================================================== * Copyright (C) 2023 Nordix Foundation. All rights reserved. + * Copyright (C) 2023 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. @@ -18,9 +19,11 @@ package com.oransc.rappmanager.acm.service; +import com.google.gson.Gson; import com.oransc.rappmanager.acm.configuration.ACMConfiguration; import com.oransc.rappmanager.acm.rest.AutomationCompositionDefinitionApiClient; import com.oransc.rappmanager.acm.rest.AutomationCompositionInstanceApiClient; +import com.oransc.rappmanager.dme.service.DmeAcmInterceptor; import com.oransc.rappmanager.models.RappDeployer; import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler; import com.oransc.rappmanager.models.rapp.Rapp; @@ -41,6 +44,7 @@ import org.onap.policy.clamp.models.acm.messages.rest.commissioning.PrimeOrder; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.AcInstanceStateUpdate; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.DeployOrder; import org.onap.policy.clamp.models.acm.messages.rest.instantiation.InstantiationResponse; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; @@ -57,6 +61,8 @@ public class AcmDeployer implements RappDeployer { private final RappCsarConfigurationHandler rappCsarConfigurationHandler; private final RappInstanceStateMachine rappInstanceStateMachine; private final ACMConfiguration acmConfiguration; + private final Gson gson; + private final DmeAcmInterceptor dmeAcmInterceptor; void updateACMInstanceState(UUID compositionId, RappACMInstance rappACMInstance, DeployOrder deployOrder) { AcInstanceStateUpdate acInstanceStateUpdate = new AcInstanceStateUpdate(); @@ -75,9 +81,10 @@ public class AcmDeployer implements RappDeployer { public CommissioningResponse createComposition(String compositionPayload) { CommissioningResponse commissioningResponse = null; try { - commissioningResponse = - automationCompositionDefinitionApiClient.createCompositionDefinitions(compositionPayload, - UUID.randomUUID()); + ToscaServiceTemplate toscaServiceTemplate = gson.fromJson(compositionPayload, ToscaServiceTemplate.class); + dmeAcmInterceptor.injectToscaServiceTemplate(toscaServiceTemplate); + commissioningResponse = automationCompositionDefinitionApiClient.createCompositionDefinitions( + gson.toJson(toscaServiceTemplate), UUID.randomUUID()); } catch (Exception e) { logger.warn("Error in creating composition", e); } @@ -129,9 +136,13 @@ public class AcmDeployer implements RappDeployer { String instantiationPayload = rappCsarConfigurationHandler.getInstantiationPayload(rapp, rappInstance.getAcm(), rapp.getCompositionId()); + AutomationComposition automationComposition = + gson.fromJson(instantiationPayload, AutomationComposition.class); + dmeAcmInterceptor.injectAutomationComposition(automationComposition, rapp, rappInstance); + InstantiationResponse instantiationResponse = automationCompositionInstanceApiClient.createCompositionInstance(rapp.getCompositionId(), - instantiationPayload, UUID.randomUUID()); + gson.toJson(automationComposition), UUID.randomUUID()); if (instantiationResponse.getInstanceId() != null) { rappInstance.getAcm().setAcmInstanceId(instantiationResponse.getInstanceId()); updateACMInstanceState(rapp.getCompositionId(), rappInstance.getAcm(), DeployOrder.DEPLOY); @@ -246,8 +257,10 @@ public class AcmDeployer implements RappDeployer { void sendRappInstanceStateEvent(RappInstance rappInstance, DeployState deployState) { if (deployState.equals(DeployState.DEPLOYED)) { rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.ACMDEPLOYED); + rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEDEPLOYED); } else if (deployState.equals(DeployState.UNDEPLOYED)) { rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.ACMUNDEPLOYED); + rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DMEUNDEPLOYED); } else if (deployState.equals(DeployState.DEPLOYING)) { rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DEPLOYING); } else if (deployState.equals(DeployState.UNDEPLOYING)) { 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 5268640..aab5f34 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 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. @@ -34,6 +35,7 @@ import static org.springframework.test.web.client.response.MockRestResponseCreat 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.csar.RappCsarConfigurationHandler; import com.oransc.rappmanager.models.rapp.Rapp; @@ -74,9 +76,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, + RappCsarConfigurationHandler.class, RappCacheService.class, RappInstanceStateMachineConfig.class, + RappInstanceStateMachine.class}) @TestInstance(TestInstance.Lifecycle.PER_CLASS) @AutoConfigureMockMvc class AcmDeployerTest { @@ -162,8 +165,10 @@ class AcmDeployerTest { 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))) @@ -173,7 +178,7 @@ 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(); } @@ -182,7 +187,7 @@ class AcmDeployerTest { 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()); @@ -201,7 +206,7 @@ class AcmDeployerTest { 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()); diff --git a/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/BeanTestConfiguration.java b/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/BeanTestConfiguration.java index a2c2f67..5242f90 100755 --- a/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/BeanTestConfiguration.java +++ b/rapp-manager-acm/src/test/java/com/oransc/rappmanager/acm/service/BeanTestConfiguration.java @@ -1,7 +1,27 @@ +/*- + * ============LICENSE_START====================================================================== + * Copyright (C) 2023 Nordix Foundation. All rights reserved. + * Copyright (C) 2023 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. + * 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. + * ============LICENSE_END======================================================================== + */ + package com.oransc.rappmanager.acm.service; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; import com.oransc.rappmanager.acm.ApiClient; import com.oransc.rappmanager.acm.configuration.ACMConfiguration; import com.oransc.rappmanager.acm.configuration.JacksonMessageConverterConfiguration; @@ -30,6 +50,11 @@ public class BeanTestConfiguration { return objectMapper; } + @Bean + public Gson gson() { + return new Gson(); + } + @Bean public RestTemplateBuilder restTemplateBuilder() { return new RestTemplateBuilder(); diff --git a/rapp-manager-acm/src/test/java/com/oransc/rappmanager/models/rapp/RappResourceBuilder.java b/rapp-manager-acm/src/test/java/com/oransc/rappmanager/models/rapp/RappResourceBuilder.java index 9aa2107..9da38fb 100755 --- a/rapp-manager-acm/src/test/java/com/oransc/rappmanager/models/rapp/RappResourceBuilder.java +++ b/rapp-manager-acm/src/test/java/com/oransc/rappmanager/models/rapp/RappResourceBuilder.java @@ -1,6 +1,26 @@ +/*- + * ============LICENSE_START====================================================================== + * Copyright (C) 2023 Nordix Foundation. All rights reserved. + * Copyright (C) 2023 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. + * 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. + * ============LICENSE_END======================================================================== + */ + package com.oransc.rappmanager.models.rapp; import com.oransc.rappmanager.models.rappinstance.RappACMInstance; +import com.oransc.rappmanager.models.rappinstance.RappDMEInstance; import com.oransc.rappmanager.models.rappinstance.RappInstance; import java.util.Set; @@ -11,6 +31,11 @@ public class RappResourceBuilder { RappResources.ACMResources acmResources = new RappResources.ACMResources("compositions", Set.of()); acmResources.setCompositionInstances(Set.of("kserve-instance")); rappResources.setAcm(acmResources); + RappResources.DMEResources dmeResources = + new RappResources.DMEResources(Set.of("json-file-data-from-filestore"), + Set.of("xml-file-data-from-filestore"), Set.of("json-file-data-producer"), + Set.of("json-file-consumer")); + rappResources.setDme(dmeResources); return rappResources; } @@ -19,6 +44,12 @@ public class RappResourceBuilder { RappACMInstance rappACMInstance = new RappACMInstance(); rappACMInstance.setInstance("kserve-instance"); rappInstance.setAcm(rappACMInstance); + RappDMEInstance rappDMEInstance = new RappDMEInstance(); + rappDMEInstance.setInfoTypeConsumer("json-file-data-from-filestore"); + rappDMEInstance.setInfoTypesProducer(Set.of("xml-file-data-from-filestore")); + rappDMEInstance.setInfoProducer("json-file-data-producer"); + rappDMEInstance.setInfoConsumer("json-file-consumer"); + rappInstance.setDme(rappDMEInstance); return rappInstance; } } diff --git a/rapp-manager-application/src/main/java/com/oransc/rappmanager/service/RappService.java b/rapp-manager-application/src/main/java/com/oransc/rappmanager/service/RappService.java index 278bcbd..9fddd4d 100755 --- a/rapp-manager-application/src/main/java/com/oransc/rappmanager/service/RappService.java +++ b/rapp-manager-application/src/main/java/com/oransc/rappmanager/service/RappService.java @@ -1,6 +1,7 @@ /*- * ============LICENSE_START====================================================================== * Copyright (C) 2023 Nordix Foundation. All rights reserved. + * Copyright (C) 2023 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. @@ -102,8 +103,8 @@ public class RappService { if (rappInstance.getState().equals(RappInstanceState.UNDEPLOYED)) { rappInstance.setReason(null); rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.DEPLOYING); - if (acmDeployer.deployRappInstance(rapp, rappInstance) && smeDeployer.deployRappInstance(rapp, rappInstance) - && dmeDeployer.deployRappInstance(rapp, rappInstance)) { + if (acmDeployer.deployRappInstance(rapp, rappInstance) && smeDeployer.deployRappInstance(rapp, + rappInstance)) { return ResponseEntity.accepted().build(); } return ResponseEntity.status(HttpStatus.BAD_GATEWAY).build(); @@ -119,7 +120,7 @@ public class RappService { rappInstance.setReason(null); rappInstanceStateMachine.sendRappInstanceEvent(rappInstance, RappEvent.UNDEPLOYING); if (acmDeployer.undeployRappInstance(rapp, rappInstance) && smeDeployer.undeployRappInstance(rapp, - rappInstance) && dmeDeployer.undeployRappInstance(rapp, rappInstance)) { + rappInstance)) { return ResponseEntity.accepted().build(); } return ResponseEntity.status(HttpStatus.BAD_GATEWAY).build(); diff --git a/rapp-manager-application/src/test/java/com/oransc/rappmanager/service/RappServiceTest.java b/rapp-manager-application/src/test/java/com/oransc/rappmanager/service/RappServiceTest.java index d9be9b7..7bf8adb 100755 --- a/rapp-manager-application/src/test/java/com/oransc/rappmanager/service/RappServiceTest.java +++ b/rapp-manager-application/src/test/java/com/oransc/rappmanager/service/RappServiceTest.java @@ -1,3 +1,22 @@ +/*- + * ============LICENSE_START====================================================================== + * Copyright (C) 2023 Nordix Foundation. All rights reserved. + * Copyright (C) 2023 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. + * 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. + * ============LICENSE_END======================================================================== + */ + package com.oransc.rappmanager.service; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -174,18 +193,6 @@ class RappServiceTest { assertEquals(HttpStatus.BAD_GATEWAY, rappService.deployRappInstance(rapp, rappInstance).getStatusCode()); } - @Test - void testDeployRappInstanceDmeFailure() { - Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile) - .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build(); - RappInstance rappInstance = new RappInstance(); - rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId()); - when(acmDeployer.deployRappInstance(any(), any())).thenReturn(true); - when(smeDeployer.deployRappInstance(any(), any())).thenReturn(true); - when(dmeDeployer.deployRappInstance(any(), any())).thenReturn(false); - assertEquals(HttpStatus.BAD_GATEWAY, rappService.deployRappInstance(rapp, rappInstance).getStatusCode()); - } - @Test void testDeployRappInstanceFailureWithState() { Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile) @@ -228,19 +235,6 @@ class RappServiceTest { assertEquals(HttpStatus.BAD_GATEWAY, rappService.undeployRappInstance(rapp, rappInstance).getStatusCode()); } - @Test - void testUndeployRappInstanceDmeFailure() { - Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile) - .packageLocation(validCsarFileLocation).state(RappState.PRIMED).build(); - RappInstance rappInstance = new RappInstance(); - rappInstance.setState(RappInstanceState.DEPLOYED); - rappInstanceStateMachine.onboardRappInstance(rappInstance.getRappInstanceId()); - when(acmDeployer.undeployRappInstance(any(), any())).thenReturn(true); - when(smeDeployer.undeployRappInstance(any(), any())).thenReturn(true); - when(dmeDeployer.undeployRappInstance(any(), any())).thenReturn(false); - assertEquals(HttpStatus.BAD_GATEWAY, rappService.undeployRappInstance(rapp, rappInstance).getStatusCode()); - } - @Test void testUndeployRappInstanceInvalidStateFailure() { Rapp rapp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile) diff --git a/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/DataConsumerEntity.java b/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/DataConsumerEntity.java new file mode 100755 index 0000000..b67ec7b --- /dev/null +++ b/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/DataConsumerEntity.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START====================================================================== + * Copyright (C) 2023 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. + * 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. + * ============LICENSE_END======================================================================== + */ + +package com.oransc.rappmanager.dme.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; +import lombok.Data; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +@Data +@Builder +public class DataConsumerEntity { + + @NotNull + @JsonIgnore + private ToscaConceptIdentifier dataConsumerEntityId; + + @NotNull + private String dataConsumerId; + + @NotNull + private String payload; + +} diff --git a/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/DataProducerEntity.java b/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/DataProducerEntity.java new file mode 100755 index 0000000..515a126 --- /dev/null +++ b/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/DataProducerEntity.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START====================================================================== + * Copyright (C) 2023 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. + * 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. + * ============LICENSE_END======================================================================== + */ + +package com.oransc.rappmanager.dme.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; +import lombok.Data; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +@Data +@Builder +public class DataProducerEntity { + + @NotNull + @JsonIgnore + private ToscaConceptIdentifier dataProducerEntityId; + + @NotNull + private String dataProducerId; + + @NotNull + private String payload; + +} diff --git a/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/InfoTypeEntity.java b/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/InfoTypeEntity.java new file mode 100755 index 0000000..a71efe4 --- /dev/null +++ b/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/models/InfoTypeEntity.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START====================================================================== + * Copyright (C) 2023 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. + * 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. + * ============LICENSE_END======================================================================== + */ + +package com.oransc.rappmanager.dme.models; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.validation.constraints.NotNull; +import lombok.Builder; +import lombok.Data; +import org.onap.policy.models.tosca.authorative.concepts.ToscaConceptIdentifier; + +@Data +@Builder +public class InfoTypeEntity { + + @NotNull + @JsonIgnore + private ToscaConceptIdentifier infoTypeEntityId; + + @NotNull + private String infoTypeId; + + @NotNull + private String payload; + +} diff --git a/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/service/DmeAcmInterceptor.java b/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/service/DmeAcmInterceptor.java new file mode 100755 index 0000000..cd8a4f7 --- /dev/null +++ b/rapp-manager-dme/src/main/java/com/oransc/rappmanager/dme/service/DmeAcmInterceptor.java @@ -0,0 +1,295 @@ +/*- + * ============LICENSE_START====================================================================== + * Copyright (C) 2023 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. + * 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. + * ============LICENSE_END======================================================================== + */ + +package com.oransc.rappmanager.dme.service; + +import com.google.gson.JsonParser; +import com.oransc.rappmanager.dme.models.DataConsumerEntity; +import com.oransc.rappmanager.dme.models.DataProducerEntity; +import com.oransc.rappmanager.dme.models.InfoTypeEntity; +import com.oransc.rappmanager.models.AcmInterceptor; +import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler; +import com.oransc.rappmanager.models.rapp.Rapp; +import com.oransc.rappmanager.models.rappinstance.RappInstance; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import lombok.RequiredArgsConstructor; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +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.ToscaProperty; +import org.onap.policy.models.tosca.authorative.concepts.ToscaSchemaDefinition; +import org.onap.policy.models.tosca.authorative.concepts.ToscaServiceTemplate; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class DmeAcmInterceptor implements AcmInterceptor { + + private final RappCsarConfigurationHandler rappCsarConfigurationHandler; + + String dmeInfoTypeEntity = "org.onap.datatypes.policy.clamp.acm.DMEAutomationCompositionElement.InfoTypeEntity"; + String version100 = "1.0.0"; + String version101 = "1.0.1"; + String dmeDataProducerEntity = + "org.onap.datatypes.policy.clamp.acm.DMEAutomationCompositionElement.DataProducerEntity"; + String dmeDataConsumerEntity = + "org.onap.datatypes.policy.clamp.acm.DMEAutomationCompositionElement.DataConsumerEntity"; + String infoTypeEntitiesKey = "infoTypeEntities"; + String dataProducerEntitiesKey = "dataProducerEntities"; + String dataConsumerEntitiesKey = "dataConsumerEntities"; + String toscaServiceTemplateDmeElement = "onap.policy.clamp.ac.element.DMEAutomationCompositionElement"; + String toscaServiceTemplateDmeElementVersion = "1.2.3"; + String toscaNodeTypeDmeElement = "org.onap.policy.clamp.acm.DMEAutomationCompositionElement"; + String payload = "payload"; + + @Override + public void injectToscaServiceTemplate(ToscaServiceTemplate toscaServiceTemplate) { + injectToscaServiceTemplate(toscaServiceTemplate, toscaServiceTemplateDmeElement, + toscaServiceTemplateDmeElementVersion); + } + + @Override + public Map getNodeTemplates() { + Map toscaNodeTemplateMap = new HashMap<>(); + + ToscaNodeTemplate nodeTemplateParticipant = getNodeTemplateParticipant(); + toscaNodeTemplateMap.put("org.onap.policy.clamp.acm.DMEAutomationCompositionParticipant", + nodeTemplateParticipant); + ToscaNodeTemplate dmeAcmElement = getDmeAcmElement(); + toscaNodeTemplateMap.put(toscaServiceTemplateDmeElement, dmeAcmElement); + + return toscaNodeTemplateMap; + } + + @Override + public Map getNodeTypes() { + return Map.of(toscaNodeTypeDmeElement, getNodeType()); + } + + @Override + public Map getDataTypes() { + Map toscaDataTypeMap = new HashMap<>(); + + ToscaDataType dmeInfoTypeDataType = getDmeInfoTypeDataType(); + toscaDataTypeMap.put(dmeInfoTypeEntity, dmeInfoTypeDataType); + + ToscaDataType dmeDataProducerDataType = getDmeDataProducerDataType(); + toscaDataTypeMap.put(dmeDataProducerEntity, dmeDataProducerDataType); + + ToscaDataType dmeDataConsumerDataType = getDmeDataConsumerDataType(); + toscaDataTypeMap.put(dmeDataConsumerEntity, dmeDataConsumerDataType); + + return toscaDataTypeMap; + } + + @Override + public Map getInstantiationElement(Rapp rapp, RappInstance rappInstance) { + ToscaConceptIdentifier toscaConceptIdentifier = new ToscaConceptIdentifier(); + toscaConceptIdentifier.setName(toscaServiceTemplateDmeElement); + toscaConceptIdentifier.setVersion(toscaServiceTemplateDmeElementVersion); + + AutomationCompositionElement automationCompositionElement = new AutomationCompositionElement(); + automationCompositionElement.setDefinition(toscaConceptIdentifier); + + Map properties = new HashMap<>(); + properties.put(infoTypeEntitiesKey, getInfoTypeEntities(rapp, rappInstance)); + properties.put(dataProducerEntitiesKey, getDataProducerEntities(rapp, rappInstance)); + properties.put(dataConsumerEntitiesKey, getDataConsumerEntities(rapp, rappInstance)); + + automationCompositionElement.setProperties(properties); + + return Map.of(automationCompositionElement.getId(), automationCompositionElement); + } + + private List getInfoTypeEntities(Rapp rapp, RappInstance rappInstance) { + List infoTypeEntityList = new ArrayList<>(); + if (rappInstance.getDme().getInfoTypeConsumer() != null) { + String dmeConsumerInfoTypePayload = rappCsarConfigurationHandler.getDmeConsumerInfoTypePayload(rapp, + rappInstance.getDme().getInfoTypeConsumer()); + infoTypeEntityList.add(InfoTypeEntity.builder().infoTypeEntityId( + new ToscaConceptIdentifier(rappInstance.getDme().getInfoTypeConsumer(), version101)) + .infoTypeId(rappInstance.getDme().getInfoTypeConsumer()) + .payload(JsonParser.parseString(dmeConsumerInfoTypePayload).toString()) + .build()); + } + + + if (rappInstance.getDme().getInfoTypesProducer() != null) { + rappInstance.getDme().getInfoTypesProducer().forEach(infoTypeProducer -> { + if (!infoTypeProducer.equals(rappInstance.getDme().getInfoTypeConsumer())) { + String dmeProducerInfoTypePayload = + rappCsarConfigurationHandler.getDmeProducerInfoTypePayload(rapp, infoTypeProducer); + infoTypeEntityList.add(InfoTypeEntity.builder().infoTypeEntityId( + new ToscaConceptIdentifier(infoTypeProducer, version101)).infoTypeId(infoTypeProducer) + .payload(JsonParser.parseString(dmeProducerInfoTypePayload) + .toString()).build()); + } + }); + } + return infoTypeEntityList; + } + + List getDataProducerEntities(Rapp rapp, RappInstance rappInstance) { + List dataProducerEntityList = new ArrayList<>(); + if (rappInstance.getDme().getInfoProducer() != null) { + String dmeInfoProducerPayload = rappCsarConfigurationHandler.getDmeInfoProducerPayload(rapp, + rappInstance.getDme().getInfoProducer()); + dataProducerEntityList.add(DataProducerEntity.builder().dataProducerEntityId( + new ToscaConceptIdentifier(rappInstance.getDme().getInfoProducer(), version101)) + .dataProducerId(rappInstance.getDme().getInfoProducer()) + .payload(JsonParser.parseString(dmeInfoProducerPayload).toString()) + .build()); + } + return dataProducerEntityList; + } + + List getDataConsumerEntities(Rapp rapp, RappInstance rappInstance) { + List dataConsumerEntityList = new ArrayList<>(); + if (rappInstance.getDme().getInfoConsumer() != null) { + String dmeInfoConsumerPayload = rappCsarConfigurationHandler.getDmeInfoConsumerPayload(rapp, + rappInstance.getDme().getInfoConsumer()); + dataConsumerEntityList.add(DataConsumerEntity.builder().dataConsumerEntityId( + new ToscaConceptIdentifier(rappInstance.getDme().getInfoConsumer(), version101)) + .dataConsumerId(rappInstance.getDme().getInfoConsumer()) + .payload(JsonParser.parseString(dmeInfoConsumerPayload).toString()) + .build()); + } + return dataConsumerEntityList; + } + + ToscaNodeTemplate getDmeAcmElement() { + ToscaNodeTemplate toscaNodeTemplate = new ToscaNodeTemplate(); + toscaNodeTemplate.setVersion("1.2.3"); + toscaNodeTemplate.setType(toscaNodeTypeDmeElement); + toscaNodeTemplate.setTypeVersion(version101); + Map propertiesMap = new HashMap<>(); + propertiesMap.put("provider", TEMPLATE_PROVIDER); + propertiesMap.put("participantType", + new ToscaConceptIdentifier("org.onap.policy.clamp.acm.DMEParticipant", "2.3.4")); + toscaNodeTemplate.setProperties(propertiesMap); + return toscaNodeTemplate; + } + + ToscaNodeTemplate getNodeTemplateParticipant() { + ToscaNodeTemplate toscaNodeTemplate = new ToscaNodeTemplate(); + toscaNodeTemplate.setVersion("2.3.4"); + toscaNodeTemplate.setType(AC_NODE_TEMPLATE_PARTICIPANT_TYPE); + toscaNodeTemplate.setTypeVersion(version101); + Map propertiesMap = new HashMap<>(); + propertiesMap.put("provider", TEMPLATE_PROVIDER); + toscaNodeTemplate.setProperties(propertiesMap); + return toscaNodeTemplate; + } + + ToscaDataType getDmeDataConsumerDataType() { + ToscaDataType toscaDataType = new ToscaDataType(); + toscaDataType.setVersion(version100); + toscaDataType.setDerivedFrom(AC_TOSCA_DATA_TYPE_ROOT); + + Map propertyMap = new HashMap<>(); + ToscaProperty dataConsumerEntityIdProperty = getToscaProperty(TOSCA_IDENTIFIER_KEY); + propertyMap.put("dataConsumerEntityId", dataConsumerEntityIdProperty); + ToscaProperty dataConsumerIdProperty = getToscaProperty(TOSCA_PROPERTY_TYPE_STRING); + propertyMap.put("dataConsumerId", dataConsumerIdProperty); + ToscaProperty payloadProperty = getToscaProperty(TOSCA_PROPERTY_TYPE_STRING); + propertyMap.put(payload, payloadProperty); + toscaDataType.setProperties(propertyMap); + + return toscaDataType; + } + + + ToscaDataType getDmeDataProducerDataType() { + ToscaDataType toscaDataType = new ToscaDataType(); + toscaDataType.setVersion(version100); + toscaDataType.setDerivedFrom(AC_TOSCA_DATA_TYPE_ROOT); + + Map propertyMap = new HashMap<>(); + ToscaProperty dataProducerEntityIdProperty = getToscaProperty(TOSCA_IDENTIFIER_KEY); + propertyMap.put("dataProducerEntityId", dataProducerEntityIdProperty); + ToscaProperty dataProducerIdProperty = getToscaProperty(TOSCA_PROPERTY_TYPE_STRING); + propertyMap.put("dataProducerId", dataProducerIdProperty); + ToscaProperty payloadProperty = getToscaProperty(TOSCA_PROPERTY_TYPE_STRING); + propertyMap.put(payload, payloadProperty); + toscaDataType.setProperties(propertyMap); + + return toscaDataType; + } + + ToscaDataType getDmeInfoTypeDataType() { + ToscaDataType toscaDataType = new ToscaDataType(); + toscaDataType.setVersion(version100); + toscaDataType.setDerivedFrom(AC_TOSCA_DATA_TYPE_ROOT); + + Map propertyMap = new HashMap<>(); + ToscaProperty infoTypeEntityIdProperty = getToscaProperty(TOSCA_IDENTIFIER_KEY); + propertyMap.put("infoTypeEntityId", infoTypeEntityIdProperty); + ToscaProperty infoTypeIdProperty = getToscaProperty(TOSCA_PROPERTY_TYPE_STRING); + propertyMap.put("infoTypeId", infoTypeIdProperty); + ToscaProperty payloadProperty = getToscaProperty(TOSCA_PROPERTY_TYPE_STRING); + propertyMap.put(payload, payloadProperty); + toscaDataType.setProperties(propertyMap); + + return toscaDataType; + } + + ToscaProperty getToscaProperty(String type) { + ToscaProperty infoTypeEntityIdProperty = new ToscaProperty(); + infoTypeEntityIdProperty.setType(type); + infoTypeEntityIdProperty.setRequired(true); + return infoTypeEntityIdProperty; + } + + ToscaNodeType getNodeType() { + ToscaNodeType toscaNodeType = new ToscaNodeType(); + toscaNodeType.setVersion(version101); + toscaNodeType.setDerivedFrom(AC_NODE_TYPE_ELEMENT_NAME); + toscaNodeType.setProperties(Map.of(infoTypeEntitiesKey, getInfoTypeProperties(), dataProducerEntitiesKey, + getDataProducerProperties(), dataConsumerEntitiesKey, getDataConsumerProperties())); + return toscaNodeType; + } + + ToscaProperty getInfoTypeProperties() { + return getToscoProperty(dmeInfoTypeEntity, version100); + } + + ToscaProperty getDataProducerProperties() { + return getToscoProperty(dmeDataProducerEntity, version100); + } + + ToscaProperty getDataConsumerProperties() { + return getToscoProperty(dmeDataConsumerEntity, version100); + } + + ToscaProperty getToscoProperty(String schemaType, String schemaTypeVersion) { + ToscaProperty toscaProperty = new ToscaProperty(); + toscaProperty.setType(TOSCA_PROPERTY_TYPE_LIST); + toscaProperty.setRequired(true); + ToscaSchemaDefinition toscaSchemaDefinition = new ToscaSchemaDefinition(); + toscaSchemaDefinition.setType(schemaType); + toscaSchemaDefinition.setTypeVersion(schemaTypeVersion); + toscaProperty.setEntrySchema(toscaSchemaDefinition); + return toscaProperty; + } +} diff --git a/rapp-manager-dme/src/test/java/com/oransc/rappmanager/dme/service/DmeAcmInterceptorTest.java b/rapp-manager-dme/src/test/java/com/oransc/rappmanager/dme/service/DmeAcmInterceptorTest.java new file mode 100755 index 0000000..b5c9c64 --- /dev/null +++ b/rapp-manager-dme/src/test/java/com/oransc/rappmanager/dme/service/DmeAcmInterceptorTest.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START====================================================================== + * Copyright (C) 2023 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. + * 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. + * ============LICENSE_END======================================================================== + */ + +package com.oransc.rappmanager.dme.service; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import com.google.gson.JsonArray; +import com.google.gson.JsonParser; +import com.oransc.rappmanager.models.csar.RappCsarConfigurationHandler; +import com.oransc.rappmanager.models.rapp.Rapp; +import com.oransc.rappmanager.models.rapp.RappDmeResourceBuilder; +import com.oransc.rappmanager.models.rapp.RappState; +import com.oransc.rappmanager.models.rappinstance.RappInstance; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import java.util.stream.Stream; +import org.junit.jupiter.api.Test; +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.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +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.ToscaServiceTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest(classes = {RappCsarConfigurationHandler.class, DmeAcmInterceptor.class}) +class DmeAcmInterceptorTest { + + @Autowired + DmeAcmInterceptor dmeAcmInterceptor; + + RappDmeResourceBuilder rappDmeResourceBuilder = new RappDmeResourceBuilder(); + private static final String validRappFile = "valid-rapp-package.csar"; + String validCsarFileLocation = "src/test/resources/"; + + @ParameterizedTest + @MethodSource("getrAppInstances") + void testInjectAutomationComposition(RappInstance rAppInstance) { + AutomationComposition automationComposition = new AutomationComposition(); + Map elements = + new HashMap<>(Map.of(UUID.randomUUID(), new AutomationCompositionElement())); + automationComposition.setElements(elements); + assertEquals(1, automationComposition.getElements().size()); + Rapp rApp = Rapp.builder().rappId(UUID.randomUUID()).name("").packageName(validRappFile) + .packageLocation(validCsarFileLocation).state(RappState.COMMISSIONED) + .rappResources(rappDmeResourceBuilder.getResources()).build(); + dmeAcmInterceptor.injectAutomationComposition(automationComposition, rApp, rAppInstance); + assertEquals(2, automationComposition.getElements().size()); + } + + @Test + void testInjectToscaServiceTemplate() { + ToscaServiceTemplate toscaServiceTemplate = new ToscaServiceTemplate(); + toscaServiceTemplate.setDataTypes(new HashMap<>(Map.of("datatype1", new ToscaDataType()))); + toscaServiceTemplate.setNodeTypes(new HashMap<>(Map.of("nodetype1", new ToscaNodeType()))); + ToscaTopologyTemplate toscaTopologyTemplate = new ToscaTopologyTemplate(); + ToscaNodeTemplate toscaNodeTemplate = new ToscaNodeTemplate(); + String elements = "elements"; + toscaNodeTemplate.setProperties(new HashMap<>(Map.of(elements, "[{}]"))); + String nodeTemplateKey = "onap.policy.clamp.ac.element.AutomationCompositionDefinition"; + + toscaTopologyTemplate.setNodeTemplates(new HashMap<>(Map.of(nodeTemplateKey, toscaNodeTemplate))); + toscaServiceTemplate.setToscaTopologyTemplate(toscaTopologyTemplate); + Object o = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().get(nodeTemplateKey).getProperties() + .get(elements); + JsonArray elementArray = JsonParser.parseString(o.toString()).getAsJsonArray(); + assertEquals(1, toscaServiceTemplate.getDataTypes().size()); + assertEquals(1, toscaServiceTemplate.getNodeTypes().size()); + assertEquals(1, elementArray.size()); + dmeAcmInterceptor.injectToscaServiceTemplate(toscaServiceTemplate); + Object modObject = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().get(nodeTemplateKey).getProperties() + .get(elements); + JsonArray newElementArray = JsonParser.parseString(modObject.toString()).getAsJsonArray(); + assertEquals(4, toscaServiceTemplate.getDataTypes().size()); + assertEquals(2, toscaServiceTemplate.getNodeTypes().size()); + assertEquals(2, newElementArray.size()); + } + + private static Stream getrAppInstances() { + RappDmeResourceBuilder rappDmeResourceBuilder = new RappDmeResourceBuilder(); + RappInstance rappInstanceProducerEmpty = rappDmeResourceBuilder.getRappInstance(); + RappInstance rappInstanceConsumerEmpty = rappDmeResourceBuilder.getRappInstance(); + RappInstance rappInstanceSameInfoType = rappDmeResourceBuilder.getRappInstance(); + rappInstanceProducerEmpty.getDme().setInfoTypesProducer(null); + rappInstanceProducerEmpty.getDme().setInfoProducer(null); + rappInstanceConsumerEmpty.getDme().setInfoTypeConsumer(null); + rappInstanceConsumerEmpty.getDme().setInfoConsumer(null); + Set infoTypesProducer = new HashSet<>(rappInstanceSameInfoType.getDme().getInfoTypesProducer()); + infoTypesProducer.remove(rappInstanceSameInfoType.getDme().getInfoConsumer()); + rappInstanceSameInfoType.getDme().setInfoTypesProducer(infoTypesProducer); + return Stream.of(Arguments.of(rappDmeResourceBuilder.getRappInstance()), + Arguments.of(rappInstanceProducerEmpty), Arguments.of(rappInstanceConsumerEmpty), + Arguments.of(rappInstanceSameInfoType)); + } +} diff --git a/rapp-manager-models/pom.xml b/rapp-manager-models/pom.xml index 963e47a..9586c73 100755 --- a/rapp-manager-models/pom.xml +++ b/rapp-manager-models/pom.xml @@ -4,6 +4,7 @@ * O-RAN-SC * %% * Copyright (C) 2023 Nordix Foundation +* Copyright (C) 2023 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. @@ -74,6 +75,15 @@ commons-compress ${apache.compress.version} + + org.onap.policy.clamp + policy-clamp-models + ${onap.acm.models.version} + + + com.google.code.gson + gson + org.springframework.boot spring-boot-starter-test diff --git a/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/AcmInterceptor.java b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/AcmInterceptor.java new file mode 100755 index 0000000..b205ef2 --- /dev/null +++ b/rapp-manager-models/src/main/java/com/oransc/rappmanager/models/AcmInterceptor.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START====================================================================== + * Copyright (C) 2023 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. + * 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. + * ============LICENSE_END======================================================================== + */ + +package com.oransc.rappmanager.models; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonParser; +import com.oransc.rappmanager.models.rapp.Rapp; +import com.oransc.rappmanager.models.rappinstance.RappInstance; +import java.util.Map; +import java.util.UUID; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +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.ToscaServiceTemplate; + +public interface AcmInterceptor { + + String AC_DEFINITION_ELEMENT_NAME = "onap.policy.clamp.ac.element.AutomationCompositionDefinition"; + String AC_DEFINITION_ELEMENTS_INDEX = "elements"; + + String AC_NODE_TYPE_ELEMENT_NAME = "org.onap.policy.clamp.acm.AutomationCompositionElement"; + String AC_NODE_TEMPLATE_PARTICIPANT_TYPE = "org.onap.policy.clamp.acm.Participant"; + String AC_TOSCA_DATA_TYPE_ROOT = "tosca.datatypes.Root"; + String TOSCA_IDENTIFIER_KEY = "onap.datatypes.ToscaConceptIdentifier"; + String TEMPLATE_PROVIDER = "NONRTRIC"; + + String TOSCA_PROPERTY_TYPE_STRING = "string"; + String TOSCA_PROPERTY_TYPE_LIST = "list"; + + default void injectToscaServiceTemplate(ToscaServiceTemplate toscaServiceTemplate, String acElementName, + String acElementVersion) { + toscaServiceTemplate.getDataTypes().putAll(getDataTypes()); + toscaServiceTemplate.getNodeTypes().putAll(getNodeTypes()); + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().putAll(getNodeTemplates()); + + Object o = toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().get(AC_DEFINITION_ELEMENT_NAME) + .getProperties().get(AC_DEFINITION_ELEMENTS_INDEX); + + JsonArray elementJsonArray = JsonParser.parseString(o.toString()).getAsJsonArray(); + elementJsonArray.add( + new Gson().toJsonTree(getElementToscaIdentifier(acElementName, acElementVersion)).getAsJsonObject()); + + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().get(AC_DEFINITION_ELEMENT_NAME) + .getProperties().put(AC_DEFINITION_ELEMENTS_INDEX, elementJsonArray); + } + + void injectToscaServiceTemplate(ToscaServiceTemplate toscaServiceTemplate); + + Map getNodeTemplates(); + + Map getNodeTypes(); + + Map getDataTypes(); + + default ToscaConceptIdentifier getElementToscaIdentifier(String acElementName, String acElementVersion) { + ToscaConceptIdentifier toscaConceptIdentifier = new ToscaConceptIdentifier(); + toscaConceptIdentifier.setName(acElementName); + toscaConceptIdentifier.setVersion(acElementVersion); + return toscaConceptIdentifier; + } + + default void injectAutomationComposition(AutomationComposition automationComposition, Rapp rapp, + RappInstance rappInstance) { + automationComposition.getElements().putAll(getInstantiationElement(rapp, rappInstance)); + } + + Map getInstantiationElement(Rapp rapp, RappInstance rappInstance); +} diff --git a/rapp-manager-models/src/test/java/com/oransc/rappmanager/models/AcmInterceptorTest.java b/rapp-manager-models/src/test/java/com/oransc/rappmanager/models/AcmInterceptorTest.java new file mode 100755 index 0000000..0deadfa --- /dev/null +++ b/rapp-manager-models/src/test/java/com/oransc/rappmanager/models/AcmInterceptorTest.java @@ -0,0 +1,107 @@ +/*- + * ============LICENSE_START====================================================================== + * Copyright (C) 2023 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. + * 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. + * ============LICENSE_END======================================================================== + */ + +package com.oransc.rappmanager.models; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.mock; + +import com.google.gson.JsonArray; +import com.google.gson.JsonParser; +import com.oransc.rappmanager.models.rapp.Rapp; +import com.oransc.rappmanager.models.rappinstance.RappInstance; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; +import org.junit.jupiter.api.Test; +import org.onap.policy.clamp.models.acm.concepts.AutomationComposition; +import org.onap.policy.clamp.models.acm.concepts.AutomationCompositionElement; +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.ToscaServiceTemplate; +import org.onap.policy.models.tosca.authorative.concepts.ToscaTopologyTemplate; + +class AcmInterceptorTest implements AcmInterceptor { + + @Test + void testInjectAutomationComposition() { + AutomationComposition automationComposition = new AutomationComposition(); + Map elements = + new HashMap<>(Map.of(UUID.randomUUID(), new AutomationCompositionElement())); + automationComposition.setElements(elements); + assertEquals(1, automationComposition.getElements().size()); + injectAutomationComposition(automationComposition, mock(Rapp.class), mock(RappInstance.class)); + assertEquals(2, automationComposition.getElements().size()); + } + + @Test + void testInjectToscaServiceTemplate() { + ToscaServiceTemplate toscaServiceTemplate = new ToscaServiceTemplate(); + toscaServiceTemplate.setDataTypes(new HashMap<>(Map.of("datatype1", new ToscaDataType()))); + toscaServiceTemplate.setNodeTypes(new HashMap<>(Map.of("nodetype1", new ToscaNodeType()))); + ToscaTopologyTemplate toscaTopologyTemplate = new ToscaTopologyTemplate(); + ToscaNodeTemplate toscaNodeTemplate = new ToscaNodeTemplate(); + String elements = "elements"; + toscaNodeTemplate.setProperties(new HashMap<>(Map.of(elements, "[{}]"))); + String nodeTemplateKey = "onap.policy.clamp.ac.element.AutomationCompositionDefinition"; + + toscaTopologyTemplate.setNodeTemplates(new HashMap<>(Map.of(nodeTemplateKey, toscaNodeTemplate))); + toscaServiceTemplate.setToscaTopologyTemplate(toscaTopologyTemplate); + Object o = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().get(nodeTemplateKey).getProperties() + .get(elements); + JsonArray elementArray = JsonParser.parseString(o.toString()).getAsJsonArray(); + assertEquals(1, toscaServiceTemplate.getDataTypes().size()); + assertEquals(1, toscaServiceTemplate.getNodeTypes().size()); + assertEquals(1, elementArray.size()); + injectToscaServiceTemplate(toscaServiceTemplate); + Object modObject = + toscaServiceTemplate.getToscaTopologyTemplate().getNodeTemplates().get(nodeTemplateKey).getProperties() + .get(elements); + JsonArray newElementArray = JsonParser.parseString(modObject.toString()).getAsJsonArray(); + assertEquals(2, toscaServiceTemplate.getDataTypes().size()); + assertEquals(2, toscaServiceTemplate.getNodeTypes().size()); + assertEquals(2, newElementArray.size()); + } + + @Override + public void injectToscaServiceTemplate(ToscaServiceTemplate toscaServiceTemplate) { + injectToscaServiceTemplate(toscaServiceTemplate, "element1", "1.0.0"); + } + + @Override + public Map getNodeTemplates() { + return new HashMap<>(Map.of(UUID.randomUUID().toString(), new ToscaNodeTemplate())); + } + + @Override + public Map getNodeTypes() { + return new HashMap<>(Map.of(UUID.randomUUID().toString(), new ToscaNodeType())); + } + + @Override + public Map getDataTypes() { + return new HashMap<>(Map.of(UUID.randomUUID().toString(), new ToscaDataType())); + } + + @Override + public Map getInstantiationElement(Rapp rapp, RappInstance rappInstance) { + return new HashMap<>(Map.of(UUID.randomUUID(), new AutomationCompositionElement())); + } +} -- 2.16.6