Merge "Support instantiation of same model vnfs/vf-modules"
authorSeshu Kumar M <seshu.kumar.m@huawei.com>
Wed, 4 Aug 2021 06:51:34 +0000 (06:51 +0000)
committerGerrit Code Review <gerrit@onap.org>
Wed, 4 Aug 2021 06:51:34 +0000 (06:51 +0000)
31 files changed:
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/entities/ResourceKey.java
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/entities/WorkflowResourceIds.java
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/BBInputSetup.java
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/exceptions/ResourceNotFoundException.java [new file with mode: 0644]
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/cds/ConfigureInstanceParamsForVfModule.java
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/cds/ConfigureInstanceParamsForVnf.java
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/cds/VfModuleCDSRequestProvider.java
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/cds/VnfCDSRequestProvider.java
bpmn/MSOCommonBPMN/src/test/java/org/onap/so/bpmn/servicedecomposition/tasks/BBInputSetupTest.java
bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/cds/AbstractVnfCDSRequestProviderTest.java
bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/cds/ConfigureInstanceParamsForVfModuleTest.java
bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/cds/ConfigureInstanceParamsForVnfTest.java [new file with mode: 0644]
bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/cds/VfModuleCDSRequestProviderTest.java
bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/cds/VnfCDSRequestProviderTest.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/Resource.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowAction.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/ebb/loader/UserParamsServiceTraversal.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/utils/WorkflowResourceIdsUtils.java
bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowActionTest.java
bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/ebb/loader/UserParamsServiceTraversalTest.java
bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/utils/WorkflowResourceIdsUtilsTest.java
bpmn/so-bpmn-tasks/src/test/resources/__files/Macro/ServiceMacroCreateMultipleSameModelVnfsAndVfModules.json [new file with mode: 0644]
mso-api-handlers/mso-api-handler-infra/src/main/java/org/onap/so/apihandlerinfra/validation/UserParamsValidation.java
mso-api-handlers/mso-api-handler-infra/src/test/java/org/onap/so/apihandlerinfra/validation/UserParamsValidationTest.java
mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/RequestParameters/Network.json
mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/RequestParameters/NetworkCloudConfig.json
mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/RequestParameters/NetworkModelCustomizationId.json
mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/RequestParameters/NetworkModelVersionId.json
mso-api-handlers/mso-api-handler-infra/src/test/resources/MsoRequestTest/SuccessfulValidation/ServiceAssign.json
mso-api-handlers/mso-api-handler-infra/src/test/resources/ServiceInstanceTest/ServiceAssign.json
mso-api-handlers/mso-api-handler-infra/src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json [new file with mode: 0644]

