Modify instance resource list creation 80/86580/3
authorsubhash kumar singh <subhash.kumar.singh@huawei.com>
Tue, 30 Apr 2019 01:34:39 +0000 (07:04 +0530)
committersubhash kumar singh <subhash.kumar.singh@huawei.com>
Thu, 2 May 2019 11:04:39 +0000 (16:34 +0530)
Modify instance resource list creation to avoid hard locking of
model name in UUI request.

e.g.
VF resource and gruop resource has resource input
vf { resource_input : { key1:value2, key2:[vf_prop_list,INDEX,key]|default}

Derive the key ("vf_prop_list") from resource input and use this
info to map UUI request.

UUI req:
{
...
  resourceInput: {
          vf_prop_list :   /// mapped with resource input of resource
                  {
....

Change-Id: Ic40079a094b2628bcf6f5758121b7492ee3c1353
Issue-ID: SO-1393
Signed-off-by: subhash kumar singh <subhash.kumar.singh@huawei.com>
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/bpmn/common/resource/InstanceResourceList.java
bpmn/MSOCommonBPMN/src/test/java/org/onap/so/bpmn/common/resource/InstnaceResourceListTest.java [new file with mode: 0644]
bpmn/MSOCommonBPMN/src/test/resources/__files/InstanceResourceList/InstanceResourceList.json [new file with mode: 0644]
bpmn/MSOCoreBPMN/src/main/java/org/onap/so/bpmn/core/domain/GroupResource.java
bpmn/MSOCoreBPMN/src/main/java/org/onap/so/bpmn/core/domain/VnfcResource.java

index b50ecda..71ea3b5 100644 (file)
  */
 package org.onap.so.bpmn.common.resource;
 
+import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
+import com.google.gson.JsonArray;
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import org.onap.so.bpmn.core.domain.GroupResource;
 import org.onap.so.bpmn.core.domain.Resource;
 import org.onap.so.bpmn.core.domain.ResourceType;
+import org.onap.so.bpmn.core.domain.VnfResource;
+import java.lang.reflect.Type;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 
 public class InstanceResourceList {
 
-    private static List<Map<String, List<GroupResource>>> convertUUIReqTOStd(final String uuiRequest,
+    private static Map<String, List<List<GroupResource>>> convertUUIReqTOStd(final JsonObject reqInputJsonObj,
             List<Resource> seqResourceList) {
 
-        List<Map<String, List<GroupResource>>> normalizedList = new ArrayList<>();
+        Map<String, List<List<GroupResource>>> normalizedRequest = new HashMap<>();
+        for (Resource r : seqResourceList) {
 
-        Gson gson = new Gson();
-        JsonObject servJsonObject = gson.fromJson(uuiRequest, JsonObject.class);
+            if (r.getResourceType() == ResourceType.VNF) {
+                String pk = getPrimaryKey(r);
 
-        JsonObject reqInputJsonObj = servJsonObject.getAsJsonObject("service").getAsJsonObject("parameters")
-                .getAsJsonObject("requestInputs");
+                JsonElement vfNode = reqInputJsonObj.get(pk);
 
-        // iterate all node in requestInputs
-        Iterator<Map.Entry<String, JsonElement>> iterator = reqInputJsonObj.entrySet().iterator();
-
-        while (iterator.hasNext()) { // iterate all <vf>_list
-            Map.Entry<String, JsonElement> entry = iterator.next();
-
-            // truncate "_list" from key and keep only the <VF_NAME>
-            String key = entry.getKey().substring(0, entry.getKey().indexOf("_list"));
-
-            // all the element represent VF will contain "<VF_NAME>_list".
-            if (key.contains("_list")) {
-                // this will return list of vf of same type
-                // e.g. vf_list [{vf1}, {vf2}]
-                Iterator<JsonElement> vfsIterator = entry.getValue().getAsJsonArray().iterator();
-
-                while (vfsIterator.hasNext()) { // iterate all [] inside vf_list
-                    JsonObject vfObject = vfsIterator.next().getAsJsonObject();
-                    List<GroupResource> tmpGrpsHolder = new ArrayList<>();
-
-                    // iterate vfObject to get groups(vfc)
-                    // currently each vfc represented by one group.
-                    Iterator<Map.Entry<String, JsonElement>> vfIterator = vfObject.entrySet().iterator();
-                    while (vfIterator.hasNext()) { // iterate all property inside a VF
-                        Map.Entry<String, JsonElement> vfEntry = vfIterator.next();
-
-                        // property name for vfc input will always carry "<VFC_NAME>_list"
-                        if (vfEntry.getKey().contains("_list")) {
-                            // truncate "_list" from key and keep only the <VFC_NAME>
-                            String vfcName = vfEntry.getKey().substring(0, vfEntry.getKey().indexOf("_list"));
-                            GroupResource grpRes = getGroupResource(vfcName, seqResourceList);
-                            // A <vfc>_list can contain more than one vfc of same type
-                            Iterator<JsonElement> vfcsIterator = vfEntry.getValue().getAsJsonArray().iterator();
-
-                            while (vfcsIterator.hasNext()) { // iterate all the vfcs inside <vfc>_list
-                                tmpGrpsHolder.add(grpRes);
-                            }
+                // if the service property is type of array then it
+                // means it is a VF resource
+                if (vfNode instanceof JsonArray) {
+
+                    for (int i = 0; i < ((JsonArray) vfNode).size(); i++) {
+                        List<List<GroupResource>> groupsList = normalizedRequest.get(pk);
+                        if (groupsList == null) {
+                            groupsList = new ArrayList<>();
+                            normalizedRequest.put(pk, groupsList);
                         }
+
+                        groupsList.add(new ArrayList<>());
                     }
-                    List<GroupResource> seqGrpResourceList = seqGrpResource(tmpGrpsHolder, seqResourceList);
-                    HashMap<String, List<GroupResource>> entryNormList = new HashMap<>();
-                    entryNormList.put(key, seqGrpResourceList);
-                    normalizedList.add(entryNormList);
                 }
-            }
-        }
 
-        return normalizedList;
-    }
+            } else if (r.getResourceType() == ResourceType.GROUP) {
+                String sk = getPrimaryKey(r);
 
-    private static List<GroupResource> seqGrpResource(List<GroupResource> grpResources, List<Resource> resourceList) {
-        List<GroupResource> seqGrpResList = new ArrayList<>();
-        for (Resource r : resourceList) {
-            if (r.getResourceType() != ResourceType.GROUP) {
-                continue;
-            }
-            for (GroupResource g : grpResources) {
-                if (r.getModelInfo().getModelName().equalsIgnoreCase(g.getModelInfo().getModelName())) {
-                    seqGrpResList.add(g);
+                for (String pk : normalizedRequest.keySet()) {
+                    JsonArray vfs = reqInputJsonObj.getAsJsonArray(pk);
+
+                    for (int i = 0; i < vfs.size(); i++) {
+
+                        JsonElement vfcsNode = vfs.get(i).getAsJsonObject().get(sk);
+                        if (vfcsNode instanceof JsonArray) {
+
+                            List<GroupResource> groupResources = normalizedRequest.get(pk).get(i);
+
+                            if (groupResources == null) {
+                                groupResources = new ArrayList<>();
+                                normalizedRequest.get(pk).add(i, groupResources);
+                            }
+
+                            for (int j = 0; j < ((JsonArray) vfcsNode).size(); j++) {
+                                groupResources.add((GroupResource) r);
+                            }
+                        }
+                    }
                 }
             }
         }
-        return seqGrpResList;
+        return normalizedRequest;
     }
 
-    private static GroupResource getGroupResource(String vfcName, List<Resource> seqRessourceList) {
-        for (Resource r : seqRessourceList) {
-            if (r.getResourceType() == ResourceType.GROUP) {
-                // Currently only once vnfc is added to group
-                return ((GroupResource) r).getVnfcs().get(0).getModelInfo().getModelName().contains(vfcName)
-                        ? (GroupResource) r
-                        : null;
-            }
+    // this method returns key from resource input
+    // e.g. {\"sdwansite_emails\" : \"[sdwansiteresource_list(PK), INDEX, sdwansite_emails]|default\",
+    // ....}
+    // it will return sdwansiteresource_list
+    private static String getPrimaryKey(Resource resource) {
+        String pk = "";
+
+        String resourceInput = "";
+        if (resource instanceof VnfResource) {
+            resourceInput = ((VnfResource) resource).getResourceInput();
+        } else if (resource instanceof GroupResource) {
+            resourceInput = ((GroupResource) resource).getVnfcs().get(0).getResourceInput();
         }
-        return null;
+
+        Gson gson = new Gson();
+        Type type = new TypeToken<Map<String, String>>() {}.getType();
+        Map<String, String> map = gson.fromJson(resourceInput, type);
+
+        Optional<String> pkOpt = map.values().stream().filter(e -> e.contains("[")).map(e -> e.replace("[", ""))
+                .map(e -> e.split(",")[0]).findFirst();
+
+        return pkOpt.isPresent() ? pkOpt.get() : "";
     }
 
-    private static List<Resource> convertToInstanceResourceList(List<Map<String, List<GroupResource>>> normalizedReq,
+    private static List<Resource> convertToInstanceResourceList(Map<String, List<List<GroupResource>>> normalizedReq,
             List<Resource> seqResourceList) {
         List<Resource> flatResourceList = new ArrayList<>();
         for (Resource r : seqResourceList) {
             if (r.getResourceType() == ResourceType.VNF) {
-                for (Map<String, List<GroupResource>> entry : normalizedReq) {
-                    if (r.getModelInfo().getModelName().equalsIgnoreCase(entry.keySet().iterator().next())) {
-                        flatResourceList.add(r);
-                        flatResourceList.addAll(entry.get(entry.keySet().iterator().next()));
+                String primaryKey = getPrimaryKey(r);
+                for (String pk : normalizedReq.keySet()) {
+
+                    if (primaryKey.equalsIgnoreCase(pk)) {
+
+                        List<List<GroupResource>> vfs = normalizedReq.get(pk);
+
+                        vfs.stream().forEach(e -> {
+                            flatResourceList.add(r);
+                            flatResourceList.addAll(e);
+                        });
                     }
                 }
             }
@@ -139,22 +143,13 @@ public class InstanceResourceList {
     public static List<Resource> getInstanceResourceList(final List<Resource> seqResourceList,
             final String uuiRequest) {
 
+        Gson gson = new Gson();
+        JsonObject servJsonObject = gson.fromJson(uuiRequest, JsonObject.class);
+        JsonObject reqInputJsonObj = servJsonObject.getAsJsonObject("service").getAsJsonObject("parameters")
+                .getAsJsonObject("requestInputs");
+
         // this will convert UUI request to normalized form
-        List<Map<String, List<GroupResource>>> normalizedReq = convertUUIReqTOStd(uuiRequest, seqResourceList);
-
-        // now UUI json req is normalized to
-        // [
-        // { VFB1 : [GrpA1, GrA2, GrB1]},
-        // { VFB2 : [GrpA1, GrB1]},
-        // { VFA1 : [GrpC1]}
-        // ]
-        // now sequence according to VF order (Group is already sequenced).
-        // After sequence it will look like :
-        // [
-        // { VFA1 : [GrpA1, GrA2, GrB1]},
-        // { VFA2 : [GrpA1, GrB1]},
-        // { VFB1 : [GrpC1]}
-        // ]
-        return convertToInstanceResourceList(normalizedReq, seqResourceList);
+        Map<String, List<List<GroupResource>>> normalizedRequest = convertUUIReqTOStd(reqInputJsonObj, seqResourceList);
+        return convertToInstanceResourceList(normalizedRequest, seqResourceList);
     }
 }
diff --git a/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/bpmn/common/resource/InstnaceResourceListTest.java b/bpmn/MSOCommonBPMN/src/test/java/org/onap/so/bpmn/common/resource/InstnaceResourceListTest.java
new file mode 100644 (file)
index 0000000..3be67c9
--- /dev/null
@@ -0,0 +1,46 @@
+package org.onap.so.bpmn.common.resource;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.onap.so.bpmn.core.domain.GroupResource;
+import org.onap.so.bpmn.core.domain.Resource;
+import org.onap.so.bpmn.core.domain.ResourceType;
+import org.onap.so.bpmn.core.domain.VnfResource;
+import org.onap.so.bpmn.core.domain.VnfcResource;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class InstnaceResourceListTest {
+
+    public static String RESOURCE_PATH = "src/test/resources/__files/InstanceResourceList/";
+
+    @Test
+    public void testInstanceResourceList() throws IOException {
+        String uuiRequest = new String(Files.readAllBytes(Paths.get(RESOURCE_PATH + "InstanceResourceList" + ".json")));
+        List<Resource> instanceResourceList =
+                InstanceResourceList.getInstanceResourceList(createResourceSequence(), uuiRequest);
+        Assert.assertEquals(4, instanceResourceList.size());
+        Assert.assertEquals(ResourceType.VNF, instanceResourceList.get(0).getResourceType());
+        Assert.assertEquals(ResourceType.GROUP, instanceResourceList.get(1).getResourceType());
+        Assert.assertEquals(ResourceType.VNF, instanceResourceList.get(2).getResourceType());
+        Assert.assertEquals(ResourceType.GROUP, instanceResourceList.get(3).getResourceType());
+    }
+
+    private List<Resource> createResourceSequence() {
+        List<Resource> resourceList = new ArrayList<>();
+        VnfResource vnfResource = new VnfResource();
+        vnfResource.setResourceInput("{\"a\":\"[sdwansiteresource_list,INDEX,sdwansiteresource_list]\"}");
+
+        VnfcResource vnfcResource = new VnfcResource();
+        vnfcResource.setResourceInput("{\"a\":\"[sdwansitewan_list,INDEX,test]\"}");
+
+        GroupResource groupResource = new GroupResource();
+        groupResource.setVnfcs(Arrays.asList(vnfcResource));
+
+        return Arrays.asList(vnfResource, groupResource);
+    }
+}
diff --git a/bpmn/MSOCommonBPMN/src/test/resources/__files/InstanceResourceList/InstanceResourceList.json b/bpmn/MSOCommonBPMN/src/test/resources/__files/InstanceResourceList/InstanceResourceList.json
new file mode 100644 (file)
index 0000000..0b3d9f0
--- /dev/null
@@ -0,0 +1,175 @@
+{
+  "service":{
+    "name":"SiteService",
+    "description":"SiteService",
+    "serviceInvariantUuid":"5c13f3fb-2744-4635-9f1f-c59c92dc8f70",
+    "serviceUuid":"3a76b1f5-fb0d-4b6b-82d5-0e8a4ebc3838",
+    "globalSubscriberId":"test_custormer",
+    "serviceType":"example-service-type",
+    "parameters":{
+      "locationConstraints":[
+
+      ],
+      "resources":[
+        {
+          "resourceIndex":"1",
+          "resourceName":"sdwanvpnresource",
+          "resourceInvariantUuid":"0c0e1cbe-6e01-4f9e-8c45-a9700ebc14df",
+          "resourceUuid":"4ad2d390-5c51-45f5-9710-b467a4ec7a73",
+          "resourceCustomizationUuid":"66590e07-0777-415c-af44-36347cf3ddd3",
+          "parameters":{
+            "locationConstraints":[
+
+            ],
+            "resources":[
+
+            ],
+            "requestInputs":{
+
+            }
+          }
+        },
+        {
+          "resourceIndex":"1",
+          "resourceName":"sdwansiteresource",
+          "resourceInvariantUuid":"97a3e552-08c4-4697-aeeb-d8d3e09ce58e",
+          "resourceUuid":"63d8e1af-32dc-4c71-891d-e3f7b6a976d2",
+          "resourceCustomizationUuid":"205456e7-3dc0-40c4-8cb0-28e6c1877042",
+          "parameters":{
+            "locationConstraints":[
+
+            ],
+            "resources":[
+
+            ],
+            "requestInputs":{
+
+            }
+          }
+        },
+        {
+          "resourceIndex":"2",
+          "resourceName":"sdwansiteresource",
+          "resourceInvariantUuid":"97a3e552-08c4-4697-aeeb-d8d3e09ce58e",
+          "resourceUuid":"63d8e1af-32dc-4c71-891d-e3f7b6a976d2",
+          "resourceCustomizationUuid":"205456e7-3dc0-40c4-8cb0-28e6c1877042",
+          "parameters":{
+            "locationConstraints":[
+
+            ],
+            "resources":[
+
+            ],
+            "requestInputs":{
+
+            }
+          }
+        }
+      ],
+      "requestInputs":{
+        "sdwanvpnresource_list":[
+          {
+            "sdwanvpn_topology":"hub_spoke",
+            "sdwanvpn_name":"defaultvpn",
+            "sdwansitelan_list":[
+              {
+                "role":"Hub",
+                "portType":"GE",
+                "portSwitch":"layer3-port",
+                "vlanId":"",
+                "ipAddress":"192.168.10.1",
+                "deviceName":"vCPE",
+                "portNumer":"0/0/1"
+              },
+              {
+                "role":"Hub",
+                "portType":"GE",
+                "portSwitch":"layer2-port",
+                "vlanId":"55",
+                "ipAddress":"192.168.11.1",
+                "deviceName":"CPE_Beijing",
+                "portNumer":"0/0/1"
+              }
+            ]
+          }
+        ],
+        "sdwansiteresource_list":[
+          {
+            "sdwansite_emails":"chenchuanyu@huawei.com",
+            "sdwansite_address":"Huawei Public Cloud",
+            "sdwansite_description":"DC Site",
+            "sdwansite_role":"dsvpn_hub",
+            "sdwansite_postcode":"20000",
+            "sdwansite_type":"single_gateway",
+            "sdwansite_latitude":"",
+            "sdwansite_controlPoint":"",
+            "sdwansite_longitude":"",
+            "sdwansitewan_list":[
+              {
+                "providerIpAddress":"",
+                "portType":"GE",
+                "inputBandwidth":"1000",
+                "ipAddress":"",
+                "name":"10000",
+                "transportNetworkName":"internet",
+                "outputBandwidth":"10000",
+                "deviceName":"vCPE",
+                "portNumber":"0/0/0",
+                "ipMode":"DHCP",
+                "publicIP":"119.3.7.113"
+              }
+            ],
+            "sdwandevice_list":[
+              {
+                "esn":"XXXXXXX",
+                "vendor":"Huawei",
+                "name":"vCPE",
+                "type":"AR1000V",
+                "version":"1.0",
+                "class":"VNF",
+                "systemIp":"20.20.20.1"
+              }
+            ]
+          },
+          {
+            "sdwansite_emails":"chenchuanyu@huawei.com",
+            "sdwansite_address":"Huawei Public Cloud",
+            "sdwansite_description":"DC Site",
+            "sdwansite_role":"dsvpn_hub",
+            "sdwansite_postcode":"20000",
+            "sdwansite_type":"single_gateway",
+            "sdwansite_latitude":"",
+            "sdwansite_controlPoint":"",
+            "sdwansite_longitude":"",
+            "sdwansitewan_list":[
+              {
+                "providerIpAddress":"",
+                "portType":"GE",
+                "inputBandwidth":"1000",
+                "ipAddress":"172.18.1.2/24",
+                "name":"10000",
+                "transportNetworkName":"internet",
+                "outputBandwidth":"10000",
+                "deviceName":"CPE_Beijing",
+                "portNumber":"0/0/0",
+                "ipMode":"Static",
+                "publicIP":""
+              }
+            ],
+            "sdwandevice_list":[
+              {
+                "esn":"XXXXXXX",
+                "vendor":"Huawei",
+                "name":"CPE_Beijing",
+                "type":"AR161",
+                "version":"1.0",
+                "class":"PNF",
+                "systemIp":"20.20.20.2"
+              }
+            ]
+          }
+        ]
+      }
+    }
+  }
+}
\ No newline at end of file
index d194f27..79714d0 100644 (file)
  */
 package org.onap.so.bpmn.core.domain;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.List;
 import java.util.UUID;
 
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class GroupResource extends Resource {
     private static final long serialVersionUID = 1L;
 
index 5fced9a..c363fcc 100644 (file)
  */
 package org.onap.so.bpmn.core.domain;
 
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.fasterxml.jackson.annotation.JsonProperty;
 import java.util.UUID;
 
+@JsonIgnoreProperties(ignoreUnknown = true)
 public class VnfcResource extends Resource {
     private static final long serialVersionUID = 1L;
 
+    @JsonProperty("resource-input")
+    private String resourceInput;
+
     public VnfcResource() {
         resourceType = ResourceType.VNFC;
         setResourceId(UUID.randomUUID().toString());
     }
+
+    public String getResourceInput() {
+        return resourceInput;
+    }
+
+    public void setResourceInput(String resourceInput) {
+        this.resourceInput = resourceInput;
+    }
 }