diff options
16 files changed, 555 insertions, 20 deletions
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java index 0dd7635506..15cf4af62a 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java @@ -121,6 +121,8 @@ public class CreateAAIInventory { cloudInformation.getOwner()); logger.debug("Successfully queried neutron resources and built AAI actions to add l-interfaces to vservers."); + heatBridgeClient.buildAddVolumes(stackResources); + // Update AAI logger.debug("Current Dry Run Value: {}", env.getProperty("heatBridgeDryrun", Boolean.class, false)); heatBridgeClient.submitToAai(env.getProperty("heatBridgeDryrun", Boolean.class, false)); diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java index 1b2fdfedfa..1de7273909 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java @@ -160,6 +160,13 @@ public interface HeatBridgeApi { String cloudOwner) throws HeatBridgeException; /** + * Query and build AAI actions for Openstack volumes + * + * @throws HeatBridgeException when failing to remove heatbridge data from AAI for a given vf-module + */ + void buildAddVolumes(List<Resource> stackResources) throws HeatBridgeException; + + /** * Query and build AAI actions for Openstack Compute resources to AAI's pserver and pinterface objects * * @param stackResources Openstack StackResources list @@ -180,4 +187,6 @@ public interface HeatBridgeApi { * @throws HeatBridgeException when failing to remove heatbridge data from AAI for a given vf-module */ void deleteVfModuleData(String vnfId, String vfModuleId) throws HeatBridgeException; + + } diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java index 0512912b9f..1bf4aff8f6 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java @@ -64,6 +64,7 @@ import org.onap.aai.domain.yang.SriovPf; import org.onap.aai.domain.yang.SriovVf; import org.onap.aai.domain.yang.Subnets; import org.onap.aai.domain.yang.Vlan; +import org.onap.aai.domain.yang.Volume; import org.onap.aai.domain.yang.Vserver; import org.onap.aaiclient.client.aai.AAIDSLQueryClient; import org.onap.aaiclient.client.aai.AAIResourcesClient; @@ -103,6 +104,7 @@ import org.openstack4j.model.network.Network; import org.openstack4j.model.network.NetworkType; import org.openstack4j.model.network.Port; import org.openstack4j.model.network.Subnet; +import org.openstack4j.model.storage.block.VolumeAttachment; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; @@ -421,6 +423,46 @@ public class HeatBridgeImpl implements HeatBridgeApi { } } + @Override + public void buildAddVolumes(List<Resource> stackResources) throws HeatBridgeException { + try { + if (stackResources.stream().anyMatch(r -> r.getType().equals("OS::Cinder::Volume"))) { + stackResources.stream().filter(r -> r.getType().equalsIgnoreCase("OS::Cinder::Volume")) + .forEach(r -> createVolume(r)); + } else { + logger.debug("Heat stack contains no volumes"); + } + } catch (Exception e) { + logger.error("Failed to add volumes to AAI", e); + throw new HeatBridgeException("Failed to add volumes to AAI", e); + } + + } + + protected void createVolume(Resource r) { + org.openstack4j.model.storage.block.Volume osVolume = osClient.getVolumeById(r.getPhysicalResourceId()); + List<? extends VolumeAttachment> attachments = osVolume.getAttachments(); + if (attachments != null) { + Optional<? extends VolumeAttachment> vserver = attachments.stream().findFirst(); + if (vserver.isPresent()) { + Volume volume = new Volume(); + volume.setVolumeId(r.getPhysicalResourceId()); + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .cloudRegion(cloudOwner, cloudRegionId).tenant(tenantId).vserver(vserver.get().getServerId()) + .volume(r.getPhysicalResourceId())); + transaction.createIfNotExists(uri, Optional.of(volume)); + } else { + logger.warn( + "Volume {} contains no attachments in openstack. Unable to determine which vserver volume belongs too.", + r.getPhysicalResourceId()); + } + } else { + logger.warn( + "Volume {} contains no attachments in openstack. Unable to determine which vserver volume belongs too.", + r.getPhysicalResourceId()); + } + } + protected String getInterfaceType(NodeType nodeType, String nicType) { logger.debug("nicType: " + nicType + "nodeType: " + nodeType); if (DIRECT.equalsIgnoreCase(nicType)) { @@ -488,7 +530,13 @@ public class HeatBridgeImpl implements HeatBridgeApi { for (Pserver pserver : serverHostnames.values()) { AAIResourceUri uri = AAIUriFactory .createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure().pserver(pserver.getHostname())); - resourcesClient.createIfNotExists(uri, Optional.of(pserver)); + if (resourcesClient.exists(uri)) { + Pserver updatePserver = new Pserver(); + updatePserver.setPserverId(pserver.getPserverId()); + resourcesClient.update(uri, updatePserver); + } else { + resourcesClient.create(uri, pserver); + } } } diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java index 1f6c0df90f..bbdd05bddc 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java @@ -247,8 +247,8 @@ public class AaiHelper { Pserver pserver = new Pserver(); pserver.setInMaint(false); pserver.setHostname(server.getHypervisorHostname()); - if (server.getId() != null) { - pserver.setPserverId(server.getId()); + if (server.getHostId() != null) { + pserver.setPserverId(server.getHostId()); } if (server.getHost() != null) { pserver.setPserverName2(server.getHost()); diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClient.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClient.java index 8d47ff4ceb..a4aacfe0e2 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClient.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClient.java @@ -43,6 +43,7 @@ import org.openstack4j.model.heat.Resource; import org.openstack4j.model.network.Network; import org.openstack4j.model.network.Port; import org.openstack4j.model.network.Subnet; +import org.openstack4j.model.storage.block.Volume; public interface OpenstackClient { @@ -101,4 +102,11 @@ public interface OpenstackClient { * @return Subnet object. */ Subnet getSubnetById(String subnetId); + + /** + * Get a volume object by volume ID + * + * @return Volume object. + */ + Volume getVolumeById(String volumeId); } diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClientImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClientImpl.java index 1505203d7c..81f09b8a3e 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClientImpl.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClientImpl.java @@ -46,6 +46,8 @@ import org.openstack4j.model.heat.Resource; import org.openstack4j.model.network.Network; import org.openstack4j.model.network.Port; import org.openstack4j.model.network.Subnet; +import org.openstack4j.model.storage.block.Volume; +import org.openstack4j.model.storage.block.VolumeBackup; abstract class OpenstackClientImpl implements OpenstackClient { @Override @@ -84,6 +86,11 @@ abstract class OpenstackClientImpl implements OpenstackClient { return getClient().networking().subnet().get(subnetId); } + @Override + public Volume getVolumeById(String id) { + return getClient().blockStorage().volumes().get(id); + } + /** * Retrieves the specific client to utilize. * diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java index fab7df5345..cf3e1c5ee1 100644 --- a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java +++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java @@ -106,6 +106,8 @@ import org.openstack4j.model.network.Network; import org.openstack4j.model.network.NetworkType; import org.openstack4j.model.network.Port; import org.openstack4j.model.network.Subnet; +import org.openstack4j.model.storage.block.Volume; +import org.openstack4j.model.storage.block.VolumeAttachment; import org.openstack4j.openstack.heat.domain.HeatResource; import org.openstack4j.openstack.heat.domain.HeatResource.Resources; import org.slf4j.Logger; @@ -118,7 +120,6 @@ import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; - @RunWith(MockitoJUnitRunner.Silent.class) public class HeatBridgeImplTest { @@ -808,6 +809,28 @@ public class HeatBridgeImplTest { assertEquals(1, images.size()); } + @Test + public void testBuildAddVolumes() throws HeatBridgeException { + List<Resource> stackResources = (List<Resource>) extractTestStackResources(); + Volume volume = mock(Volume.class); + List<VolumeAttachment> attachments = new ArrayList<>(); + VolumeAttachment server = mock(VolumeAttachment.class); + attachments.add(server); + when(volume.getAttachments()).thenAnswer(x -> attachments); + when(server.getServerId()).thenReturn("vserverIdTest"); + + when(osClient.getVolumeById("5ad95036-8daf-4379-a59c-865f35976ca3")).thenReturn(volume); + + heatbridge.buildAddVolumes(stackResources); + + verify(transaction, times(1)).createIfNotExists( + eq(AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .cloudRegion("CloudOwner", "RegionOne").tenant("7320ec4a5b9d4589ba7c4412ccfd290f") + .vserver("vserverIdTest").volume("5ad95036-8daf-4379-a59c-865f35976ca3"))), + any(Optional.class)); + verify(osClient, times(1)).getVolumeById(eq("5ad95036-8daf-4379-a59c-865f35976ca3")); + } + private List<? extends Resource> extractTestStackResources() { List<HeatResource> stackResources = null; try { @@ -838,4 +861,5 @@ public class HeatBridgeImplTest { } + } diff --git a/adapters/mso-openstack-adapters/src/test/resources/stack-resources.json b/adapters/mso-openstack-adapters/src/test/resources/stack-resources.json index 6b63895a33..159c6665f2 100644 --- a/adapters/mso-openstack-adapters/src/test/resources/stack-resources.json +++ b/adapters/mso-openstack-adapters/src/test/resources/stack-resources.json @@ -436,6 +436,28 @@ "resource_status_reason": "state changed", "physical_resource_id": "5ad95036-8daf-4379-a59c-865f35976cd4", "resource_type": "OS::Neutron::Net" + }, + { + "resource_name": "volume", + "links": [ + { + "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_pfe_network-2wmjvgzrhtvs/290fc2fd-cd1d-47d0-90eb-2ece7c009b29/resources/bridge_network", + "rel": "self" + }, + { + "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_pfe_network-2wmjvgzrhtvs/290fc2fd-cd1d-47d0-90eb-2ece7c009b29", + "rel": "stack" + } + ], + "logical_resource_id": "some_id", + "resource_status": "CREATE_COMPLETE", + "updated_time": "2018-04-09T21:09:55Z", + "required_by": [ + "bridge_network_subnet" + ], + "resource_status_reason": "state changed", + "physical_resource_id": "5ad95036-8daf-4379-a59c-865f35976ca3", + "resource_type": "OS::Cinder::Volume" } ] } diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/UserParamsServiceTraversal.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/UserParamsServiceTraversal.java index 3556cc024c..6c6bd61041 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/UserParamsServiceTraversal.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/UserParamsServiceTraversal.java @@ -104,7 +104,8 @@ public class UserParamsServiceTraversal { if ((vfModuleCustomization.getVfModule() != null) && ((vfModuleCustomization.getVfModule().getModuleHeatTemplate() != null && vfModuleCustomization.getHeatEnvironment() != null)) - || (vfModuleCustomization.getVfModule().getModelName() != null + || (vfModuleCustomization.getVfModule() != null + && vfModuleCustomization.getVfModule().getModelName() != null && vfModuleCustomization.getVfModule().getModelName() .contains("helm"))) { foundVfModuleOrVG = true; diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBTasks.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBTasks.java index ccefc772c3..ec2ca74fa7 100644 --- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBTasks.java +++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionBBTasks.java @@ -420,18 +420,25 @@ public class WorkflowActionBBTasks { } public void postProcessingExecuteBB(DelegateExecution execution) { - List<ExecuteBuildingBlock> flowsToExecute = - (List<ExecuteBuildingBlock>) execution.getVariable("flowsToExecute"); - String handlingCode = (String) execution.getVariable(HANDLINGCODE); - final boolean aLaCarte = (boolean) execution.getVariable(G_ALACARTE); - int currentSequence = (int) execution.getVariable(G_CURRENT_SEQUENCE); - ExecuteBuildingBlock ebb = flowsToExecute.get(currentSequence - 1); - String bbFlowName = ebb.getBuildingBlock().getBpmnFlowName(); - if ("ActivateVfModuleBB".equalsIgnoreCase(bbFlowName) && aLaCarte && "Success".equalsIgnoreCase(handlingCode)) { - postProcessingExecuteBBActivateVfModule(execution, ebb, flowsToExecute); - } + try { + List<ExecuteBuildingBlock> flowsToExecute = + (List<ExecuteBuildingBlock>) execution.getVariable("flowsToExecute"); + String handlingCode = (String) execution.getVariable(HANDLINGCODE); + final boolean aLaCarte = (boolean) execution.getVariable(G_ALACARTE); + int currentSequence = (int) execution.getVariable(G_CURRENT_SEQUENCE); + logger.debug("Current Sequence: {}", currentSequence); + ExecuteBuildingBlock ebb = flowsToExecute.get(currentSequence - 1); + String bbFlowName = ebb.getBuildingBlock().getBpmnFlowName(); + if ("ActivateVfModuleBB".equalsIgnoreCase(bbFlowName) && aLaCarte + && "Success".equalsIgnoreCase(handlingCode)) { + postProcessingExecuteBBActivateVfModule(execution, ebb, flowsToExecute); + } - flowManipulatorListenerRunner.postModifyFlows(flowsToExecute, new DelegateExecutionImpl(execution)); + flowManipulatorListenerRunner.postModifyFlows(flowsToExecute, new DelegateExecutionImpl(execution)); + } catch (Exception ex) { + logger.error("Exception in postProcessingExecuteBB", ex); + workflowAction.buildAndThrowException(execution, "Failed to post process Execute BB"); + } } protected void postProcessingExecuteBBActivateVfModule(DelegateExecution execution, ExecuteBuildingBlock ebb, diff --git a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/decisionpoint/impl/buildingblock/controller/sdnc/prepare/PrepareSdncUpgradePreCheckPnfBBTest.java b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/decisionpoint/impl/buildingblock/controller/sdnc/prepare/PrepareSdncUpgradePreCheckPnfBBTest.java index 0ba1e27f5e..5a070aff4a 100644 --- a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/decisionpoint/impl/buildingblock/controller/sdnc/prepare/PrepareSdncUpgradePreCheckPnfBBTest.java +++ b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/decisionpoint/impl/buildingblock/controller/sdnc/prepare/PrepareSdncUpgradePreCheckPnfBBTest.java @@ -55,16 +55,40 @@ public class PrepareSdncUpgradePreCheckPnfBBTest { } @Test - public void prepare_jsonWithoutActionPayload() { + public void prepareJson_payloadWithoutAction() { String payloadWithoutActionArray = "{\"json name\": \"test1\"}"; ControllerContext<BuildingBlockExecution> controllerContext = - createControllerContext(payloadWithoutActionArray); + createControllerContext(payloadWithoutActionArray, "action1"); testedObject.prepare(controllerContext); assertThat((String) controllerContext.getExecution().getVariable("payload")) .isEqualTo(payloadWithoutActionArray); } + @Test + public void prepareJson_payloadWithActionJsonObject() { + String jsonActionObjectKey = "action1"; + String jsonActionObject = String.format("{\"%s\":\"act1\"}", jsonActionObjectKey); + String payloadWithActionArray = String.format("{\"json name\":\"test1\",\"action\": [%s]}", jsonActionObject); + ControllerContext<BuildingBlockExecution> controllerContext = + createControllerContext(payloadWithActionArray, jsonActionObjectKey); + + testedObject.prepare(controllerContext); + + assertThat((String) controllerContext.getExecution().getVariable("payload")).isEqualTo(jsonActionObject); + } + + @Test + public void prepareJson_payloadWithActionJsonObjectButDifferentKey() { + String payloadWithActionArray = ("{\"json name\":\"test1\",\"action\": [{\"action1\":\"act1\"}]}"); + ControllerContext<BuildingBlockExecution> controllerContext = + createControllerContext(payloadWithActionArray, "otherAction"); + + testedObject.prepare(controllerContext); + + assertThat((String) controllerContext.getExecution().getVariable("payload")).isEqualTo(payloadWithActionArray); + } + private ControllerContext<BuildingBlockExecution> createControllerContext(String actor, String action, String scope) { ControllerContext<BuildingBlockExecution> controllerContext = new ControllerContext<>(); @@ -74,9 +98,10 @@ public class PrepareSdncUpgradePreCheckPnfBBTest { return controllerContext; } - private ControllerContext<BuildingBlockExecution> createControllerContext(String payload) { + private ControllerContext<BuildingBlockExecution> createControllerContext(String payload, String action) { ControllerContext<BuildingBlockExecution> controllerContext = new ControllerContext<>(); controllerContext.setExecution(prepareBuildingBlockExecution(payload)); + controllerContext.setControllerAction(action); return controllerContext; } diff --git a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/service/level/ServiceLevelTest.java b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/service/level/ServiceLevelTest.java new file mode 100644 index 0000000000..cfaa4040c7 --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/service/level/ServiceLevelTest.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2021 Nokia + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.bpmn.infrastructure.service.level; + +import static org.assertj.core.api.Assertions.assertThat; +import java.util.ArrayList; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.camunda.bpm.extension.mockito.delegate.DelegateExecutionFake; +import org.junit.Test; +import java.util.List; +import org.onap.so.bpmn.infrastructure.service.level.impl.ServiceLevelConstants; + +public class ServiceLevelTest { + + private static final String EXECUTION_KEY_PNF_NAME_LIST = "pnfNameList"; + private static final String EXECUTION_KEY_PNF_COUNTER = "pnfCounter"; + + @Test + public void pnfCounterExecution_success() { + // given + String pnfName = "pnfName1"; + DelegateExecution execution = new DelegateExecutionFake(); + execution.setVariable(EXECUTION_KEY_PNF_NAME_LIST, createPnfNameList(pnfName)); + execution.setVariable(EXECUTION_KEY_PNF_COUNTER, 0); + // when + new ServiceLevel().pnfCounterExecution(execution); + // then + assertThat(execution.getVariable(ServiceLevelConstants.PNF_NAME)).isEqualTo(pnfName); + assertThat(execution.getVariable(EXECUTION_KEY_PNF_COUNTER)).isEqualTo(1); + } + + private List<String> createPnfNameList(String pnfName) { + List<String> pnfNameList = new ArrayList<>(); + pnfNameList.add(pnfName); + return pnfNameList; + } +} diff --git a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/UserParamsServiceTraversalTest.java b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/UserParamsServiceTraversalTest.java new file mode 100644 index 0000000000..99f17a3628 --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/UserParamsServiceTraversalTest.java @@ -0,0 +1,219 @@ +/*- + * ============LICENSE_START======================================================= + * ONAP - SO + * ================================================================================ + * Modifications Copyright (c) 2020 Nokia + * ================================================================================ + * 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 org.onap.so.bpmn.infrastructure.workflow.tasks; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.camunda.bpm.engine.delegate.DelegateExecution; +import org.camunda.bpm.extension.mockito.delegate.DelegateExecutionFake; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.onap.so.bpmn.BaseTaskTest; +import org.onap.so.bpmn.common.BBConstants; +import org.onap.so.client.exception.ExceptionBuilder; +import org.onap.so.db.catalog.beans.ConfigurationResource; +import org.onap.so.db.catalog.beans.CvnfcCustomization; +import org.onap.so.db.catalog.beans.HeatTemplate; +import org.onap.so.db.catalog.beans.NetworkCollectionResourceCustomization; +import org.onap.so.db.catalog.beans.VfModuleCustomization; +import org.onap.so.db.catalog.beans.Service; +import org.onap.so.db.catalog.beans.VfModule; +import org.onap.so.db.catalog.beans.CollectionResourceCustomization; +import org.onap.so.db.catalog.beans.CvnfcConfigurationCustomization; +import org.onap.so.db.catalog.beans.HeatEnvironment; +import org.onap.so.db.catalog.client.CatalogDbClient; +import org.onap.so.serviceinstancebeans.ServiceInstancesRequest; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mock; + +public class UserParamsServiceTraversalTest extends BaseTaskTest { + + private static final String MACRO_ASSIGN_JSON = "Macro/ServiceMacroAssign.json"; + private static final String MACRO_ASSIGN_PNF_JSON = "Macro/ServiceMacroAssignPnf.json"; + private static final String NETWORK_COLLECTION_JSON = "Macro/CreateNetworkCollection.json"; + private static final String serviceInstanceId = "123"; + private DelegateExecution execution; + private CatalogDbClient mockCatalogDbClient; + private UserParamsServiceTraversal userParamsServiceTraversal; + private String requestAction; + + @Before + public void before() throws Exception { + execution = new DelegateExecutionFake(); + mockCatalogDbClient = mock(CatalogDbClient.class); + userParamsServiceTraversal = new UserParamsServiceTraversal(mockCatalogDbClient, mock(ExceptionBuilder.class)); + requestAction = "assignInstance"; + } + + @Test + public void getResourceListFromUserParamsForVnfs() throws Exception { + initExecution(requestAction, readBpmnRequestFromFile(MACRO_ASSIGN_JSON), false); + Mockito.doReturn(getVfModuleCustomization()).when(mockCatalogDbClient) + .getVfModuleCustomizationByModelCuztomizationUUID("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f"); + Mockito.doReturn(getCvnfcCustomizations()).when(mockCatalogDbClient).getCvnfcCustomization(anyString(), + anyString(), anyString()); + + List<Resource> resourceListFromUserParams = userParamsServiceTraversal.getResourceListFromUserParams(execution, + getUserParams(), serviceInstanceId, requestAction); + List<WorkflowType> expected = List.of(WorkflowType.SERVICE, WorkflowType.VNF, WorkflowType.VOLUMEGROUP, + WorkflowType.VFMODULE, WorkflowType.CONFIGURATION); + List<WorkflowType> result = + resourceListFromUserParams.stream().map(Resource::getResourceType).collect(Collectors.toList()); + + assertEquals(5, resourceListFromUserParams.size()); + assertThat(expected, is(result)); + } + + @Test + public void getResourceListFromUserParamsForPnfs() throws Exception { + initExecution(requestAction, readBpmnRequestFromFile(MACRO_ASSIGN_PNF_JSON), false); + Mockito.doReturn(getVfModuleCustomization()).when(mockCatalogDbClient) + .getVfModuleCustomizationByModelCuztomizationUUID("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f"); + Mockito.doReturn(getCvnfcCustomizations()).when(mockCatalogDbClient).getCvnfcCustomization(anyString(), + anyString(), anyString()); + + List<Resource> resourceListFromUserParams = userParamsServiceTraversal.getResourceListFromUserParams(execution, + getUserParams(), serviceInstanceId, requestAction); + List<WorkflowType> expected = List.of(WorkflowType.SERVICE, WorkflowType.PNF); + List<WorkflowType> result = + resourceListFromUserParams.stream().map(Resource::getResourceType).collect(Collectors.toList()); + + assertEquals(2, resourceListFromUserParams.size()); + assertThat(expected, is(result)); + } + + @Test + public void getResourceListFromUserParamsForNetworks() throws Exception { + requestAction = "createInstance"; + initExecution(requestAction, readBpmnRequestFromFile(NETWORK_COLLECTION_JSON), false); + Mockito.doReturn(getVfModuleCustomization()).when(mockCatalogDbClient) + .getVfModuleCustomizationByModelCuztomizationUUID("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f"); + Mockito.doReturn(getCvnfcCustomizations()).when(mockCatalogDbClient).getCvnfcCustomization(anyString(), + anyString(), anyString()); + Mockito.doReturn(getService()).when(mockCatalogDbClient).getServiceByID(anyString()); + Mockito.doReturn(new NetworkCollectionResourceCustomization()).when(mockCatalogDbClient) + .getNetworkCollectionResourceCustomizationByID(anyString()); + + List<Resource> resourceListFromUserParams = userParamsServiceTraversal.getResourceListFromUserParams(execution, + getUserParams(), serviceInstanceId, requestAction); + List<WorkflowType> expected = List.of(WorkflowType.SERVICE, WorkflowType.NETWORK, WorkflowType.NETWORK, + WorkflowType.NETWORKCOLLECTION); + List<WorkflowType> result = + resourceListFromUserParams.stream().map(Resource::getResourceType).collect(Collectors.toList()); + + assertEquals(4, resourceListFromUserParams.size()); + assertThat(expected, is(result)); + } + + @Test + public void getResourceListFromUserParamsBuildAndThrowExceptionWhenVfModuleAreEmpty() throws Exception { + initExecution(requestAction, readBpmnRequestFromFile(MACRO_ASSIGN_JSON), false); + VfModuleCustomization vfModuleCustomization = new VfModuleCustomization(); + vfModuleCustomization.setVfModule(null); + Mockito.doReturn(vfModuleCustomization).when(mockCatalogDbClient) + .getVfModuleCustomizationByModelCuztomizationUUID("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f"); + + List<Resource> resourceListFromUserParams = userParamsServiceTraversal.getResourceListFromUserParams(execution, + getUserParams(), serviceInstanceId, requestAction); + List<WorkflowType> expected = List.of(WorkflowType.SERVICE, WorkflowType.VNF); + List<WorkflowType> result = + resourceListFromUserParams.stream().map(Resource::getResourceType).collect(Collectors.toList()); + + assertEquals(2, resourceListFromUserParams.size()); + assertThat(expected, is(result)); + } + + private List<Map<String, Object>> getUserParams() throws IOException { + String bpmnRequest = (String) execution.getVariable(BBConstants.G_BPMN_REQUEST); + ServiceInstancesRequest sIRequest = new ObjectMapper().readValue(bpmnRequest, ServiceInstancesRequest.class); + return sIRequest.getRequestDetails().getRequestParameters().getUserParams(); + } + + @Test + public void getResourceListFromUserParamsWhenUserParamsAreNull() throws Exception { + List<Resource> expectedResourceList = new ArrayList<>(); + List<Resource> resultResourceList = userParamsServiceTraversal.getResourceListFromUserParams(execution, null, + serviceInstanceId, requestAction); + + assertEquals(expectedResourceList, resultResourceList); + } + + private String readBpmnRequestFromFile(String fileName) throws IOException { + return new String(Files.readAllBytes(Paths.get("src/test/resources/__files/" + fileName))); + } + + private void initExecution(String gAction, String bpmnRequest, boolean isAlaCarte) { + execution.setVariable("mso-request-id", "00f704ca-c5e5-4f95-a72c-6889db7b0688"); + execution.setVariable("requestAction", gAction); + execution.setVariable("bpmnRequest", bpmnRequest); + execution.setVariable("aLaCarte", isAlaCarte); + execution.setVariable("apiVersion", "7"); + } + + private Service getService() { + Service service = new Service(); + List<CollectionResourceCustomization> collectionResourceCustomizations = new ArrayList<>(); + CollectionResourceCustomization collectionResourceCustomization = new CollectionResourceCustomization(); + collectionResourceCustomization.setModelCustomizationUUID("123"); + collectionResourceCustomizations.add(collectionResourceCustomization); + service.setCollectionResourceCustomizations(collectionResourceCustomizations); + return service; + } + + private VfModuleCustomization getVfModuleCustomization() { + VfModuleCustomization vfModuleCustomization = new VfModuleCustomization(); + vfModuleCustomization.setVolumeHeatEnv(new HeatEnvironment()); + vfModuleCustomization.setModelCustomizationUUID("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f"); + VfModule vfModule = new VfModule(); + vfModule.setVolumeHeatTemplate(new HeatTemplate()); + vfModule.setModelName("helm"); + vfModule.setModuleHeatTemplate(new HeatTemplate()); + vfModuleCustomization.setVfModule(vfModule); + return vfModuleCustomization; + } + + private List<CvnfcCustomization> getCvnfcCustomizations() { + ConfigurationResource configurationResource = new ConfigurationResource(); + configurationResource.setToscaNodeType("FabricConfiguration"); + + CvnfcConfigurationCustomization cvnfcConfigurationCustomization = new CvnfcConfigurationCustomization(); + cvnfcConfigurationCustomization.setConfigurationResource(configurationResource); + CvnfcCustomization cvnfcCustomization = new CvnfcCustomization(); + + List<CvnfcConfigurationCustomization> cvnfcConfigurationCustomizations = new ArrayList<>(); + cvnfcConfigurationCustomizations.add(cvnfcConfigurationCustomization); + cvnfcCustomization.setCvnfcConfigurationCustomization(cvnfcConfigurationCustomizations); + + List<CvnfcCustomization> cvnfcCustomizations = new ArrayList<>(); + cvnfcCustomizations.add(cvnfcCustomization); + return cvnfcCustomizations; + } +} diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/Macro/ServiceMacroAssignPnf.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/Macro/ServiceMacroAssignPnf.json new file mode 100644 index 0000000000..4be44e0c1f --- /dev/null +++ b/bpmn/so-bpmn-tasks/src/test/resources/__files/Macro/ServiceMacroAssignPnf.json @@ -0,0 +1,72 @@ +{ + "requestDetails": { + "modelInfo": { + "modelType": "service", + "modelInvariantId": "5d48acb5-097d-4982-aeb2-f4a3bd87d31b", + "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", + "modelName": "Sample Service Model", + "modelVersion": "10.0" + }, + "cloudConfiguration": { + "cloudOwner" : "my-custom-cloud-owner" + }, + "owningEntity": { + "owningEntityId": "038d99af-0427-42c2-9d15-971b99b9b489", + "owningEntityName": "PACKET CORE" + }, + "project": { + "projectName": "{some project name}" + }, + "subscriberInfo": { + "globalSubscriberId": "{some subscriber id}" + }, + "requestInfo": { + "productFamilyId": "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", + "source": "VID", + "suppressRollback": true, + "requestorId": "xxxxxx", + "instanceName": "test" + }, + "requestParameters": { + "subscriptionServiceType": "VMX", + "aLaCarte": false, + "userParams": [ + { + "service": { + "modelInfo": { + "modelType": "service", + "modelName": "Sample Service Model", + "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a" + }, + "instanceParams": [], + "resources": { + "pnfs": [ + { + "modelInfo": { + "modelType": "pnf", + "modelName": "2016-73_MOW-AVPN-vPE-BV-L", + "modelVersionId": "7f40c192-f63c-463e-ba94-286933b895f8", + "modelCustomizationName": "2016-73_MOW-AVPN-vPE-BV-L 0", + "modelCustomizationId": "ab153b6e-c364-44c0-bef6-1f2982117f04" + }, + "cloudConfiguration": { + "lcpCloudRegionId": "mdt1", + "tenantId": "88a6ca3ee0394ade9403f075db23167e" + }, + "platform": { + "platformName": "test" + }, + "lineOfBusiness": { + "lineOfBusinessName": "someValue" + }, + "productFamilyId": "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb", + "instanceParams": [] + } + ] + } + } + } + ] + } + } +} diff --git a/releases/1.8.0.yaml b/releases/1.8.0.yaml new file mode 100644 index 0000000000..99bf277e47 --- /dev/null +++ b/releases/1.8.0.yaml @@ -0,0 +1,36 @@ + +--- +distribution_type: 'container' +container_release_tag: '1.8.0' +project: 'so' +log_dir: 'so-maven-docker-stage-master/635/' +ref: '31aba9aba28d7be2417a99ba7e862a7a8c68005b' +containers: + - name: 'so/vnfm-adapter' + version: '1.8.0-20210215T1458' + - name: 'so/catalog-db-adapter' + version: '1.8.0-20210215T1458' + - name: 'so/request-db-adapter' + version: '1.8.0-20210215T1458' + - name: 'so/openstack-adapter' + version: '1.8.0-20210215T1458' + - name: 'so/sdnc-adapter' + version: '1.8.0-20210215T1458' + - name: 'so/vfc-adapter' + version: '1.8.0-20210215T1458' + - name: 'so/sdc-controller' + version: '1.8.0-20210215T1458' + - name: 'so/bpmn-infra' + version: '1.8.0-20210215T1458' + - name: 'so/so-monitoring' + version: '1.8.0-20210215T1458' + - name: 'so/api-handler-infra' + version: '1.8.0-20210215T1458' + - name: 'so/nssmf-adapter' + version: '1.8.0-20210215T1458' + - name: 'so/mso-cnf-adapter' + version: '1.8.0-20210210T0420' + - name: 'so/so-oof-adapter' + version: '1.8.0-20210215T1458' + - name: 'so/so-etsi-nfvo-ns-lcm' + version: '1.8.0-20210215T1458' diff --git a/version.properties b/version.properties index 11f0383267..b3f28cde3f 100644 --- a/version.properties +++ b/version.properties @@ -4,7 +4,7 @@ major=1 minor=8 -patch=0 +patch=1 base_version=${major}.${minor}.${patch} |