index 508709e..5df7c60 100644 (file)
@@ -40,6 +40,8 @@ public class WorkflowResourceIds implements Serializable {
     private String networkCollectionId;
     private String configurationId;
     private String instanceGroupId;
+    private String vnfInstanceName;
+    private String vfModuleInstanceName;
 
 
     public WorkflowResourceIds() {
@@ -139,4 +141,20 @@ public class WorkflowResourceIds implements Serializable {
     public void setInstanceGroupId(String instanceGroupId) {
         this.instanceGroupId = instanceGroupId;
     }
+
+    public String getVnfInstanceName() {
+        return vnfInstanceName;
+    }
+
+    public void setVnfInstanceName(String vnfInstanceName) {
+        this.vnfInstanceName = vnfInstanceName;
+    }
+
+    public String getVfModuleInstanceName() {
+        return vfModuleInstanceName;
+    }
+
+    public void setVfModuleInstanceName(String vfModuleInstanceName) {
+        this.vfModuleInstanceName = vfModuleInstanceName;
+    }
 }
index 83d1f52..569f6b1 100644 (file)
@@ -31,6 +31,7 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.UUID;
+import org.apache.commons.lang3.StringUtils;
 import org.camunda.bpm.engine.delegate.DelegateExecution;
 import org.camunda.bpm.engine.delegate.JavaDelegate;
 import org.javatuples.Pair;
@@ -74,6 +75,7 @@ import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
 import org.onap.so.bpmn.servicedecomposition.generalobjects.OrchestrationContext;
 import org.onap.so.bpmn.servicedecomposition.generalobjects.RequestContext;
 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.NoServiceInstanceFoundException;
+import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.ResourceNotFoundException;
 import org.onap.so.bpmn.servicedecomposition.tasks.exceptions.ServiceModelNotFoundException;
 import org.onap.so.client.exception.ExceptionBuilder;
 import org.onap.so.db.catalog.beans.CollectionNetworkResourceCustomization;
@@ -258,6 +260,8 @@ public class BBInputSetup implements JavaDelegate {
         lookupKeyMap.put(ResourceKey.VOLUME_GROUP_ID, workflowResourceIds.getVolumeGroupId());
         lookupKeyMap.put(ResourceKey.CONFIGURATION_ID, workflowResourceIds.getConfigurationId());
         lookupKeyMap.put(ResourceKey.INSTANCE_GROUP_ID, workflowResourceIds.getInstanceGroupId());
+        lookupKeyMap.put(ResourceKey.VNF_INSTANCE_NAME, workflowResourceIds.getVnfInstanceName());
+        lookupKeyMap.put(ResourceKey.VF_MODULE_INSTANCE_NAME, workflowResourceIds.getVfModuleInstanceName());
     }
 
     protected GeneralBuildingBlock getGBBALaCarteNonService(ExecuteBuildingBlock executeBB,
@@ -1581,7 +1585,13 @@ public class BBInputSetup implements JavaDelegate {
                         .setBbName(bbName).setServiceInstance(serviceInstance).setLookupKeyMap(lookupKeyMap).build();
         if (bbName.contains(VNF) || (bbName.contains(CONTROLLER)
                 && (VNF).equalsIgnoreCase(executeBB.getBuildingBlock().getBpmnScope()))) {
-            vnfs = findVnfsByKey(key, resources, vnfs);
+            String vnfInstanceName = lookupKeyMap.get(ResourceKey.VNF_INSTANCE_NAME);
+            if (StringUtils.isNotBlank(vnfInstanceName)) {
+                vnfs = findVnfsByInstanceName(vnfInstanceName, resources);
+            } else {
+                vnfs = findVnfsByKey(key, resources);
+            }
+
             String vnfId = lookupKeyMap.get(ResourceKey.GENERIC_VNF_ID);
             // This stores the vnf id in request db to be retrieved later when
             // working on a vf module or volume group
@@ -1611,15 +1621,15 @@ public class BBInputSetup implements JavaDelegate {
                     .ifPresent(pnfs -> BBInputSetupPnf.populatePnfToServiceInstance(pnfs, pnfId, serviceInstance));
         } else if (bbName.contains(VF_MODULE) || bbName.contains(VOLUME_GROUP) || (bbName.contains(CONTROLLER)
                 && (VF_MODULE).equalsIgnoreCase(executeBB.getBuildingBlock().getBpmnScope()))) {
-            Pair<Vnfs, VfModules> vnfsAndVfModules = getVfModulesAndItsVnfsByKey(key, resources);
-            if (vnfsAndVfModules != null) {
-                vfModules = vnfsAndVfModules.getValue1();
-                vnfs = vnfsAndVfModules.getValue0();
+            String vfModuleInstanceName = lookupKeyMap.get(ResourceKey.VF_MODULE_INSTANCE_NAME);
+            if (StringUtils.isNotBlank(vfModuleInstanceName)) {
+                vfModules = getVfModulesByInstanceName(vfModuleInstanceName, resources);
+            } else {
+                vfModules = getVfModulesByKey(key, resources);
             }
+
             lookupKeyMap.put(ResourceKey.GENERIC_VNF_ID, getVnfId(executeBB, lookupKeyMap));
-            if (vnfs == null) {
-                throw new Exception("Could not find Vnf to orchestrate VfModule");
-            }
+
             parameter.setModelInfo(vfModules.getModelInfo());
             if (bbName.contains(VOLUME_GROUP)) {
                 parameter.setResourceId(lookupKeyMap.get(ResourceKey.VOLUME_GROUP_ID));
@@ -1682,25 +1692,45 @@ public class BBInputSetup implements JavaDelegate {
         return null;
     }
 
-    protected Pair<Vnfs, VfModules> getVfModulesAndItsVnfsByKey(String key, Resources resources) {
+    protected VfModules getVfModulesByInstanceName(String vfModuleInstanceName, Resources resources) {
+        for (Vnfs vnfs : resources.getVnfs()) {
+            for (VfModules vfModules : vnfs.getVfModules()) {
+                if (vfModules.getInstanceName().equals(vfModuleInstanceName)) {
+                    return vfModules;
+                }
+            }
+        }
+        throw new ResourceNotFoundException(
+                "Could not find vf-module with instanceName: " + vfModuleInstanceName + " in userparams");
+    }
+
+    protected VfModules getVfModulesByKey(String key, Resources resources) {
         for (Vnfs vnfs : resources.getVnfs()) {
             for (VfModules vfModules : vnfs.getVfModules()) {
                 if (vfModules.getModelInfo().getModelCustomizationId().equalsIgnoreCase(key)) {
-                    return new Pair<Vnfs, VfModules>(vnfs, vfModules);
+                    return vfModules;
                 }
             }
         }
-        return null;
+        throw new ResourceNotFoundException("Could not find vf-module with key: " + key + " in userparams");
+    }
+
+    protected Vnfs findVnfsByInstanceName(String instanceName, Resources resources) {
+        for (Vnfs tempVnfs : resources.getVnfs()) {
+            if (tempVnfs.getInstanceName().equals(instanceName)) {
+                return tempVnfs;
+            }
+        }
+        throw new ResourceNotFoundException("Could not find vnf with instanceName: " + instanceName + " in userparams");
     }
 
-    protected Vnfs findVnfsByKey(String key, Resources resources, Vnfs vnfs) {
+    protected Vnfs findVnfsByKey(String key, Resources resources) {
         for (Vnfs tempVnfs : resources.getVnfs()) {
             if (tempVnfs.getModelInfo().getModelCustomizationId().equalsIgnoreCase(key)) {
-                vnfs = tempVnfs;
-                break;
+                return tempVnfs;
             }
         }
-        return vnfs;
+        throw new ResourceNotFoundException("Could not find vnf with key: " + key + " in userparams");
     }
 
     protected CloudRegion getCloudRegionFromMacroRequest(CloudConfiguration cloudConfiguration, Resources resources) {
diff --git a/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/exceptions/ResourceNotFoundException.java b/bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/servicedecomposition/tasks/exceptions/ResourceNotFoundException.java
new file mode 100644 (file)
index 0000000..d8eed96
--- /dev/null
@@ -0,0 +1,14 @@
+package org.onap.so.bpmn.servicedecomposition.tasks.exceptions;
+
+public class ResourceNotFoundException extends RuntimeException {
+
+    static final long serialVersionUID = -2741357347054072719L;
+
+    public ResourceNotFoundException() {
+        super();
+    }
+
+    public ResourceNotFoundException(String message) {
+        super(message);
+    }
+}
index 6f850fa..eeaecb9 100644 (file)
@@ -21,7 +21,7 @@
 package org.onap.so.client.cds;
 
 import com.google.gson.JsonObject;
-import org.onap.so.client.cds.ExtractServiceFromUserParameters;
+import org.apache.commons.lang3.StringUtils;
 import org.onap.so.client.exception.PayloadGenerationException;
 import org.onap.so.serviceinstancebeans.Service;
 import org.onap.so.serviceinstancebeans.VfModules;
@@ -47,12 +47,17 @@ public class ConfigureInstanceParamsForVfModule {
      * @throws PayloadGenerationException- If it doesn't able to populate instance parameters from SO payload.
      */
     public void populateInstanceParams(JsonObject jsonObject, List<Map<String, Object>> userParamsFromRequest,
-            String vnfCustomizationUuid, String vfModuleCustomizationUuid) throws PayloadGenerationException {
+            String vnfCustomizationUuid, String vfModuleCustomizationUuid, String vfModuleInstanceName)
+            throws PayloadGenerationException {
         try {
             Service service = extractServiceFromUserParameters.getServiceFromRequestUserParams(userParamsFromRequest);
 
-            List<Map<String, String>> instanceParamsList =
-                    getInstanceParams(service, vnfCustomizationUuid, vfModuleCustomizationUuid);
+            List<Map<String, String>> instanceParamsList;
+            if (StringUtils.isNotBlank(vfModuleInstanceName)) {
+                instanceParamsList = getInstanceParamsByInstanceNames(service, vfModuleInstanceName);
+            } else {
+                instanceParamsList = getInstanceParams(service, vnfCustomizationUuid, vfModuleCustomizationUuid);
+            }
 
             instanceParamsList.stream().flatMap(instanceParamsMap -> instanceParamsMap.entrySet().stream())
                     .forEachOrdered(entry -> jsonObject.addProperty(entry.getKey(), entry.getValue()));
@@ -61,6 +66,14 @@ public class ConfigureInstanceParamsForVfModule {
         }
     }
 
+    private List<Map<String, String>> getInstanceParamsByInstanceNames(Service service, String vfModuleInstanceName)
+            throws PayloadGenerationException {
+        return service.getResources().getVnfs().stream().map(Vnfs::getVfModules).flatMap(List::stream)
+                .filter(vfm -> vfModuleInstanceName.equals(vfm.getInstanceName())).findFirst()
+                .map(VfModules::getInstanceParams).orElseThrow(() -> new PayloadGenerationException(
+                        "Could not find vfModule with instanceName: " + vfModuleInstanceName));
+    }
+
     private List<Map<String, String>> getInstanceParams(Service service, String vnfCustomizationUuid,
             String vfModuleCustomizationUuid) throws PayloadGenerationException {
 
index 22c9a7b..43283ac 100644 (file)
@@ -21,6 +21,7 @@
 package org.onap.so.client.cds;
 
 import com.google.gson.JsonObject;
+import org.apache.commons.lang3.StringUtils;
 import org.onap.so.client.exception.PayloadGenerationException;
 import org.onap.so.serviceinstancebeans.Service;
 import org.onap.so.serviceinstancebeans.Vnfs;
@@ -45,10 +46,16 @@ public class ConfigureInstanceParamsForVnf {
      * @throws PayloadGenerationException if it doesn't able to populate instance parameters from SO payload.
      */
     public void populateInstanceParams(JsonObject jsonObject, List<Map<String, Object>> userParamsFromRequest,
-            String modelCustomizationUuid) throws PayloadGenerationException {
+            String modelCustomizationUuid, String vnfInstanceName) throws PayloadGenerationException {
         try {
             Service service = extractServiceFromUserParameters.getServiceFromRequestUserParams(userParamsFromRequest);
-            List<Map<String, String>> instanceParamsList = getInstanceParamForVnf(service, modelCustomizationUuid);
+
+            List<Map<String, String>> instanceParamsList;
+            if (StringUtils.isNotBlank(vnfInstanceName)) {
+                instanceParamsList = getInstanceParamByVnfInstanceName(service, vnfInstanceName);
+            } else {
+                instanceParamsList = getInstanceParamForVnf(service, modelCustomizationUuid);
+            }
 
             instanceParamsList.stream().flatMap(instanceParamsMap -> instanceParamsMap.entrySet().stream())
                     .forEachOrdered(entry -> jsonObject.addProperty(entry.getKey(), entry.getValue()));
@@ -57,6 +64,13 @@ public class ConfigureInstanceParamsForVnf {
         }
     }
 
+    private List<Map<String, String>> getInstanceParamByVnfInstanceName(Service service, String instanceName)
+            throws PayloadGenerationException {
+        return service.getResources().getVnfs().stream().filter(vnf -> instanceName.equals(vnf.getInstanceName()))
+                .findFirst().map(Vnfs::getInstanceParams).orElseThrow(
+                        () -> new PayloadGenerationException("Could not find vnf with instanceName: " + instanceName));
+    }
+
     private List<Map<String, String>> getInstanceParamForVnf(Service service, String genericVnfModelCustomizationUuid)
             throws PayloadGenerationException {
         Optional<Vnfs> foundedVnf = service.getResources().getVnfs().stream()
index 478b65c..06ab84a 100644 (file)
@@ -104,9 +104,11 @@ public class VfModuleCDSRequestProvider implements CDSRequestProvider {
             final GeneralBuildingBlock buildingBlock = execution.getGeneralBuildingBlock();
             List<Map<String, Object>> userParamsFromRequest =
                     buildingBlock.getRequestContext().getRequestParameters().getUserParams();
+            String vfModuleInstanceName =
+                    execution.getLookupMap().getOrDefault(ResourceKey.VF_MODULE_INSTANCE_NAME, "");
             if (userParamsFromRequest != null && userParamsFromRequest.size() != 0) {
                 configureInstanceParamsForVfModule.populateInstanceParams(vfModuleObject, userParamsFromRequest,
-                        modelCustomizationUuidForVnf, modelCustomizationUuidForVfModule);
+                        modelCustomizationUuidForVnf, modelCustomizationUuidForVfModule, vfModuleInstanceName);
             }
         } catch (Exception e) {
             throw new PayloadGenerationException("Failed to buildPropertyObject for VF-Module", e);
index 6251eb6..5f63732 100644 (file)
@@ -23,6 +23,7 @@
 package org.onap.so.client.cds;
 
 import com.google.gson.JsonObject;
+import org.apache.commons.lang3.StringUtils;
 import org.onap.so.bpmn.common.BuildingBlockExecution;
 import org.onap.so.bpmn.servicedecomposition.bbobjects.GenericVnf;
 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
@@ -93,9 +94,10 @@ public class VnfCDSRequestProvider implements CDSRequestProvider {
             final GeneralBuildingBlock buildingBlock = execution.getGeneralBuildingBlock();
             List<Map<String, Object>> userParamsFromRequest =
                     buildingBlock.getRequestContext().getRequestParameters().getUserParams();
+            String vnfInstanceName = execution.getLookupMap().getOrDefault(ResourceKey.VNF_INSTANCE_NAME, "");
             if (userParamsFromRequest != null && userParamsFromRequest.size() != 0) {
                 configureInstanceParamsForVnf.populateInstanceParams(vnfObject, userParamsFromRequest,
-                        modelCustomizationUuid);
+                        modelCustomizationUuid, vnfInstanceName);
             }
         } catch (Exception e) {
             throw new PayloadGenerationException("Failed to buildPropertyObjectForVnf", e);
index 127253a..8961c99 100644 (file)
@@ -131,6 +131,8 @@ import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonMappingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import org.onap.so.serviceinstancebeans.VfModules;
+import org.onap.so.serviceinstancebeans.Vnfs;
 
 @RunWith(MockitoJUnitRunner.class)
 public class BBInputSetupTest {
@@ -2116,6 +2118,8 @@ public class BBInputSetupTest {
         String volumeGroupId = "volumeGroupId";
         String configurationId = "configurationId";
         String instanceGroupId = "instancegroupId";
+        String vnfInstanceName = "vnfInstanceName";
+        String vfModuleInstanceName = "vfModuleInstanceName";
 
         expected.put(ResourceKey.SERVICE_INSTANCE_ID, serviceInstanceId);
         expected.put(ResourceKey.NETWORK_ID, networkId);
@@ -2125,6 +2129,8 @@ public class BBInputSetupTest {
         expected.put(ResourceKey.VOLUME_GROUP_ID, volumeGroupId);
         expected.put(ResourceKey.CONFIGURATION_ID, configurationId);
         expected.put(ResourceKey.INSTANCE_GROUP_ID, instanceGroupId);
+        expected.put(ResourceKey.VNF_INSTANCE_NAME, vnfInstanceName);
+        expected.put(ResourceKey.VF_MODULE_INSTANCE_NAME, vfModuleInstanceName);
 
         WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
         workflowResourceIds.setServiceInstanceId(serviceInstanceId);
@@ -2135,12 +2141,52 @@ public class BBInputSetupTest {
         workflowResourceIds.setVolumeGroupId(volumeGroupId);
         workflowResourceIds.setConfigurationId(configurationId);
         workflowResourceIds.setInstanceGroupId(instanceGroupId);
+        workflowResourceIds.setVnfInstanceName(vnfInstanceName);
+        workflowResourceIds.setVfModuleInstanceName(vfModuleInstanceName);
 
         SPY_bbInputSetup.populateLookupKeyMapWithIds(workflowResourceIds, actual);
 
         assertThat(actual, sameBeanAs(expected));
     }
 
+    @Test
+    public void testGetVfModulesByInstanceName() throws IOException {
+        org.onap.so.serviceinstancebeans.Service serviceMacro = mapper.readValue(
+                new File(RESOURCE_PATH + "ServiceMacroVfModules.json"), org.onap.so.serviceinstancebeans.Service.class);
+        Resources resources = serviceMacro.getResources();
+        VfModules expectedVfModule = resources.getVnfs().get(0).getVfModules().get(2);
+        assertEquals(expectedVfModule,
+                SPY_bbInputSetup.getVfModulesByInstanceName("vmxnjr001_AVPN_base_vRE_BV_expansion_002", resources));
+    }
+
+    @Test
+    public void testGetVfModulesByKey() throws IOException {
+        org.onap.so.serviceinstancebeans.Service serviceMacro = mapper.readValue(
+                new File(RESOURCE_PATH + "ServiceMacroVfModules.json"), org.onap.so.serviceinstancebeans.Service.class);
+        Resources resources = serviceMacro.getResources();
+        VfModules expectedVfModule = resources.getVnfs().get(0).getVfModules().get(0);
+        assertEquals(expectedVfModule,
+                SPY_bbInputSetup.getVfModulesByKey("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f", resources));
+    }
+
+    @Test
+    public void testFindVnfsByInstanceName() throws IOException {
+        org.onap.so.serviceinstancebeans.Service serviceMacro = mapper.readValue(
+                new File(RESOURCE_PATH + "ServiceMacroVfModules.json"), org.onap.so.serviceinstancebeans.Service.class);
+        Resources resources = serviceMacro.getResources();
+        Vnfs expectedVnf = resources.getVnfs().get(0);
+        assertEquals(expectedVnf, SPY_bbInputSetup.findVnfsByInstanceName("vmxnjr001", resources));
+    }
+
+    @Test
+    public void testVnfsByKey() throws IOException {
+        org.onap.so.serviceinstancebeans.Service serviceMacro = mapper.readValue(
+                new File(RESOURCE_PATH + "ServiceMacroVfModules.json"), org.onap.so.serviceinstancebeans.Service.class);
+        Resources resources = serviceMacro.getResources();
+        Vnfs expectedVnf = resources.getVnfs().get(0);
+        assertEquals(expectedVnf, SPY_bbInputSetup.findVnfsByKey("ab153b6e-c364-44c0-bef6-1f2982117f04", resources));
+    }
+
     @Test
     public void testGBBMacroNoUserParamsVrfConfiguration() throws Exception {
         String resourceId = "123";
index 06defaa..6de1364 100644 (file)
@@ -82,6 +82,7 @@ public abstract class AbstractVnfCDSRequestProviderTest {
     @Before
     public void setUp() {
         buildingBlockExecution = createBuildingBlockExecution();
+        buildingBlockExecution.setVariable("lookupKeyMap", new HashMap<>());
         executeBuildingBlock = new ExecuteBuildingBlock();
     }
 
index 9baf5dc..0273b9d 100644 (file)
 
 package org.onap.so.client.cds;
 
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
 import com.google.gson.JsonObject;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
-import org.onap.so.bpmn.servicedecomposition.entities.ResourceKey;
 import org.onap.so.serviceinstancebeans.ModelInfo;
 import org.onap.so.serviceinstancebeans.Resources;
 import org.onap.so.serviceinstancebeans.Service;
 import org.onap.so.serviceinstancebeans.VfModules;
 import org.onap.so.serviceinstancebeans.Vnfs;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.ArgumentMatchers.anyList;
-import static org.mockito.Mockito.doReturn;
 
-@RunWith(MockitoJUnitRunner.Silent.class)
+@RunWith(MockitoJUnitRunner.class)
 public class ConfigureInstanceParamsForVfModuleTest {
 
     @InjectMocks
@@ -49,79 +49,77 @@ public class ConfigureInstanceParamsForVfModuleTest {
     @Mock
     private ExtractServiceFromUserParameters extractServiceFromUserParameters;
 
-    private static final String TEST_VNF_MODEL_CUSTOMIZATION_UUID = "23ce9ac4-e5dd-11e9-81b4-2a2ae2dbcce4";
-    private static final String TEST_VF_MODULE_CUSTOMIZATION_UUID = "23ce9ac4-e5dd-11e9-81b4-2a2ae2dbcce2";
-    private static final String TEST_INSTANCE_PARAM_VALUE_1 = "vf-module-1-value";
-    private static final String TEST_INSTANCE_PARAM_VALUE_2 = "vf-module-2-value";
-    private static final String TEST_INSTANCE_PARAM_KEY_1 = "instance-param-1";
-    private static final String TEST_INSTANCE_PARAM_KEY_2 = "instance-param-2";
+    private static final String VNF_CUSTOMIZATION_ID = UUID.randomUUID().toString();
+    private static final String VFMODULE_1_CUSTOMIZATION_ID = UUID.randomUUID().toString();
+    private static final String VFMODULE_2_CUSTOMIZATION_ID = UUID.randomUUID().toString();
+    private static final String VFMODULE_1_INSTANCE_NAME = "vfmodule-instance-1";
+    private static final String VFMODULE_2_INSTANCE_NAME = "vfmodule-instance-2";
+    private static final List<Map<String, String>> VFMODULE_1_INSTANCE_PARAMS =
+            Arrays.asList(Map.of("param-1", "xyz", "param-2", "123"), Map.of("param-3", "CCC"));
+    private static final List<Map<String, String>> VFMODULE_2_INSTANCE_PARAMS =
+            Arrays.asList(Map.of("param-1", "abc", "param-2", "999"), Map.of("param-3", "AAA"));
+
 
     @Test
-    public void testInstanceParamsForVfModule() throws Exception {
-        // given
-        List<Map<String, Object>> userParamsFromRequest = createRequestParameters();
-        JsonObject jsonObject = new JsonObject();
-        doReturn(getUserParams()).when(extractServiceFromUserParameters).getServiceFromRequestUserParams(anyList());
+    public void testPopulateInstanceParamsByInstanceName() throws Exception {
+        Service service = new Service();
+        Resources resources = new Resources();
+        resources.setVnfs(createVnfs());
+        service.setResources(resources);
 
-        // when
-        configureInstanceParamsForVfModule.populateInstanceParams(jsonObject, userParamsFromRequest,
-                TEST_VNF_MODEL_CUSTOMIZATION_UUID, TEST_VF_MODULE_CUSTOMIZATION_UUID);
+        when(extractServiceFromUserParameters.getServiceFromRequestUserParams(any())).thenReturn(service);
+        JsonObject jsonObject = new JsonObject();
 
-        // verify
-        assertEquals(TEST_INSTANCE_PARAM_VALUE_1, jsonObject.get(TEST_INSTANCE_PARAM_KEY_1).getAsString());
-        assertEquals(TEST_INSTANCE_PARAM_VALUE_2, jsonObject.get(TEST_INSTANCE_PARAM_KEY_2).getAsString());
-    }
+        configureInstanceParamsForVfModule.populateInstanceParams(jsonObject, new ArrayList<>(), VNF_CUSTOMIZATION_ID,
+                VFMODULE_2_CUSTOMIZATION_ID, VFMODULE_2_INSTANCE_NAME);
 
-    private List<Map<String, Object>> createRequestParameters() {
-        List<Map<String, Object>> userParams = new ArrayList<>();
-        Map<String, Object> userParamMap = new HashMap<>();
-        userParamMap.put("service", getUserParams());
-        userParams.add(userParamMap);
-        return userParams;
+        assertEquals("abc", jsonObject.get("param-1").getAsString());
+        assertEquals("999", jsonObject.get("param-2").getAsString());
+        assertEquals("AAA", jsonObject.get("param-3").getAsString());
     }
 
-    private Service getUserParams() {
+    @Test
+    public void testPopulateInstanceParamsByCustomizationId() throws Exception {
         Service service = new Service();
         Resources resources = new Resources();
         resources.setVnfs(createVnfs());
         service.setResources(resources);
-        return service;
-    }
-
-    private List<Vnfs> createVnfs() {
-        Vnfs searchedVnf = createVnf();
-        List<Vnfs> vnfList = new ArrayList<>();
-        vnfList.add(searchedVnf);
-        return vnfList;
-    }
-
-    private Vnfs createVnf() {
-        Vnfs vnf = new Vnfs();
-        ModelInfo modelInfoForVnf = new ModelInfo();
-        modelInfoForVnf.setModelCustomizationId(TEST_VNF_MODEL_CUSTOMIZATION_UUID);
-        vnf.setModelInfo(modelInfoForVnf);
-
-        VfModules vfModule = new VfModules();
 
-        ModelInfo modelInfoForVfModule = new ModelInfo();
-        modelInfoForVfModule.setModelCustomizationId(TEST_VF_MODULE_CUSTOMIZATION_UUID);
-
-        vfModule.setModelInfo(modelInfoForVfModule);
-
-        // Set instance parameters.
-        List<Map<String, String>> instanceParamsListSearchedVfModule = new ArrayList<>();
-        Map<String, String> instanceParams = new HashMap<>();
-        instanceParams.put("instance-param-1", TEST_INSTANCE_PARAM_VALUE_1);
-        instanceParams.put("instance-param-2", TEST_INSTANCE_PARAM_VALUE_2);
-
-        instanceParamsListSearchedVfModule.add(instanceParams);
-        vfModule.setInstanceParams(instanceParamsListSearchedVfModule);
+        when(extractServiceFromUserParameters.getServiceFromRequestUserParams(any())).thenReturn(service);
+        JsonObject jsonObject = new JsonObject();
 
-        List<VfModules> vfModules = new ArrayList<>();
-        vfModules.add(vfModule);
+        // No instance name is passed
+        configureInstanceParamsForVfModule.populateInstanceParams(jsonObject, new ArrayList<>(), VNF_CUSTOMIZATION_ID,
+                VFMODULE_1_CUSTOMIZATION_ID, null);
 
-        vnf.setVfModules(vfModules);
+        assertEquals("xyz", jsonObject.get("param-1").getAsString());
+        assertEquals("123", jsonObject.get("param-2").getAsString());
+        assertEquals("CCC", jsonObject.get("param-3").getAsString());
+    }
 
-        return vnf;
+    private List<Vnfs> createVnfs() {
+        Vnfs vnf1 = new Vnfs();
+        ModelInfo modelInfo = new ModelInfo();
+        modelInfo.setModelCustomizationId(VNF_CUSTOMIZATION_ID);
+        vnf1.setModelInfo(modelInfo);
+
+        VfModules vfModule1 = new VfModules();
+        modelInfo = new ModelInfo();
+        modelInfo.setModelCustomizationId(VFMODULE_1_CUSTOMIZATION_ID);
+        vfModule1.setModelInfo(modelInfo);
+        vfModule1.setInstanceName(VFMODULE_1_INSTANCE_NAME);
+        vfModule1.setInstanceParams(VFMODULE_1_INSTANCE_PARAMS);
+
+        VfModules vfModule2 = new VfModules();
+        modelInfo = new ModelInfo();
+        modelInfo.setModelCustomizationId(VFMODULE_2_CUSTOMIZATION_ID);
+        vfModule2.setModelInfo(modelInfo);
+        vfModule2.setInstanceName(VFMODULE_2_INSTANCE_NAME);
+        vfModule2.setInstanceParams(VFMODULE_2_INSTANCE_PARAMS);
+
+        vnf1.setVfModules(Arrays.asList(vfModule1, vfModule2));
+
+        return Arrays.asList(vnf1);
     }
+
 }
diff --git a/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/cds/ConfigureInstanceParamsForVnfTest.java b/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/client/cds/ConfigureInstanceParamsForVnfTest.java
new file mode 100644 (file)
index 0000000..547129e
--- /dev/null
@@ -0,0 +1,114 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2021 Bell Canada
+ * ================================================================================
+ * 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.client.cds;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.when;
+import com.google.gson.JsonObject;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.so.serviceinstancebeans.ModelInfo;
+import org.onap.so.serviceinstancebeans.Resources;
+import org.onap.so.serviceinstancebeans.Service;
+import org.onap.so.serviceinstancebeans.Vnfs;
+
+@RunWith(MockitoJUnitRunner.class)
+public class ConfigureInstanceParamsForVnfTest {
+
+    @InjectMocks
+    private ConfigureInstanceParamsForVnf configureInstanceParamsForVnf;
+
+    @Mock
+    private ExtractServiceFromUserParameters extractServiceFromUserParameters;
+
+    private static final String VNF_1_CUSTOMIZATION_ID = UUID.randomUUID().toString();
+    private static final String VNF_2_CUSTOMIZATION_ID = UUID.randomUUID().toString();
+    private static final String VNF_1_INSTANCE_NAME = "vnf-instance-1";
+    private static final String VNF_2_INSTANCE_NAME = "vnf-instance-2";
+    private static final List<Map<String, String>> VNF_1_INSTANCE_PARAMS =
+            Arrays.asList(Map.of("param-1", "xyz", "param-2", "123"), Map.of("param-3", "CCC"));
+    private static final List<Map<String, String>> VNF_2_INSTANCE_PARAMS =
+            Arrays.asList(Map.of("param-1", "abc", "param-2", "999"), Map.of("param-3", "AAA"));
+
+
+    @Test
+    public void testPopulateInstanceParamsByInstanceName() throws Exception {
+        Service service = new Service();
+        Resources resources = new Resources();
+        resources.setVnfs(createVnfs());
+        service.setResources(resources);
+        when(extractServiceFromUserParameters.getServiceFromRequestUserParams(any())).thenReturn(service);
+        JsonObject jsonObject = new JsonObject();
+
+        configureInstanceParamsForVnf.populateInstanceParams(jsonObject, new ArrayList<>(), VNF_2_CUSTOMIZATION_ID,
+                VNF_2_INSTANCE_NAME);
+
+        assertEquals("abc", jsonObject.get("param-1").getAsString());
+        assertEquals("999", jsonObject.get("param-2").getAsString());
+        assertEquals("AAA", jsonObject.get("param-3").getAsString());
+    }
+
+    @Test
+    public void testPopulateInstanceParamsByCustomizationId() throws Exception {
+        Service service = new Service();
+        Resources resources = new Resources();
+        resources.setVnfs(createVnfs());
+        service.setResources(resources);
+        when(extractServiceFromUserParameters.getServiceFromRequestUserParams(any())).thenReturn(service);
+        JsonObject jsonObject = new JsonObject();
+
+        // No instance name is passed
+        configureInstanceParamsForVnf.populateInstanceParams(jsonObject, new ArrayList<>(), VNF_1_CUSTOMIZATION_ID,
+                null);
+
+        assertEquals("xyz", jsonObject.get("param-1").getAsString());
+        assertEquals("123", jsonObject.get("param-2").getAsString());
+        assertEquals("CCC", jsonObject.get("param-3").getAsString());
+    }
+
+    private List<Vnfs> createVnfs() {
+        Vnfs vnf1 = new Vnfs();
+        vnf1.setInstanceName(VNF_1_INSTANCE_NAME);
+        ModelInfo modelInfo = new ModelInfo();
+        modelInfo.setModelCustomizationId(VNF_1_CUSTOMIZATION_ID);
+        vnf1.setModelInfo(modelInfo);
+        vnf1.setInstanceParams(VNF_1_INSTANCE_PARAMS);
+
+        Vnfs vnf2 = new Vnfs();
+        modelInfo = new ModelInfo();
+        modelInfo.setModelCustomizationId(VNF_2_CUSTOMIZATION_ID);
+        vnf2.setModelInfo(modelInfo);
+        vnf2.setInstanceName(VNF_2_INSTANCE_NAME);
+        vnf2.setInstanceParams(VNF_2_INSTANCE_PARAMS);
+
+        return Arrays.asList(vnf1, vnf2);
+    }
+
+}
index f224ebf..f5045b1 100644 (file)
@@ -22,18 +22,28 @@ package org.onap.so.client.cds;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.gson.JsonObject;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.UUID;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.InjectMocks;
 import org.mockito.Mock;
 import org.mockito.Spy;
+import org.mockito.junit.MockitoJUnitRunner;
 import org.onap.so.bpmn.servicedecomposition.bbobjects.ServiceInstance;
 import org.onap.so.bpmn.servicedecomposition.entities.ResourceKey;
-import org.onap.so.client.exception.PayloadGenerationException;
+import org.onap.so.serviceinstancebeans.ModelInfo;
+import org.onap.so.serviceinstancebeans.Resources;
 import org.onap.so.serviceinstancebeans.Service;
+import org.onap.so.serviceinstancebeans.VfModules;
+import org.onap.so.serviceinstancebeans.Vnfs;
 import org.springframework.beans.factory.annotation.Autowired;
 import java.util.List;
 import java.util.Map;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.*;
@@ -68,7 +78,7 @@ public class VfModuleCDSRequestProviderTest extends AbstractVnfCDSRequestProvide
                 ResourceKey.VF_MODULE_ID);
         doReturn(getUserParams()).when(extractServiceFromUserParameters).getServiceFromRequestUserParams(anyList());
         doCallRealMethod().when(configureInstanceParamsForVfModule).populateInstanceParams(any(), any(), anyString(),
-                anyString());
+                anyString(), any());
 
         // when
         vfModuleCDSRequestProvider.setExecutionObject(buildingBlockExecution);
@@ -105,7 +115,7 @@ public class VfModuleCDSRequestProviderTest extends AbstractVnfCDSRequestProvide
                 ResourceKey.VF_MODULE_ID);
         doReturn(getUserParams()).when(extractServiceFromUserParameters).getServiceFromRequestUserParams(anyList());
         doCallRealMethod().when(configureInstanceParamsForVfModule).populateInstanceParams(any(), any(), anyString(),
-                anyString());
+                anyString(), any());
 
         vfModuleCDSRequestProvider.setExecutionObject(buildingBlockExecution);
         String payload = vfModuleCDSRequestProvider.buildRequestPayload(DEPLOY_ACTION).get();
index 7aafd90..e801c2a 100644 (file)
@@ -50,8 +50,6 @@ public class VnfCDSRequestProviderTest extends AbstractVnfCDSRequestProviderTest
                 ResourceKey.SERVICE_INSTANCE_ID);
         doReturn(createGenericVnf()).when(extractPojosForBB).extractByKey(buildingBlockExecution,
                 ResourceKey.GENERIC_VNF_ID);
-        doNothing().when(configureInstanceParamsForVnf).populateInstanceParams(any(), any(), anyString());
-
         // when
         vnfCDSRequestProvider.setExecutionObject(buildingBlockExecution);
         String payload = vnfCDSRequestProvider.buildRequestPayload(ASSIGN_ACTION).get();
@@ -81,7 +79,6 @@ public class VnfCDSRequestProviderTest extends AbstractVnfCDSRequestProviderTest
                 ResourceKey.SERVICE_INSTANCE_ID);
         doReturn(createGenericVnf()).when(extractPojosForBB).extractByKey(buildingBlockExecution,
                 ResourceKey.GENERIC_VNF_ID);
-        doNothing().when(configureInstanceParamsForVnf).populateInstanceParams(any(), any(), any());
 
         // when
         vnfCDSRequestProvider.setExecutionObject(buildingBlockExecution);
index 0d2844d..99cff93 100644 (file)
@@ -23,7 +23,6 @@
 package org.onap.so.bpmn.infrastructure.workflow.tasks;
 
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Comparator;
 import java.util.List;
 
@@ -37,6 +36,7 @@ public class Resource {
     private String vnfCustomizationId;
     private String vfModuleCustomizationId;
     private String cvnfModuleCustomizationId;
+    private String instanceName;
     private int processingPriority;
     private Resource parent;
     private List<Resource> children;
@@ -121,6 +121,14 @@ public class Resource {
         this.cvnfModuleCustomizationId = cvnfModuleCustomizationId;
     }
 
+    public String getInstanceName() {
+        return instanceName;
+    }
+
+    public void setInstanceName(String instanceName) {
+        this.instanceName = instanceName;
+    }
+
     public int getProcessingPriority() {
         return processingPriority == 0 ? (isBaseVfModule() ? Integer.MIN_VALUE + 1 : 0) : processingPriority;
     }
index ce775af..e49aed8 100644 (file)
@@ -43,14 +43,18 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 import java.util.UUID;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 import org.apache.commons.lang3.SerializationUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.camunda.bpm.engine.delegate.DelegateExecution;
 import org.javatuples.Pair;
 import org.onap.aai.domain.yang.Vnfc;
@@ -666,11 +670,12 @@ public class WorkflowAction {
         for (Pair<WorkflowType, String> pair : aaiResourceIds) {
             logger.debug("{}, {}", pair.getValue0(), pair.getValue1());
         }
-
+        Map<Resource, String> resourceInstanceIds = new HashMap<>();
         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
-                        .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
-                                retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId)));
+                        .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource,
+                                retrieveAAIResourceId(aaiResourceIds, type), null, serviceInstanceId,
+                                resourceInstanceIds)));
     }
 
     private String retrieveAAIResourceId(List<Pair<WorkflowType, String>> aaiResourceIds, WorkflowType resource) {
@@ -687,27 +692,45 @@ public class WorkflowAction {
 
     private void generateResourceIds(List<ExecuteBuildingBlock> flowsToExecute, List<Resource> resourceList,
             String serviceInstanceId) {
+        Map<Resource, String> resourceInstanceIds = new HashMap<>();
         Arrays.stream(WorkflowType.values()).filter(type -> !type.equals(WorkflowType.SERVICE))
                 .forEach(type -> resourceList.stream().filter(resource -> type.equals(resource.getResourceType()))
-                        .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource.getResourceId(),
-                                null, resource.getVirtualLinkKey(), serviceInstanceId)));
+                        .forEach(resource -> updateWorkflowResourceIds(flowsToExecute, type, resource, null,
+                                resource.getVirtualLinkKey(), serviceInstanceId, resourceInstanceIds)));
     }
 
     protected void updateWorkflowResourceIds(List<ExecuteBuildingBlock> flowsToExecute, WorkflowType resourceType,
-            String key, String id, String virtualLinkKey, String serviceInstanceId) {
+            Resource resource, String id, String virtualLinkKey, String serviceInstanceId,
+            Map<Resource, String> resourceInstanceIds) {
+        String key = resource.getResourceId();
         String resourceId = id;
         if (resourceId == null) {
             resourceId = UUID.randomUUID().toString();
         }
+        resourceInstanceIds.put(resource, resourceId);
+        Set<String> assignedFlows = new LinkedHashSet<>();
         for (ExecuteBuildingBlock ebb : flowsToExecute) {
-            if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey()) && (ebb.getBuildingBlock()
-                    .getBpmnFlowName().contains(resourceType.toString())
-                    || (ebb.getBuildingBlock().getBpmnFlowName().contains(CONTROLLER)
-                            && ebb.getBuildingBlock().getBpmnScope().equalsIgnoreCase(resourceType.toString())))) {
+            String resourceTypeStr = resourceType.toString();
+            String flowName = ebb.getBuildingBlock().getBpmnFlowName();
+            String scope = StringUtils.defaultString(ebb.getBuildingBlock().getBpmnScope());
+            String action = StringUtils.defaultString(ebb.getBuildingBlock().getBpmnAction());
+
+            if (key != null && key.equalsIgnoreCase(ebb.getBuildingBlock().getKey())
+                    && isFlowAssignable(assignedFlows, ebb, resourceType, flowName + action)
+                    && (flowName.contains(resourceTypeStr)
+                            || (flowName.contains(CONTROLLER) && resourceTypeStr.equalsIgnoreCase(scope)))) {
                 WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
                 workflowResourceIds.setServiceInstanceId(serviceInstanceId);
+                Resource parent = resource.getParent();
+                if (parent != null && resourceInstanceIds.containsKey(parent)) {
+                    WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, parent.getResourceType(),
+                            resourceInstanceIds.get(parent));
+                }
+                WorkflowResourceIdsUtils.setInstanceNameByWorkflowType(workflowResourceIds, resourceType,
+                        resource.getInstanceName());
                 WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, resourceType, resourceId);
                 ebb.setWorkflowResourceIds(workflowResourceIds);
+                assignedFlows.add(flowName + action);
             }
             if (virtualLinkKey != null && ebb.getBuildingBlock().isVirtualLink()
                     && virtualLinkKey.equalsIgnoreCase(ebb.getBuildingBlock().getVirtualLinkKey())) {
@@ -719,6 +742,12 @@ public class WorkflowAction {
         }
     }
 
+    private boolean isFlowAssignable(Set<String> assignedFlows, ExecuteBuildingBlock ebb, WorkflowType resourceType,
+            String assignedFlowName) {
+        String id = WorkflowResourceIdsUtils.getResourceIdByWorkflowType(ebb.getWorkflowResourceIds(), resourceType);
+        return !assignedFlows.contains(assignedFlowName) && id.isEmpty();
+    }
+
     protected WorkflowResourceIds populateResourceIdsFromApiHandler(DelegateExecution execution) {
         return WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
     }
index 1f93274..c383b4a 100644 (file)
@@ -114,6 +114,7 @@ public class UserParamsServiceTraversal {
             Resource vnfResource = new Resource(WorkflowType.VNF, vnf.getModelInfo().getModelCustomizationId(), false,
                     serviceResource);
             vnfResource.setProcessingPriority(vnf.getProcessingPriority());
+            vnfResource.setInstanceName(vnf.getInstanceName());
             resourceList.add(vnfResource);
             setResourceListForVfModules(execution, resourceList, vnfResource, validate, vnf);
         }
@@ -170,6 +171,7 @@ public class UserParamsServiceTraversal {
         resource.setProcessingPriority(vfModule.getProcessingPriority());
         resource.setBaseVfModule(vfModuleCustomization.getVfModule().getIsBase() != null
                 && vfModuleCustomization.getVfModule().getIsBase());
+        resource.setInstanceName(vfModule.getInstanceName());
         resourceList.add(resource);
         return resource;
     }
index d16eac1..9cabf66 100644 (file)
@@ -20,6 +20,7 @@
 
 package org.onap.so.bpmn.infrastructure.workflow.tasks.utils;
 
+import org.apache.commons.lang3.StringUtils;
 import org.camunda.bpm.engine.delegate.DelegateExecution;
 import org.onap.so.bpmn.infrastructure.workflow.tasks.WorkflowType;
 import org.onap.so.bpmn.servicedecomposition.entities.WorkflowResourceIds;
@@ -63,6 +64,42 @@ public final class WorkflowResourceIdsUtils {
         }
     }
 
+    public static void setInstanceNameByWorkflowType(WorkflowResourceIds workflowResourceIds, WorkflowType resourceType,
+            String instanceName) {
+        if (resourceType == WorkflowType.VNF) {
+            workflowResourceIds.setVnfInstanceName(instanceName);
+        } else if (resourceType == WorkflowType.VFMODULE) {
+            workflowResourceIds.setVfModuleInstanceName(instanceName);
+        }
+    }
+
+    public static String getResourceIdByWorkflowType(WorkflowResourceIds workflowResourceIds,
+            WorkflowType resourceType) {
+        switch (resourceType) {
+            case SERVICE:
+                return StringUtils.defaultString(workflowResourceIds.getServiceInstanceId());
+            case VNF:
+                return StringUtils.defaultString(workflowResourceIds.getVnfId());
+            case PNF:
+                return StringUtils.defaultString(workflowResourceIds.getPnfId());
+            case VFMODULE:
+                return StringUtils.defaultString(workflowResourceIds.getVfModuleId());
+            case VOLUMEGROUP:
+                return StringUtils.defaultString(workflowResourceIds.getVolumeGroupId());
+            case NETWORK:
+                return StringUtils.defaultString(workflowResourceIds.getNetworkId());
+            case NETWORKCOLLECTION:
+                return StringUtils.defaultString(workflowResourceIds.getNetworkCollectionId());
+            case CONFIGURATION:
+                return StringUtils.defaultString(workflowResourceIds.getConfigurationId());
+            case INSTANCE_GROUP:
+                return StringUtils.defaultString(workflowResourceIds.getInstanceGroupId());
+            default:
+                return "";
+        }
+    }
+
+
     public static WorkflowResourceIds getWorkflowResourceIdsFromExecution(DelegateExecution execution) {
         WorkflowResourceIds workflowResourceIds = new WorkflowResourceIds();
         workflowResourceIds.setServiceInstanceId((String) execution.getVariable("serviceInstanceId"));
@@ -71,6 +108,8 @@ public final class WorkflowResourceIdsUtils {
         workflowResourceIds.setVnfId((String) execution.getVariable("vnfId"));
         workflowResourceIds.setVolumeGroupId((String) execution.getVariable("volumeGroupId"));
         workflowResourceIds.setInstanceGroupId((String) execution.getVariable("instanceGroupId"));
+        workflowResourceIds.setVnfInstanceName((String) execution.getVariable("vnfInstanceName"));
+        workflowResourceIds.setVfModuleInstanceName((String) execution.getVariable("vfModuleInstanceName"));
         return workflowResourceIds;
     }
 
index e52d2df..021bac3 100644 (file)
@@ -51,8 +51,11 @@ import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
+import java.util.Set;
 import java.util.UUID;
+import java.util.stream.Collectors;
 import org.camunda.bpm.engine.delegate.BpmnError;
 import org.camunda.bpm.engine.delegate.DelegateExecution;
 import org.camunda.bpm.extension.mockito.delegate.DelegateExecutionFake;
@@ -118,6 +121,8 @@ public class WorkflowActionTest extends BaseTaskTest {
     private static final String MACRO_CREATE_NETWORK_COLLECTION_JSON = "Macro/CreateNetworkCollection.json";
     private static final String MACRO_VNF_MACRO_REPLACE_JSON = "Macro/VnfMacroReplace.json";
     private static final String MACRO_CREATE_JSON = "Macro/ServiceMacroAssignVnfAndPnf.json";
+    private static final String MACRO_CREATE_SERVICE_MULTIPLE_SAME_MODEL_VNF_VFMODULE =
+            "Macro/ServiceMacroCreateMultipleSameModelVnfsAndVfModules.json";
 
     @Mock
     protected Environment environment;
@@ -751,6 +756,139 @@ public class WorkflowActionTest extends BaseTaskTest {
         assertEquals(true, execution.getVariable("homing"));
     }
 
+    @Test
+    public void selectExecutionListServiceMacroCreateWithMultipleSameModelVnfAndVfModules() throws Exception {
+        String gAction = "createInstance";
+        String resource = "Service";
+        String bpmnRequest = readBpmnRequestFromFile(MACRO_CREATE_SERVICE_MULTIPLE_SAME_MODEL_VNF_VFMODULE);
+        initExecution(gAction, bpmnRequest, false);
+        execution.setVariable("requestUri", "v7/serviceInstances");
+        execution.setVariable("serviceInstanceId", UUID.randomUUID().toString());
+
+        // Service-Macro-Create
+        NorthBoundRequest northBoundRequest = new NorthBoundRequest();
+        List<OrchestrationFlow> orchFlows = createFlowList("AssignServiceInstanceBB", "CreateNetworkCollectionBB",
+                "AssignNetworkBB", "AssignVnfBB", "AssignVolumeGroupBB", "AssignVfModuleBB", "ControllerExecutionBB",
+                "AssignPnfBB", "WaitForPnfReadyBB", "ControllerExecutionBB", "ControllerExecutionBB", "ActivatePnfBB",
+                "CreateNetworkBB", "ActivateNetworkBB", "CreateVolumeGroupBB", "ActivateVolumeGroupBB",
+                "CreateVfModuleBB", "ActivateVfModuleBB", "ControllerExecutionBB", "ActivateVnfBB",
+                "ActivateNetworkCollectionBB", "ActivateServiceInstanceBB");
+        orchFlows.get(6).setBpmnAction("config-assign");
+        orchFlows.get(6).setBpmnScope("vnf");
+        orchFlows.get(9).setBpmnAction("config-assign");
+        orchFlows.get(9).setBpmnScope("pnf");
+        orchFlows.get(10).setBpmnAction("config-deploy");
+        orchFlows.get(10).setBpmnScope("pnf");
+        orchFlows.get(18).setBpmnAction("config-deploy");
+        orchFlows.get(18).setBpmnScope("vnf");
+        northBoundRequest.setOrchestrationFlowList(orchFlows);
+
+        Service service = new Service();
+        service.setModelUUID("f2444885-3c76-4ddc-8668-7741c0631495");
+
+        VfModuleCustomization vfModuleCustomization = new VfModuleCustomization();
+        vfModuleCustomization.setModelCustomizationUUID("3bd19000-6d21-49f1-9eb3-ea76a6eac5e0");
+        vfModuleCustomization.setVolumeHeatEnv(new HeatEnvironment());
+        org.onap.so.db.catalog.beans.VfModule vfModule = new org.onap.so.db.catalog.beans.VfModule();
+        vfModule.setVolumeHeatTemplate(new HeatTemplate());
+        vfModuleCustomization.setVfModule(vfModule);
+
+        VfModuleCustomization vfModuleCustomization2 = new VfModuleCustomization();
+        vfModuleCustomization2.setModelCustomizationUUID("83677d89-428a-407b-b4ec-738e68275d84");
+        vfModuleCustomization2.setHeatEnvironment(new HeatEnvironment());
+        org.onap.so.db.catalog.beans.VfModule vfModule2 = new org.onap.so.db.catalog.beans.VfModule();
+        vfModule2.setModuleHeatTemplate(new HeatTemplate());
+        vfModuleCustomization2.setVfModule(vfModule2);
+
+        when(catalogDbClient.getNorthBoundRequestByActionAndIsALaCarteAndRequestScopeAndCloudOwner(gAction, resource,
+                false, "DEFAULT")).thenReturn(northBoundRequest);
+        when(catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID("3bd19000-6d21-49f1-9eb3-ea76a6eac5e0"))
+                .thenReturn(vfModuleCustomization);
+        when(catalogDbClient.getVfModuleCustomizationByModelCuztomizationUUID("83677d89-428a-407b-b4ec-738e68275d84"))
+                .thenReturn(vfModuleCustomization2);
+        when(catalogDbClient.getServiceByID("f2444885-3c76-4ddc-8668-7741c0631495")).thenReturn(service);
+
+
+        Resource serviceResource =
+                new Resource(WorkflowType.SERVICE, "f2444885-3c76-4ddc-8668-7741c0631495", false, null);
+        Resource vnfResource1 =
+                new Resource(WorkflowType.VNF, "0d0ba1ee-6b7f-47fe-8266-2967993b2c08", false, serviceResource);
+        vnfResource1.setInstanceName("vnf-instanceName-1");
+        Resource vfmResource1 =
+                new Resource(WorkflowType.VFMODULE, "3bd19000-6d21-49f1-9eb3-ea76a6eac5e0", false, vnfResource1);
+        vfmResource1.setInstanceName("demo-network-1");
+        Resource vfmResource2 =
+                new Resource(WorkflowType.VFMODULE, "83677d89-428a-407b-b4ec-738e68275d84", false, vnfResource1);
+        vfmResource2.setInstanceName("demo-1");
+        Resource vnfResource2 =
+                new Resource(WorkflowType.VNF, "0d0ba1ee-6b7f-47fe-8266-2967993b2c08", false, serviceResource);
+        vnfResource2.setInstanceName("vnf-instanceName-2");
+        Resource vfmResource3 =
+                new Resource(WorkflowType.VFMODULE, "83677d89-428a-407b-b4ec-738e68275d84", false, vnfResource2);
+        vfmResource3.setInstanceName("demo-2");
+        Resource vfmResource4 =
+                new Resource(WorkflowType.VFMODULE, "83677d89-428a-407b-b4ec-738e68275d84", false, vnfResource2);
+        vfmResource4.setInstanceName("demo-3");
+
+        when(userParamsServiceTraversal.getResourceListFromUserParams(any(), anyList(), anyString(), any()))
+                .thenReturn(Arrays.asList(serviceResource, vnfResource1, vnfResource2, vfmResource1, vfmResource2,
+                        vfmResource3, vfmResource4));
+
+        workflowAction.selectExecutionList(execution);
+
+        List<ExecuteBuildingBlock> ebbs = (List<ExecuteBuildingBlock>) execution.getVariable("flowsToExecute");
+
+        Map<String, List<ExecuteBuildingBlock>> flowNamesToEbbList =
+                ebbs.stream().collect(Collectors.groupingBy(e -> e.getBuildingBlock().getBpmnFlowName()));
+
+        assertEquals(1, flowNamesToEbbList.get("AssignServiceInstanceBB").size());
+        assertEquals(2, flowNamesToEbbList.get("AssignVnfBB").size());
+        assertEquals(4, flowNamesToEbbList.get("AssignVfModuleBB").size());
+        assertEquals(4, flowNamesToEbbList.get("ControllerExecutionBB").size());
+        assertEquals(4, flowNamesToEbbList.get("CreateVfModuleBB").size());
+        assertEquals(4, flowNamesToEbbList.get("ActivateVfModuleBB").size());
+        assertEquals(2, flowNamesToEbbList.get("ActivateVnfBB").size());
+        assertEquals(1, flowNamesToEbbList.get("ActivateServiceInstanceBB").size());
+
+        String vnfInstanceId1 = flowNamesToEbbList.get("AssignVnfBB").get(0).getWorkflowResourceIds().getVnfId();
+        String vnfInstanceId2 = flowNamesToEbbList.get("AssignVnfBB").get(1).getWorkflowResourceIds().getVnfId();
+
+        // should be 3 = 1 AssignVfModuleBB + 1 CreateVfModuleBB + 1 ActivateVfModuleBB
+        boolean allEbbsForVfModule1HaveCorrectParentVnfId =
+                3 == ebbs.stream().map(ExecuteBuildingBlock::getWorkflowResourceIds)
+                        .filter(w -> "demo-network-1".equals(w.getVfModuleInstanceName())
+                                && vnfInstanceId1.equals(w.getVnfId()))
+                        .count();
+        boolean allEbbsForVfModule2HaveCorrectParentVnfId = 3 == ebbs.stream()
+                .map(ExecuteBuildingBlock::getWorkflowResourceIds)
+                .filter(w -> "demo-1".equals(w.getVfModuleInstanceName()) && vnfInstanceId1.equals(w.getVnfId()))
+                .count();
+        boolean allEbbsForVfModule3HaveCorrectParentVnfId = 3 == ebbs.stream()
+                .map(ExecuteBuildingBlock::getWorkflowResourceIds)
+                .filter(w -> "demo-2".equals(w.getVfModuleInstanceName()) && vnfInstanceId2.equals(w.getVnfId()))
+                .count();
+        boolean allEbbsForVfModule4HaveCorrectParentVnfId = 3 == ebbs.stream()
+                .map(ExecuteBuildingBlock::getWorkflowResourceIds)
+                .filter(w -> "demo-3".equals(w.getVfModuleInstanceName()) && vnfInstanceId2.equals(w.getVnfId()))
+                .count();
+        assertTrue(allEbbsForVfModule1HaveCorrectParentVnfId);
+        assertTrue(allEbbsForVfModule2HaveCorrectParentVnfId);
+        assertTrue(allEbbsForVfModule3HaveCorrectParentVnfId);
+        assertTrue(allEbbsForVfModule4HaveCorrectParentVnfId);
+
+        boolean controllerExecutionBBsforVnf1HaveCorrectVnfId = flowNamesToEbbList.get("ControllerExecutionBB").stream()
+                .filter(e -> vnfInstanceId1.equals(e.getWorkflowResourceIds().getVnfId()))
+                .map(ExecuteBuildingBlock::getBuildingBlock).map(BuildingBlock::getBpmnAction)
+                .collect(Collectors.toSet()).containsAll(Set.of("config-assign", "config-deploy"));
+        assertTrue(controllerExecutionBBsforVnf1HaveCorrectVnfId);
+
+        boolean controllerExecutionBBsforVnf2HaveCorrectVnfId = flowNamesToEbbList.get("ControllerExecutionBB").stream()
+                .filter(e -> vnfInstanceId2.equals(e.getWorkflowResourceIds().getVnfId()))
+                .map(ExecuteBuildingBlock::getBuildingBlock).map(BuildingBlock::getBpmnAction)
+                .collect(Collectors.toSet()).containsAll(Set.of("config-assign", "config-deploy"));
+        assertTrue(controllerExecutionBBsforVnf2HaveCorrectVnfId);
+    }
+
     @Test
     public void selectExecutionListServiceMacroDeleteTest() throws Exception {
         String gAction = "deleteInstance";
index 58fee86..cac7f87 100644 (file)
@@ -53,6 +53,7 @@ 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.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.mock;
 
@@ -63,6 +64,8 @@ public class UserParamsServiceTraversalTest extends BaseTaskTest {
     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 MACRO_CREATE_WITHOUT_RESOURCES_JSON = "Macro/ServiceMacroCreateWithoutResources.json";
+    private static final String MACRO_CREATE_SVC_SAME_MODEL_VNF_VFMODULE =
+            "Macro/ServiceMacroCreateMultipleSameModelVnfsAndVfModules.json";
     private static final String serviceInstanceId = "123";
     private DelegateExecution execution;
     private CatalogDbClient mockCatalogDbClient;
@@ -80,8 +83,6 @@ public class UserParamsServiceTraversalTest extends BaseTaskTest {
     @Test
     public void getResourceListFromUserParams() throws Exception {
         initExecution(requestAction, readBpmnRequestFromFile(MACRO_CREATE_WITHOUT_RESOURCES_JSON), false);
-        Mockito.doReturn(getVfModuleCustomization()).when(mockCatalogDbClient)
-                .getVfModuleCustomizationByModelCuztomizationUUID("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f");
         Mockito.doReturn(getCvnfcCustomizations()).when(mockCatalogDbClient).getCvnfcCustomization(anyString(),
                 anyString(), anyString());
 
@@ -95,10 +96,63 @@ public class UserParamsServiceTraversalTest extends BaseTaskTest {
         assertThat(expected, is(result));
     }
 
+    @Test
+    public void getResourceListFromUserParamsMultipleSameModelVnfVfModule() throws Exception {
+        initExecution("createInstance", readBpmnRequestFromFile(MACRO_CREATE_SVC_SAME_MODEL_VNF_VFMODULE), false);
+        Mockito.doReturn(getVfModuleCustomization("3bd19000-6d21-49f1-9eb3-ea76a6eac5e0", false))
+                .when(mockCatalogDbClient)
+                .getVfModuleCustomizationByModelCuztomizationUUID("3bd19000-6d21-49f1-9eb3-ea76a6eac5e0");
+        Mockito.doReturn(getVfModuleCustomization("83677d89-428a-407b-b4ec-738e68275d84", false))
+                .when(mockCatalogDbClient)
+                .getVfModuleCustomizationByModelCuztomizationUUID("83677d89-428a-407b-b4ec-738e68275d84");
+
+        List<Resource> resources = userParamsServiceTraversal.getResourceListFromUserParams(execution, getUserParams(),
+                serviceInstanceId, requestAction);
+
+        assertEquals(7, resources.size());
+
+        Resource service = resources.get(0);
+        assertTrue(service.getResourceType() == WorkflowType.SERVICE);
+        assertEquals(2, service.getChildren().size());
+
+        Resource vnf1 = service.getChildren().get(0);
+        assertEquals(service, vnf1.getParent());
+        assertEquals("vnf-instanceName-1", vnf1.getInstanceName());
+        assertEquals("0d0ba1ee-6b7f-47fe-8266-2967993b2c08", vnf1.getResourceId());
+        assertEquals(2, vnf1.getChildren().size());
+
+        Resource vnf2 = service.getChildren().get(1);
+        assertEquals(service, vnf2.getParent());
+        assertEquals("vnf-instanceName-2", vnf2.getInstanceName());
+        assertEquals("0d0ba1ee-6b7f-47fe-8266-2967993b2c08", vnf2.getResourceId());
+        assertEquals(2, vnf2.getChildren().size());
+
+        Resource vfmodule1 = vnf1.getChildren().get(0);
+        assertEquals(vnf1, vfmodule1.getParent());
+        assertEquals("demo-network-1", vfmodule1.getInstanceName());
+        assertEquals("3bd19000-6d21-49f1-9eb3-ea76a6eac5e0", vfmodule1.getResourceId());
+
+        Resource vfmodule2 = vnf1.getChildren().get(1);
+        assertEquals(vnf1, vfmodule2.getParent());
+        assertEquals("demo-1", vfmodule2.getInstanceName());
+        assertEquals("83677d89-428a-407b-b4ec-738e68275d84", vfmodule2.getResourceId());
+
+        Resource vfmodule3 = vnf2.getChildren().get(0);
+        assertEquals(vnf2, vfmodule3.getParent());
+        assertEquals("demo-2", vfmodule3.getInstanceName());
+        assertEquals("83677d89-428a-407b-b4ec-738e68275d84", vfmodule3.getResourceId());
+
+        Resource vfmodule4 = vnf2.getChildren().get(1);
+        assertEquals(vnf2, vfmodule4.getParent());
+        assertEquals("demo-3", vfmodule4.getInstanceName());
+        assertEquals("83677d89-428a-407b-b4ec-738e68275d84", vfmodule4.getResourceId());
+    }
+
     @Test
     public void getResourceListFromUserParamsForVnfs() throws Exception {
         initExecution(requestAction, readBpmnRequestFromFile(MACRO_ASSIGN_JSON), false);
-        Mockito.doReturn(getVfModuleCustomization()).when(mockCatalogDbClient)
+        Mockito.doReturn(getVfModuleCustomization("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f", true))
+                .when(mockCatalogDbClient)
                 .getVfModuleCustomizationByModelCuztomizationUUID("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f");
         Mockito.doReturn(getCvnfcCustomizations()).when(mockCatalogDbClient).getCvnfcCustomization(anyString(),
                 anyString(), anyString());
@@ -117,7 +171,8 @@ public class UserParamsServiceTraversalTest extends BaseTaskTest {
     @Test
     public void getResourceListFromUserParamsForVnfsWithPriorities() throws Exception {
         initExecution(requestAction, readBpmnRequestFromFile(MACRO_CREATE_JSON), false);
-        Mockito.doReturn(getVfModuleCustomization()).when(mockCatalogDbClient)
+        Mockito.doReturn(getVfModuleCustomization("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f", true))
+                .when(mockCatalogDbClient)
                 .getVfModuleCustomizationByModelCuztomizationUUID("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f");
         Mockito.doReturn(getCvnfcCustomizations()).when(mockCatalogDbClient).getCvnfcCustomization(anyString(),
                 anyString(), anyString());
@@ -137,8 +192,6 @@ public class UserParamsServiceTraversalTest extends BaseTaskTest {
     @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());
 
@@ -156,8 +209,6 @@ public class UserParamsServiceTraversalTest extends BaseTaskTest {
     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());
@@ -230,13 +281,17 @@ public class UserParamsServiceTraversalTest extends BaseTaskTest {
         return service;
     }
 
-    private VfModuleCustomization getVfModuleCustomization() {
+    private VfModuleCustomization getVfModuleCustomization(String modelCustomizationUUID, boolean includeVolumeGroup) {
         VfModuleCustomization vfModuleCustomization = new VfModuleCustomization();
-        vfModuleCustomization.setVolumeHeatEnv(new HeatEnvironment());
-        vfModuleCustomization.setModelCustomizationUUID("a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f");
+        vfModuleCustomization.setModelCustomizationUUID(modelCustomizationUUID);
         VfModule vfModule = new VfModule();
-        vfModule.setVolumeHeatTemplate(new HeatTemplate());
-        vfModule.setModelName("helm");
+        if (includeVolumeGroup) {
+            vfModuleCustomization.setVolumeHeatEnv(new HeatEnvironment());
+            vfModule.setVolumeHeatTemplate(new HeatTemplate());
+            vfModule.setModelName("helm");
+        } else {
+            vfModuleCustomization.setHeatEnvironment(new HeatEnvironment());
+        }
         vfModule.setModuleHeatTemplate(new HeatTemplate());
         vfModuleCustomization.setVfModule(vfModule);
         return vfModuleCustomization;
index 0d68cf3..996c0c0 100644 (file)
@@ -40,7 +40,8 @@ public class WorkflowResourceIdsUtilsTest {
     private static final String PNF_ID = "pnfId";
     private static final String NETWORK_COLLECTION_ID = "networkCollectionId";
     private static final String CONFIGURATION_ID = "configurationId";
-
+    private static final String VNF_INSTANCE_NAME = "vnfInstanceNameId";
+    private static final String VF_MODULE_INSTANCE_NAME = "vfModuleInstanceNameId";
     private WorkflowResourceIds workflowResourceIds;
 
     @Before
@@ -57,6 +58,8 @@ public class WorkflowResourceIdsUtilsTest {
         execution.setVariable("vnfId", VNF_ID);
         execution.setVariable("volumeGroupId", VOLUME_GROUP_ID);
         execution.setVariable("instanceGroupId", INSTANCE_GROUP_ID);
+        execution.setVariable("vnfInstanceName", VNF_INSTANCE_NAME);
+        execution.setVariable("vfModuleInstanceName", VF_MODULE_INSTANCE_NAME);
 
         workflowResourceIds = WorkflowResourceIdsUtils.getWorkflowResourceIdsFromExecution(execution);
 
@@ -66,54 +69,84 @@ public class WorkflowResourceIdsUtilsTest {
         assertEquals(VNF_ID, workflowResourceIds.getVnfId());
         assertEquals(VOLUME_GROUP_ID, workflowResourceIds.getVolumeGroupId());
         assertEquals(INSTANCE_GROUP_ID, workflowResourceIds.getInstanceGroupId());
+        assertEquals(VNF_INSTANCE_NAME, workflowResourceIds.getVnfInstanceName());
+        assertEquals(VF_MODULE_INSTANCE_NAME, workflowResourceIds.getVfModuleInstanceName());
     }
 
     @Test
     public void shouldProperlySetServiceInstanceId() {
         assertFieldSetProperly(WorkflowType.SERVICE, SERVICE_ID, workflowResourceIds::getServiceInstanceId);
+        assertEquals(SERVICE_ID,
+                WorkflowResourceIdsUtils.getResourceIdByWorkflowType(workflowResourceIds, WorkflowType.SERVICE));
     }
 
     @Test
     public void shouldProperlySetVnfId() {
         assertFieldSetProperly(WorkflowType.VNF, VNF_ID, workflowResourceIds::getVnfId);
-
+        assertEquals(VNF_ID,
+                WorkflowResourceIdsUtils.getResourceIdByWorkflowType(workflowResourceIds, WorkflowType.VNF));
     }
 
     @Test
     public void shouldProperlySetPnfId() {
         assertFieldSetProperly(WorkflowType.PNF, PNF_ID, workflowResourceIds::getPnfId);
+        assertEquals(PNF_ID,
+                WorkflowResourceIdsUtils.getResourceIdByWorkflowType(workflowResourceIds, WorkflowType.PNF));
     }
 
     @Test
     public void shouldProperlySetVfModuleId() {
         assertFieldSetProperly(WorkflowType.VFMODULE, VF_MODULE_ID, workflowResourceIds::getVfModuleId);
+        assertEquals(VF_MODULE_ID,
+                WorkflowResourceIdsUtils.getResourceIdByWorkflowType(workflowResourceIds, WorkflowType.VFMODULE));
     }
 
     @Test
     public void shouldProperlySetVolumeGroupId() {
         assertFieldSetProperly(WorkflowType.VOLUMEGROUP, VOLUME_GROUP_ID, workflowResourceIds::getVolumeGroupId);
+        assertEquals(VOLUME_GROUP_ID,
+                WorkflowResourceIdsUtils.getResourceIdByWorkflowType(workflowResourceIds, WorkflowType.VOLUMEGROUP));
     }
 
     @Test
     public void shouldProperlySetNetworkId() {
         assertFieldSetProperly(WorkflowType.NETWORK, NETWORK_ID, workflowResourceIds::getNetworkId);
+        assertEquals(NETWORK_ID,
+                WorkflowResourceIdsUtils.getResourceIdByWorkflowType(workflowResourceIds, WorkflowType.NETWORK));
     }
 
     @Test
     public void shouldProperlySetNetworkCollectionId() {
         assertFieldSetProperly(WorkflowType.NETWORKCOLLECTION, NETWORK_COLLECTION_ID,
                 workflowResourceIds::getNetworkCollectionId);
-
+        assertEquals(NETWORK_COLLECTION_ID, WorkflowResourceIdsUtils.getResourceIdByWorkflowType(workflowResourceIds,
+                WorkflowType.NETWORKCOLLECTION));
     }
 
     @Test
     public void shouldProperlySetConfigurationId() {
         assertFieldSetProperly(WorkflowType.CONFIGURATION, CONFIGURATION_ID, workflowResourceIds::getConfigurationId);
+        assertEquals(CONFIGURATION_ID,
+                WorkflowResourceIdsUtils.getResourceIdByWorkflowType(workflowResourceIds, WorkflowType.CONFIGURATION));
     }
 
     @Test
     public void shouldProperlySetInstanceGroupId() {
         assertFieldSetProperly(WorkflowType.INSTANCE_GROUP, INSTANCE_GROUP_ID, workflowResourceIds::getInstanceGroupId);
+        assertEquals(INSTANCE_GROUP_ID,
+                WorkflowResourceIdsUtils.getResourceIdByWorkflowType(workflowResourceIds, WorkflowType.INSTANCE_GROUP));
+    }
+
+    @Test
+    public void shouldPropertySetVnfInstanceName() {
+        assertFieldSetProperlyInstanceName(WorkflowType.VNF, VNF_INSTANCE_NAME,
+                workflowResourceIds::getVnfInstanceName);
+    }
+
+    @Test
+    public void shouldPropertySetVfModuleInstanceName() {
+        assertFieldSetProperlyInstanceName(WorkflowType.VFMODULE, VF_MODULE_INSTANCE_NAME,
+                workflowResourceIds::getVfModuleInstanceName);
     }
 
     private void assertFieldSetProperly(WorkflowType workflowType, String expectedId,
@@ -121,4 +154,13 @@ public class WorkflowResourceIdsUtilsTest {
         WorkflowResourceIdsUtils.setResourceIdByWorkflowType(workflowResourceIds, workflowType, expectedId);
         assertEquals(expectedId, testedObjectField.get());
     }
+
+    private void assertFieldSetProperlyInstanceName(WorkflowType workflowType, String expectedId,
+            Supplier<String> testedObjectField) {
+        WorkflowResourceIdsUtils.setInstanceNameByWorkflowType(workflowResourceIds, workflowType, expectedId);
+        assertEquals(expectedId, testedObjectField.get());
+    }
+
+
+
 }
diff --git a/bpmn/so-bpmn-tasks/src/test/resources/__files/Macro/ServiceMacroCreateMultipleSameModelVnfsAndVfModules.json b/bpmn/so-bpmn-tasks/src/test/resources/__files/Macro/ServiceMacroCreateMultipleSameModelVnfsAndVfModules.json
new file mode 100644 (file)
index 0000000..0597548
--- /dev/null
@@ -0,0 +1,187 @@
+{
+  "requestDetails": {
+    "subscriberInfo": {
+      "globalSubscriberId": "test-customer"
+    },
+    "requestInfo": {
+      "suppressRollback": false,
+      "instanceName": "test",
+      "productFamilyId": "6ea37d21-1a8d-4cd5-a727-e543191a5bb6",
+      "requestorId": "portal",
+      "source": "source"
+    },
+    "cloudConfiguration": {
+      "lcpCloudRegionId": "cloudid",
+      "tenantId": "tenantid",
+      "cloudOwner": "cloudowner"
+    },
+    "requestParameters": {
+      "subscriptionServiceType": "ubuntu",
+      "userParams": [
+        {
+          "Homing_Solution": "none"
+        },
+        {
+          "service": {
+            "instanceParams": [],
+            "resources": {
+              "vnfs": [
+                {
+                  "modelInfo": {
+                    "modelName": "UbuntuVF",
+                    "modelVersionId": "744a1610-782e-47cf-bb45-d83319e33e17",
+                    "modelInvariantUuid": "fc573bb4-d312-48ab-b81d-8b3313df4d07",
+                    "modelVersion": "1.0",
+                    "modelCustomizationId": "0d0ba1ee-6b7f-47fe-8266-2967993b2c08",
+                    "modelInstanceName": "Ubuntu VF 0"
+                  },
+                  "cloudConfiguration": {
+                    "lcpCloudRegionId": "cloudid",
+                    "tenantId": "tenantid",
+                    "cloudOwner": "cloudowner"
+                  },
+                  "platform": {
+                    "platformName": "platform"
+                  },
+                  "lineOfBusiness": {
+                    "lineOfBusinessName": "lob"
+                  },
+                  "productFamilyId": "6ea37d21-1a8d-4cd5-a727-e543191a5bb6\n",
+                  "instanceName": "vnf-instanceName-1",
+                  "instanceParams": [
+                    {
+                      "vnf-name": "vnf-vnf-name",
+                      "vnf_name": "UbuntuVNFName"
+                    }
+                  ],
+                  "vfModules": [
+                    {
+                      "modelInfo": {
+                        "modelName": "UbuntuVF..base..module-0",
+                        "modelVersionId": "8fa495ac-d057-4060-b772-868d8e97766e",
+                        "modelInvariantUuid": "71dcbf41-9838-4b3d-baa4-4024d22ef0cc",
+                        "modelVersion": "1",
+                        "modelCustomizationId": "3bd19000-6d21-49f1-9eb3-ea76a6eac5e0"
+                      },
+                      "instanceName": "demo-network-1",
+                      "instanceParams": [
+                        {
+                          "name": "demo-network-1",
+                          "cidr": "10.10.10.0/24"
+                        }
+                      ]
+                    },
+                    {
+                      "modelInfo": {
+                        "modelName": "UbuntuVF..base..module-1",
+                        "modelVersionId": "21954495-830f-48b7-b7b2-030d837789b3",
+                        "modelInvariantUuid": "90355af6-55f3-460e-abe6-bec9a27a15e6",
+                        "modelVersion": "1",
+                        "modelCustomizationId": "83677d89-428a-407b-b4ec-738e68275d84"
+                      },
+                      "instanceName": "demo-1",
+                      "instanceParams": [
+                        {
+                          "name": "demo-ubuntu-1",
+                          "network_mgmt": "vlan101",
+                          "network_name": "demo-network-1"
+                        }
+                      ]
+                    }
+                  ]
+                },
+                {
+                  "modelInfo": {
+                    "modelName": "UbuntuVF",
+                    "modelVersionId": "744a1610-782e-47cf-bb45-d83319e33e17",
+                    "modelInvariantUuid": "fc573bb4-d312-48ab-b81d-8b3313df4d07",
+                    "modelVersion": "1.0",
+                    "modelCustomizationId": "0d0ba1ee-6b7f-47fe-8266-2967993b2c08",
+                    "modelInstanceName": "Ubuntu VF 0"
+                  },
+                  "cloudConfiguration": {
+                    "lcpCloudRegionId": "cloudid",
+                    "tenantId": "tenantid",
+                    "cloudOwner": "cloudowner"
+                  },
+                  "platform": {
+                    "platformName": "platform"
+                  },
+                  "lineOfBusiness": {
+                    "lineOfBusinessName": "lob"
+                  },
+                  "productFamilyId": "6ea37d21-1a8d-4cd5-a727-e543191a5bb6\n",
+                  "instanceName": "vnf-instanceName-2",
+                  "instanceParams": [
+                    {
+                      "vnf-name": "vnf-vnf-name",
+                      "vnf_name": "UbuntuVNFName"
+                    }
+                  ],
+                  "vfModules": [
+                    {
+                      "modelInfo": {
+                        "modelName": "UbuntuVF..base..module-1",
+                        "modelVersionId": "21954495-830f-48b7-b7b2-030d837789b3",
+                        "modelInvariantUuid": "90355af6-55f3-460e-abe6-bec9a27a15e6",
+                        "modelVersion": "1",
+                        "modelCustomizationId": "83677d89-428a-407b-b4ec-738e68275d84"
+                      },
+                      "instanceName": "demo-2",
+                      "instanceParams": [
+                        {
+                          "name": "demo-ubuntu-2",
+                          "network_mgmt": "vlan101",
+                          "network_name": "demo-network-1"
+                        }
+                      ]
+                    },
+                    {
+                      "modelInfo": {
+                        "modelName": "UbuntuVF..base..module-1",
+                        "modelVersionId": "21954495-830f-48b7-b7b2-030d837789b3",
+                        "modelInvariantUuid": "90355af6-55f3-460e-abe6-bec9a27a15e6",
+                        "modelVersion": "1",
+                        "modelCustomizationId": "83677d89-428a-407b-b4ec-738e68275d84"
+                      },
+                      "instanceName": "demo-3",
+                      "instanceParams": [
+                        {
+                          "name": "demo-ubuntu-3",
+                          "network_mgmt": "vlan101",
+                          "network_name": "demo-network-1"
+                        }
+                      ]
+                    }
+                  ]
+                }
+              ]
+            },
+            "modelInfo": {
+              "modelVersion": "1.0",
+              "modelVersionId": "f2444885-3c76-4ddc-8668-7741c0631495",
+              "modelInvariantId": "3bd19000-6d21-49f1-9eb3-ea76a6eac5e0",
+              "modelName": "UbuntuSVC",
+              "modelType": "service"
+            }
+          }
+        }
+      ],
+      "aLaCarte": false
+    },
+    "project": {
+      "projectName": "Project-UbuntuDemo"
+    },
+    "owningEntity": {
+      "owningEntityId": "33a8b609-1cfe-4d19-8dc2-5b95b921de1e",
+      "owningEntityName": "demo"
+    },
+    "modelInfo": {
+      "modelVersion": "1.0",
+      "modelVersionId": "f2444885-3c76-4ddc-8668-7741c0631495",
+      "modelInvariantId": "3bd19000-6d21-49f1-9eb3-ea76a6eac5e0",
+      "modelName": "UbuntuSVC",
+      "modelType": "service"
+    }
+  }
+}
\ No newline at end of file
index 067e861..8646a74 100644 (file)
 package org.onap.so.apihandlerinfra.validation;
 
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import org.apache.commons.lang3.StringUtils;
 import org.onap.so.apihandlerinfra.Action;
 import org.onap.so.apihandlerinfra.Actions;
 import org.onap.so.exceptions.ValidationException;
@@ -36,8 +42,6 @@ public class UserParamsValidation implements ValidationRule {
     @Override
     public ValidationInformation validate(ValidationInformation info) throws ValidationException {
         Service validate = info.getUserParams();
-        Actions action = info.getAction();
-
         if (validate.getModelInfo() == null) {
             throw new ValidationException("modelInfo in userParams", true);
         } else if (validate.getModelInfo().getModelType() == null) {
@@ -49,6 +53,10 @@ public class UserParamsValidation implements ValidationRule {
         if (validate.getInstanceName() != null && info.getRequestInfo().getInstanceName() != null) {
             instanceNameValidation(info, validate);
         }
+
+        Actions action = info.getAction();
+        Map<String, Set<String>> vnfCustomIdToInstanceNames = new HashMap<>();
+        Map<String, Set<String>> vfModuleCustomIdToInstanceNames = new HashMap<>();
         for (Vnfs vnf : validate.getResources().getVnfs()) {
             if (vnf.getModelInfo() == null) {
                 throw new ValidationException("modelInfo in userParams vnf resources", true);
@@ -71,19 +79,42 @@ public class UserParamsValidation implements ValidationRule {
             if (vnf.getPlatform() != null && vnf.getPlatform().getPlatformName() == null) {
                 throw new ValidationException("platformName in userParams vnf resources", true);
             }
+
+            String vnfCustomizationId = vnf.getModelInfo().getModelCustomizationId();
+            vnfCustomIdToInstanceNames.putIfAbsent(vnfCustomizationId, new HashSet<>());
+            String vnfInstanceName = StringUtils.defaultString(vnf.getInstanceName());
+            Set<String> vnfVisitedInstanceNames = vnfCustomIdToInstanceNames.get(vnfCustomizationId);
+            if (!vnfVisitedInstanceNames.add(vnfInstanceName)) {
+                throw new ValidationException(
+                        "instanceName: same instanceName with same modelCustomizationId in userParams vnf resources",
+                        true);
+            }
             if (vnf.getVfModules().isEmpty()) {
                 throw new ValidationException("vfModules in userParams vnf resources", true);
             }
-            for (VfModules vfModules : vnf.getVfModules()) {
-                if (vfModules.getModelInfo() == null) {
+
+            for (VfModules vfModule : vnf.getVfModules()) {
+                if (vfModule.getModelInfo() == null) {
                     throw new ValidationException("modelInfo in userParams vfModules resources", true);
-                } else if (vfModules.getModelInfo().getModelCustomizationId() == null) {
+                } else if (vfModule.getModelInfo().getModelCustomizationId() == null) {
                     throw new ValidationException("modelCustomizationId in userParams vfModule resources", true);
-                } else if (vfModules.getModelInfo().getModelVersionId() == null) {
+                } else if (vfModule.getModelInfo().getModelVersionId() == null) {
                     throw new ValidationException("modelVersionId in userParams vfModule resources", true);
                 }
+
+                String vfModulecustomizationId = vfModule.getModelInfo().getModelCustomizationId();
+                vfModuleCustomIdToInstanceNames.putIfAbsent(vfModulecustomizationId, new HashSet<>());
+                String vfModuleInstanceName = StringUtils.defaultString(vfModule.getInstanceName());
+                Set<String> vfModuleVisitedInstanceNames = vfModuleCustomIdToInstanceNames.get(vfModulecustomizationId);
+                if (!vfModuleVisitedInstanceNames.add(vfModuleInstanceName)) {
+                    throw new ValidationException(
+                            "instanceName: same instanceName with same modelCustomizationId in userParams vfModule resources",
+                            true);
+                }
             }
         }
+        validateDuplicateInstanceNames(vnfCustomIdToInstanceNames, "vnf");
+        validateDuplicateInstanceNames(vfModuleCustomIdToInstanceNames, "vfModule");
 
         List<Networks> validateNetworks = new ArrayList<>();
         validateNetworks = validate.getResources().getNetworks();
@@ -135,4 +166,24 @@ public class UserParamsValidation implements ValidationRule {
                     "modelCustomizationId in userParams service");
         }
     }
+
+    private void validateDuplicateInstanceNames(Map<String, Set<String>> duplicateValidator, String type)
+            throws ValidationException {
+        Set<String> allInstanceNames = new HashSet<>();
+        for (Map.Entry<String, Set<String>> entry : duplicateValidator.entrySet()) {
+            Set<String> instanceNames = entry.getValue();
+            if (instanceNames.size() > 1 && instanceNames.contains(""))
+                throw new ValidationException(String.format(
+                        "instanceName: instanceName is missing or empty with same modelCustomizationId in userParams %s resources",
+                        type), true);
+
+            for (String instanceName : instanceNames) {
+                if (!instanceName.isBlank() && !allInstanceNames.add(instanceName)) {
+                    throw new ValidationException(String.format(
+                            "instanceName: same instanceName but different modelCustomizationId (instanceName should be unique)  in userParams %s resources",
+                            type), true);
+                }
+            }
+        }
+    }
 }
index ba02254..548b957 100644 (file)
@@ -32,6 +32,7 @@ import org.onap.so.exceptions.ValidationException;
 import org.onap.so.serviceinstancebeans.Service;
 import org.onap.so.serviceinstancebeans.ServiceInstancesRequest;
 import com.fasterxml.jackson.databind.ObjectMapper;
+import org.onap.so.serviceinstancebeans.VfModules;
 
 public class UserParamsValidationTest {
 
@@ -65,6 +66,182 @@ public class UserParamsValidationTest {
                 "src/test/resources/Validation/UserParamsValidation/ModelInfoNoModelType.json"));
     }
 
+    @Test
+    public void validateDuplicateInstanceNameDifferentCustomizationIdVnfTest() throws IOException, ValidationException {
+        thrown.expect(ValidationException.class);
+        thrown.expectMessage(
+                "No valid instanceName: same instanceName but different modelCustomizationId (instanceName should be unique)  in userParams vnf resources is specified");
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        info.getUserParams().getResources().getVnfs().get(0).setInstanceName("UbuntuVNF2");
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateDuplicateInstanceNameSameCustomizationIdVnfTest() throws IOException, ValidationException {
+        thrown.expect(ValidationException.class);
+        thrown.expectMessage(
+                "No valid instanceName: same instanceName with same modelCustomizationId in userParams vnf resources is specified");
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        info.getUserParams().getResources().getVnfs().get(2).setInstanceName("UbuntuVNF2");
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateNullInstanceNameSameCustomizationIdVnfTest() throws IOException, ValidationException {
+        thrown.expect(ValidationException.class);
+        thrown.expectMessage(
+                "No valid instanceName: instanceName is missing or empty with same modelCustomizationId in userParams vnf resources is specified");
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        info.getUserParams().getResources().getVnfs().get(1).setInstanceName(null);
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateDuplicateNullInstanceNameSameCustomizationIdVnfTest() throws IOException, ValidationException {
+        thrown.expect(ValidationException.class);
+        thrown.expectMessage(
+                "No valid instanceName: same instanceName with same modelCustomizationId in userParams vnf resources is specified");
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        info.getUserParams().getResources().getVnfs().get(1).setInstanceName(null);
+        info.getUserParams().getResources().getVnfs().get(2).setInstanceName(null);
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateDifferentInstanceNameSameCustomizationIdVnfTest() throws IOException, ValidationException {
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateNullInstanceNameDifferentCustomizationIdVnfTest() throws IOException, ValidationException {
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        info.getUserParams().getResources().getVnfs().get(0).setInstanceName(null);
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateDuplicateInstanceNameDifferentCustomizationIdVfModuleInOneVnfTest()
+            throws IOException, ValidationException {
+        thrown.expect(ValidationException.class);
+        thrown.expectMessage(
+                "No valid instanceName: same instanceName but different modelCustomizationId (instanceName should be unique)  in userParams vfModule resources is specified");
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        info.getUserParams().getResources().getVnfs().get(2).getVfModules().get(2).setInstanceName("lcm-demo-ubuntu-3");
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateDuplicateInstanceNameDifferentCustomizationIdVfModuleInMultipleVnfTest()
+            throws IOException, ValidationException {
+        thrown.expect(ValidationException.class);
+        thrown.expectMessage(
+                "No valid instanceName: same instanceName but different modelCustomizationId (instanceName should be unique)  in userParams vfModule resources is specified");
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        info.getUserParams().getResources().getVnfs().get(0).getVfModules().get(0).setInstanceName("lcm-demo-ubuntu-3");
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateDuplicateInstanceNameSameCustomizationIdVfModuleInOneVnfTest()
+            throws IOException, ValidationException {
+        thrown.expect(ValidationException.class);
+        thrown.expectMessage(
+                "No valid instanceName: same instanceName with same modelCustomizationId in userParams vfModule resources is specified");
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        info.getUserParams().getResources().getVnfs().get(2).getVfModules().get(1).setInstanceName("lcm-demo-ubuntu-2");
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateDuplicateInstanceNameSameCustomizationIdVfModuleInMultipleVnfTest()
+            throws IOException, ValidationException {
+        thrown.expect(ValidationException.class);
+        thrown.expectMessage(
+                "No valid instanceName: same instanceName with same modelCustomizationId in userParams vfModule resources is specified");
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        VfModules vfModule1 = info.getUserParams().getResources().getVnfs().get(0).getVfModules().get(0);
+        VfModules vfModule2 = info.getUserParams().getResources().getVnfs().get(1).getVfModules().get(0);
+        vfModule2.setInstanceName(vfModule1.getInstanceName());
+        vfModule2.getModelInfo().setModelCustomizationId(vfModule1.getModelInfo().getModelCustomizationId());
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateNullInstanceNameSameCustomizationIdVfModuleInOneVnfTest()
+            throws IOException, ValidationException {
+        thrown.expect(ValidationException.class);
+        thrown.expectMessage(
+                "No valid instanceName: instanceName is missing or empty with same modelCustomizationId in userParams vfModule resources is specified");
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        info.getUserParams().getResources().getVnfs().get(2).getVfModules().get(1).setInstanceName(null);
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateNullInstanceNameSameCustomizationIdVfModuleInMultipleVnfTest()
+            throws IOException, ValidationException {
+        thrown.expect(ValidationException.class);
+        thrown.expectMessage(
+                "No valid instanceName: instanceName is missing or empty with same modelCustomizationId in userParams vfModule resources is specified");
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        VfModules vfModule1 = info.getUserParams().getResources().getVnfs().get(0).getVfModules().get(0);
+        VfModules vfModule2 = info.getUserParams().getResources().getVnfs().get(1).getVfModules().get(0);
+        vfModule2.setInstanceName(null);
+        vfModule2.getModelInfo().setModelCustomizationId(vfModule1.getModelInfo().getModelCustomizationId());
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateDuplicateNullInstanceNameSameCustomizationIdVfModuleInMultipleVnfTest()
+            throws IOException, ValidationException {
+        thrown.expect(ValidationException.class);
+        thrown.expectMessage(
+                "No valid instanceName: same instanceName with same modelCustomizationId in userParams vfModule resources is specified");
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        VfModules vfModule1 = info.getUserParams().getResources().getVnfs().get(0).getVfModules().get(0);
+        VfModules vfModule2 = info.getUserParams().getResources().getVnfs().get(1).getVfModules().get(0);
+        vfModule1.setInstanceName(null);
+        vfModule2.setInstanceName(null);
+        vfModule2.getModelInfo().setModelCustomizationId(vfModule1.getModelInfo().getModelCustomizationId());
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateInstanceNameSameCustomizationIdVfModuleInVnfTest() throws IOException, ValidationException {
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        VfModules vfModule1 = info.getUserParams().getResources().getVnfs().get(0).getVfModules().get(0);
+        VfModules vfModule2 = info.getUserParams().getResources().getVnfs().get(1).getVfModules().get(0);
+        vfModule2.getModelInfo().setModelCustomizationId(vfModule1.getModelInfo().getModelCustomizationId());
+        validation.validate(info);
+    }
+
+    @Test
+    public void validateNullInstanceNameDifferentCustomizationIdVfModuleInVnfTest()
+            throws IOException, ValidationException {
+        ValidationInformation info = setupValidationInformation(
+                "src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json");
+        VfModules vfModule1 = info.getUserParams().getResources().getVnfs().get(0).getVfModules().get(0);
+        vfModule1.setInstanceName(null);
+        VfModules vfModule2 = info.getUserParams().getResources().getVnfs().get(2).getVfModules().get(2);
+        vfModule2.setInstanceName(null);
+        validation.validate(info);
+    }
+
     @Test
     public void validateInstanceNameExceptionTest() throws IOException, ValidationException {
         thrown.expect(ValidationException.class);
index a7d930f..aa6448e 100644 (file)
@@ -72,7 +72,8 @@
                         "modelName": "201673MowBvL._base_BV..module-0",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f" 
-                      }, 
+                      },
+                      "instanceName": "vfModule1",
                       "instanceParams": [ 
                         { 
                           "vmx_int_net_len": "24",
@@ -86,7 +87,8 @@
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "72d9d1cd-f46d-447a-abdb-451d6fb05fa8", 
                                                "modelType": "vfModule" 
-                      }, 
+                      },
+                      "instanceName": "vfModule2",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
                         "modelName": "201673MowBvL._vRE_BV..module-1",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "72d9d1cd-f46d-447a-abdb-451d6fb05fa8" 
-                      }, 
+                      },
+                      "instanceName": "vfModule3",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
                         "modelName": "201673MowBvL._vPFE_BV..module-2",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a",
                         "modelCustomizationId": "da4d4327-fb7d-4311-ac7a-be7ba60cf969" 
-                      }, 
+                      },
+                      "instanceName": "vfModule4",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
index 75e8fb5..c93b49a 100644 (file)
@@ -72,7 +72,8 @@
                         "modelName": "201673MowBvL._base_BV..module-0", 
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a",
                         "modelCustomizationId": "a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f" 
-                      }, 
+                      },
+                      "instanceName": "vfModule1",
                       "instanceParams": [ 
                         { 
                           "vmx_int_net_len": "24",
@@ -86,7 +87,8 @@
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a",
                         "modelCustomizationId": "72d9d1cd-f46d-447a-abdb-451d6fb05fa8", 
                                                "modelType": "vfModule" 
-                      }, 
+                      },
+                      "instanceName": "vfModule2",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
                         "modelName": "201673MowBvL._vRE_BV..module-1", 
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a",
                         "modelCustomizationId": "72d9d1cd-f46d-447a-abdb-451d6fb05fa8" 
-                      }, 
+                      },
+                      "instanceName": "vfModule3",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
                         "modelName": "201673MowBvL._vPFE_BV..module-2",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "da4d4327-fb7d-4311-ac7a-be7ba60cf969" 
-                      }, 
+                      },
+                      "instanceName": "vfModule4",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
index baf620b..a81cfd0 100644 (file)
@@ -72,7 +72,8 @@
                         "modelName": "201673MowBvL._base_BV..module-0",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f" 
-                      }, 
+                      },
+                      "instanceName": "vfModule1",
                       "instanceParams": [ 
                         { 
                           "vmx_int_net_len": "24",
@@ -86,7 +87,8 @@
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "72d9d1cd-f46d-447a-abdb-451d6fb05fa8", 
                                                "modelType": "vfModule" 
-                      }, 
+                      },
+                      "instanceName": "vfModule2",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
                         "modelName": "201673MowBvL._vRE_BV..module-1",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "72d9d1cd-f46d-447a-abdb-451d6fb05fa8" 
-                      }, 
+                      },
+                      "instanceName": "vfModule3",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
                         "modelName": "201673MowBvL._vPFE_BV..module-2",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "da4d4327-fb7d-4311-ac7a-be7ba60cf969" 
-                      }, 
+                      },
+                      "instanceName": "vfModule4",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
index 6c15285..148abbc 100644 (file)
@@ -72,7 +72,8 @@
                         "modelName": "201673MowBvL._base_BV..module-0",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f" 
-                      }, 
+                      },
+                      "instanceName": "vfModule1",
                       "instanceParams": [ 
                         { 
                           "vmx_int_net_len": "24",
@@ -86,7 +87,8 @@
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "72d9d1cd-f46d-447a-abdb-451d6fb05fa8", 
                                                "modelType": "vfModule" 
-                      }, 
+                      },
+                      "instanceName": "vfModule2",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
                         "modelName": "201673MowBvL._vRE_BV..module-1",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "72d9d1cd-f46d-447a-abdb-451d6fb05fa8" 
-                      }, 
+                      },
+                      "instanceName": "vfModule3",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
                         "modelName": "201673MowBvL._vPFE_BV..module-2",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "da4d4327-fb7d-4311-ac7a-be7ba60cf969" 
-                      }, 
+                      },
+                      "instanceName": "vfModule4",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
index bc6f8fc..d8bfcc2 100644 (file)
@@ -72,7 +72,8 @@
                         "modelName": "201673MowBvL._base__BV..module-0",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f" 
-                      }, 
+                      },
+                      "instanceName": "vfModule1",
                       "instanceParams": [ 
                         { 
                           "vmx_int_net_len": "24",
@@ -86,7 +87,8 @@
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "72d9d1cd-f46d-447a-abdb-451d6fb05fa8", 
                                                "modelType": "vfModule" 
-                      }, 
+                      },
+                      "instanceName": "vfModule2",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
                         "modelName": "201673MowBvL._vRE_BV..module-1",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "72d9d1cd-f46d-447a-abdb-451d6fb05fa8" 
-                      }, 
+                      },
+                      "instanceName": "vfModule3",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
                         "modelName": "201673MowBvL._vPFE_BV..module-2",
                         "modelVersionId": "3c40d244-808e-42ca-b09a-256d83d19d0a", 
                         "modelCustomizationId": "da4d4327-fb7d-4311-ac7a-be7ba60cf969" 
-                      }, 
+                      },
+                      "instanceName": "vfModule4",
                       "instanceParams": [ 
                         { 
                           "availability_zone_0": "mtpocdv-kvm-az01", 
index fd8b7c4..1efb0c1 100644 (file)
@@ -75,6 +75,7 @@
                                     "modelVersionId":"4c75f813-fa91-45a4-89d0-790ff5f1ae79",
                                     "modelCustomizationId":"a25e8e8c-58b8-4eec-810c-97dcc1f5cb7f"
                                  },
+                                 "instanceName": "vfModule1",
                                  "instanceParams":[
                                     {
                                        "vmx_int_net_len":"24"
@@ -88,6 +89,7 @@
                                     "modelVersionId":"56e2b103-637c-4d1a-adc8-3a7f4a6c3240",
                                     "modelCustomizationId":"72d9d1cd-f46d-447a-abdb-451d6fb05fa8"
                                  },
+                                 "instanceName": "vfModule2",
                                  "instanceParams":[
                                     {
                                        "availability_zone_0":"mtpocdv-kvm-az01",
                                     "modelVersionId":"56e2b103-637c-4d1a-adc8-3a7f4a6c3240",
                                     "modelCustomizationId":"72d9d1cd-f46d-447a-abdb-451d6fb05fa8"
                                  },
+                                 "instanceName": "vfModule3",
                                  "instanceParams":[
                                     {
                                        "availability_zone_0":"mtpocdv-kvm-az01",
                                     "modelVersionId":"f555558f-d538-4876-8ffa-b102650fad64",
                                     "modelCustomizationId":"da4d4327-fb7d-4311-ac7a-be7ba60cf969"
                                  },
+                                 "instanceName": "vfModule4",
                                  "instanceParams":[
                                     {
                                        "availability_zone_0":"mtpocdv-kvm-az01",
          ]
       }
    }
-}
\ No newline at end of file
+}
diff --git a/mso-api-handlers/mso-api-handler-infra/src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json b/mso-api-handlers/mso-api-handler-infra/src/test/resources/Validation/UserParamsValidation/DuplicateInstanceNames.json
new file mode 100644 (file)
index 0000000..1910620
--- /dev/null
@@ -0,0 +1,193 @@
+{
+  "requestDetails": {
+    "subscriberInfo": {
+      "globalSubscriberId": "ubuntu-customer"
+    },
+    "requestInfo": {
+      "suppressRollback": false,
+      "instanceName": "ThreeVNFTest",
+      "productFamilyId": "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb",
+      "requestorId": "portal",
+      "source": "postman"
+    },
+    "requestParameters": {
+      "subscriptionServiceType": "ubuntu",
+      "userParams": [
+        {
+          "service": {
+            "instanceParams": [],
+            "resources": {
+              "vnfs": [
+                {
+                  "modelInfo": {
+                    "modelName": "UbuntuVF",
+                    "modelVersionId": "9306f24c-2b99-46d9-a92c-2236199555bd",
+                    "modelInvariantUuid": "5bd13140-11b6-4975-b6ee-e496d9a0cf0d",
+                    "modelVersion": "3.0",
+                    "modelCustomizationId": "435f34f8-1701-4276-ae39-47ad03bad782",
+                    "modelInstanceName": "UbuntuVF 0"
+                  },
+                  "cloudConfiguration": {
+                  },
+                  "platform": {
+                    "platformName": "test"
+                  },
+                  "productFamilyId": "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb",
+                  "instanceName": "UbuntuVNF1",
+                  "instanceParams": [
+                    {
+                      "vnf-name": "vnf-vnf-name",
+                      "vnf_name": "UbuntuVNFName"
+                    }
+                  ],
+                  "vfModules": [
+                    {
+                      "modelInfo": {
+                        "modelName": "Ubuntuvf..base..module-0",
+                        "modelVersionId": "c9de87ba-9d2a-44df-94c4-68aad72947e8",
+                        "modelInvariantUuid": "51aaa747-68e7-4313-9717-9d32c752bbdf",
+                        "modelVersion": "1",
+                        "modelCustomizationId": "25409778-c4b0-448c-aa45-89c0a2cc4165"
+                      },
+                      "instanceName": "lcm-demo-network-1",
+                      "instanceParams": [
+                        {
+                        }
+                      ]
+                    }
+                  ]
+                },
+                {
+                  "modelInfo": {
+                    "modelName": "UbuntuBVF",
+                    "modelVersionId": "0e5c37c2-8c35-4ff8-a538-803a5f44aeb5",
+                    "modelInvariantUuid": "cf4ac32e-88b8-4fff-b5fc-9ebe2b7251f8",
+                    "modelVersion": "1.0",
+                    "modelCustomizationId": "e774a853-4a47-4a88-b5b4-9324f1d7f6a7",
+                    "modelInstanceName": "UbuntuBVF 0"
+                  },
+                  "cloudConfiguration": {
+                  },
+                  "platform": {
+                    "platformName": "test"
+                  },
+                  "productFamilyId": "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb",
+                  "instanceName": "UbuntuVNF2",
+                  "instanceParams": [
+                    {
+                      "vnf-name": "vnf-vnf-name",
+                      "vnf_name": "UbuntuVNFName2"
+                    }
+                  ],
+                  "vfModules": [
+                    {
+                      "modelInfo": {
+                        "modelName": "Ubuntubvf..ubuntu-vf-module..module-1",
+                        "modelVersionId": "548fa27f-d9d7-498f-9292-4c1ddcf79d2d",
+                        "modelInvariantUuid": "7689624d-fdcd-40a5-acf1-93f5ef1a5a59",
+                        "modelVersion": "1",
+                        "modelCustomizationId": "c8db1431-ffbe-4978-9b28-b310ca2c7d93"
+                      },
+                      "instanceName": "lcm-demo-ubuntu-1",
+                      "instanceParams": [
+                        {
+                        }
+                      ]
+                    }
+                  ]
+                },
+                {
+                  "modelInfo": {
+                    "modelName": "UbuntuBVF",
+                    "modelVersionId": "0e5c37c2-8c35-4ff8-a538-803a5f44aeb5",
+                    "modelInvariantUuid": "cf4ac32e-88b8-4fff-b5fc-9ebe2b7251f8",
+                    "modelVersion": "1.0",
+                    "modelCustomizationId": "e774a853-4a47-4a88-b5b4-9324f1d7f6a7",
+                    "modelInstanceName": "UbuntuBVF 0"
+                  },
+                  "cloudConfiguration": {
+                  },
+                  "platform": {
+                    "platformName": "test"
+                  },
+                  "productFamilyId": "a9a77d5a-123e-4ca2-9eb9-0b015d2ee0fb",
+                  "instanceName": "UbuntuVNF3",
+                  "instanceParams": [
+                    {
+                      "vnf-name": "vnf-vnf-name",
+                      "vnf_name": "UbuntuVNFName3"
+                    }
+                  ],
+                  "vfModules": [
+                    {
+                      "modelInfo": {
+                        "modelName": "Ubuntubvf..ubuntu-vf-module..module-1",
+                        "modelVersionId": "548fa27f-d9d7-498f-9292-4c1ddcf79d2d",
+                        "modelInvariantUuid": "7689624d-fdcd-40a5-acf1-93f5ef1a5a59",
+                        "modelVersion": "1",
+                        "modelCustomizationId": "c8db1431-ffbe-4978-9b28-b310ca2c7d93"
+                      },
+                      "instanceName": "lcm-demo-ubuntu-2",
+                      "instanceParams": [
+                        {
+                        }
+                      ]
+                    },
+                    {
+                      "modelInfo": {
+                        "modelName": "Ubuntubvf..ubuntu-vf-module..module-1",
+                        "modelVersionId": "548fa27f-d9d7-498f-9292-4c1ddcf79d2d",
+                        "modelInvariantUuid": "7689624d-fdcd-40a5-acf1-93f5ef1a5a59",
+                        "modelVersion": "1",
+                        "modelCustomizationId": "c8db1431-ffbe-4978-9b28-b310ca2c7d93"
+                      },
+                      "instanceName": "lcm-demo-ubuntu-3",
+                      "instanceParams": [
+                        {
+                        }
+                      ]
+                    },
+                    {
+                      "modelInfo": {
+                        "modelName": "Ubuntunosriov..base..module-0",
+                        "modelVersionId": "bcc8ef84-b367-40c0-8a5d-ceabdc1785e0",
+                        "modelInvariantUuid": "f3927419-9e68-4883-b861-20c8412872d7",
+                        "modelVersion": "1",
+                        "modelCustomizationId": "ee848516-4e08-4b30-8ed0-d411bb059842"
+                      },
+                      "instanceName": "ubuntu-demo-mp-network-1",
+                      "instanceParams": [
+                        {
+                        }
+                      ]
+                    }
+                  ]
+                }
+              ]
+            },
+            "modelInfo": {
+              "modelVersion": "2.0",
+              "modelVersionId": "3a9ff92f-dc19-4f05-930d-d238939d508b",
+              "modelInvariantId": "115405d8-6944-407d-b0ae-6b7155754643",
+              "modelName": "Ubuntu3VNFService",
+              "modelType": "service"
+            }
+          }
+        }
+      ],
+      "aLaCarte": false
+    },
+    "project": {
+      "projectName": "Project-test"
+    },
+    "owningEntity": {
+    },
+    "modelInfo": {
+      "modelVersion": "2.0",
+      "modelVersionId": "3a9ff92f-dc19-4f05-930d-d238939d508b",
+      "modelInvariantId": "115405d8-6944-407d-b0ae-6b7155754643",
+      "modelName": "Ubuntu3VNFService",
+      "modelType": "service"
+    }
+  }
+}
\ No newline at end of file