Support instantiation of same model vnfs/vf-modules 28/122128/4
authorMichael Pruss <michael.pruss@bell.ca>
Mon, 31 May 2021 22:28:08 +0000 (18:28 -0400)
committerJozsef Csongvai <jozsef.csongvai@bell.ca>
Fri, 30 Jul 2021 16:24:31 +0000 (12:24 -0400)
When instantiating a service with multiple vnfs and/or vfmodules
SO would differentiate using ModelCustomizationId. This would cause
issues when creating multiple instances of same model resource, and
each lookup would return the same object.

Instead of using ModelCustomizationId, this patch enables SO to use
instanceName parameter to differentiate the resources. Validation was
added to ensure that instanceNames are provided if there are multiple
resources of the same model. If there are no duplicate resources and
instanceName is not set, SO will default to previous logic using
ModelCustomizationId.

In order to properly associate vfmodules with their parent vnfs, the
Resource class was augmented with a parent reference which maintains
the relationship in further processing.

Id generation logic was corrected to ensure that multiple resources
of the same model are assigned unique instance ids and references to
parent instanceId.

Issue-ID: SO-3677
Change-Id: If39a0138f501177e12262f8e911137012e287fca
Signed-off-by: Michael Pruss <michael.pruss@bell.ca>
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