Implant vid-app-common org.onap.vid.job (main and test)
[vid.git] / vid-app-common / src / main / java / org / onap / vid / services / AAITreeNodeBuilder.java
index e060882..d53eba8 100644 (file)
@@ -7,9 +7,9 @@
  * 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.
 package org.onap.vid.services;
 
 import com.fasterxml.jackson.databind.JsonNode;
-import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.ImmutableList;
 import org.apache.commons.lang3.StringUtils;
-import org.jetbrains.annotations.NotNull;
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.apache.commons.lang3.tuple.Pair;
 import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate;
+import org.onap.portalsdk.core.util.SystemProperties;
 import org.onap.vid.aai.AaiClientInterface;
 import org.onap.vid.aai.ExceptionWithRequestInfo;
 import org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.Relationship;
+import org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.RelationshipData;
 import org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.RelationshipList;
+import org.onap.vid.aai.util.AAITreeNodeUtils;
+import org.onap.vid.exceptions.GenericUncheckedException;
 import org.onap.vid.model.aaiTree.AAITreeNode;
 import org.onap.vid.model.aaiTree.FailureAAITreeNode;
+import org.onap.vid.model.aaiTree.NodeType;
+import org.onap.vid.mso.model.CloudConfiguration;
+import org.onap.vid.properties.VidProperties;
 import org.onap.vid.utils.Streams;
 import org.onap.vid.utils.Tree;
 import org.onap.vid.utils.Unchecked;
+import org.springframework.http.HttpMethod;
 import org.springframework.stereotype.Component;
 
 import javax.inject.Inject;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentLinkedQueue;
-import java.util.concurrent.ConcurrentSkipListSet;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.atomic.AtomicInteger;
+import java.util.*;
+import java.util.concurrent.*;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
 import static java.util.stream.Collectors.*;
+import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER;
 import static org.onap.vid.utils.Streams.not;
 
 
 @Component
 public class AAITreeNodeBuilder {
 
+    private static final String RESULTS = "results";
     private AaiClientInterface aaiClient;
 
-    private final ObjectMapper mapper = new ObjectMapper();
-
     private static final EELFLoggerDelegate LOGGER = EELFLoggerDelegate.getLogger(AAITreeNodeBuilder.class);
 
-    //List of all the node types the tree should include
-    public static final String SERVICE_INSTANCE = "service-instance";
-    public static final String GENERIC_VNF = "generic-vnf";
-    public static final String NETWORK = "l3-network";
-    public static final String FAILURE = "failure_node";
-    public static final String COLLECTION_RESOURCE = "collection";
-    public static final String CONFIGURATION = "configuration";
-    public static final String PNF = "pnf";
-    public static final String VF_MODULE = "vf-module";
-    public static final String INSTANCE_GROUP = "instance-group";
-    public static final String PORT = "l-interface";
-    public static final String VG = "volume-group";
-    public static final String VLAN_TAG = "vlan-tag";
-
-    //Hashmap that defines the node-type and the tag that should be used to find it's ID key in the JSON.
-    private static HashMap<String, String> nodeTypeToIdKeyMap = generateTypeToIdKeyMap();
-
-    //Hashmap that defines the node-type and the tag that should be used to find it's NAMR key in the JSON.
-    private static HashMap<String, String> nodeTypeToNameKeyMap = generateTypeToNameKeyMap();
 
     public enum AAIBaseProperties {
         ORCHESTRATION_STATUS("orchestration-status"),
@@ -102,63 +85,121 @@ public class AAITreeNodeBuilder {
         }
     }
 
-    public static List<AAIServiceTree.AaiRelationship> toAaiRelationshipList(String... types) {
-        return Stream.of(types).map(AAIServiceTree.AaiRelationship::new).collect(Collectors.toList());
-    }
-
     @Inject
     public AAITreeNodeBuilder(AaiClientInterface aaiClient) {
         this.aaiClient = aaiClient;
     }
 
-    public List<AAITreeNode> buildNode(String nodeType,
-                                 String requestURL,
-                                 ConcurrentSkipListSet<AAITreeNode> nodesAccumulator, ExecutorService threadPool,
-                                 ConcurrentLinkedQueue<String> visitedNodes,
-                                 AtomicInteger nodesCounter,
-                                 Tree<AAIServiceTree.AaiRelationship> pathsTree) {
+    List<AAITreeNode> buildNode(NodeType nodeType,
+                                String requestURL,
+                                String payload,
+                                HttpMethod method,
+                                ConcurrentSkipListSet<AAITreeNode> nodesAccumulator,
+                                ExecutorService threadPool,
+                                Tree<AAIServiceTree.AaiRelationship> pathsTree) {
 
-        JsonNode topLevelJson = aaiClient.typedAaiGet(Unchecked.toURI(requestURL), JsonNode.class);
+        JsonNode jsonNode = aaiClient.typedAaiRest(Unchecked.toURI(requestURL), JsonNode.class, payload, method, false);
 
-        if (topLevelJson.has(nodeType) && topLevelJson.get(nodeType).isArray()) {
-            return Streams.fromIterable(topLevelJson.get(nodeType))
-                    .map(item -> parseNodeAndGetChildren(nodeType, requestURL, item,
-                            nodesAccumulator, threadPool, visitedNodes, nodesCounter, pathsTree))
-                    .collect(toList());
-        } else {
-            return ImmutableList.of(parseNodeAndGetChildren(nodeType, requestURL, topLevelJson,
-                    nodesAccumulator, threadPool, visitedNodes, nodesCounter, pathsTree));
+        List<Pair<AAITreeNode, List<Relationship>>> nodes = getNodesWithRelationships(jsonNode, nodeType, nodesAccumulator, pathsTree);
+
+        String timeout = SystemProperties.getProperty(VidProperties.VID_THREAD_TIMEOUT);
+        long timeoutNum = Long.parseLong(StringUtils.defaultIfEmpty(timeout, "30"));
+
+        for (Pair<AAITreeNode, List<Relationship>> entry : nodes) {
+            fetchChildrenAsync(threadPool, nodesAccumulator, entry.getKey(), entry.getValue(), pathsTree, timeoutNum);
+
+            if (getNextLevelInPathsTree(pathsTree, NodeType.VF_MODULE.getType()) != null) {
+                getRelatedVfModules(threadPool, nodesAccumulator, requestURL, entry.getKey());
+            }
         }
+
+        return nodes.stream()
+                .map(Pair::getKey)
+                .collect(Collectors.toList());
     }
 
-    private AAITreeNode parseNodeAndGetChildren(String nodeType,
-                                                String requestURL,
-                                                JsonNode topLevelJson,
-                                                ConcurrentSkipListSet<AAITreeNode> nodesAccumulator, ExecutorService threadPool,
-                                                ConcurrentLinkedQueue<String> visitedNodes,
-                                                AtomicInteger nodesCounter,
-                                                Tree<AAIServiceTree.AaiRelationship> pathsTree) {
-        AAITreeNode node = jsonToAaiNode(nodeType, topLevelJson, nodesAccumulator, nodesCounter);
-
-        RelationshipList relationships = mapper.convertValue(topLevelJson.get(AAIBaseProperties.RELATIONSHIP_LIST.getAaiKey()), RelationshipList.class);
-        if (relationships != null) {
-            getChildren(threadPool, nodesAccumulator, relationships.getRelationship(), visitedNodes, node, nodesCounter, pathsTree);
-        }
-        if (StringUtils.equals(node.getType(), GENERIC_VNF)) {
-            getRelatedVfModules(threadPool, nodesAccumulator, requestURL, node, nodesCounter);
+    private List<Pair<AAITreeNode, List<Relationship>>> getNodesWithRelationships(JsonNode jsonNode, NodeType nodeType,
+                                                                                  ConcurrentSkipListSet<AAITreeNode> nodesAccumulator,
+                                                                                  Tree<AAIServiceTree.AaiRelationship> pathsTree) {
+        if (isListOfKeyResults(jsonNode)) {
+            return Streams.fromIterable(jsonNode.get(RESULTS))
+                    .filter(item -> item.has(nodeType.getType()))
+                    .map(item -> item.get(nodeType.getType()))
+                    .map(item -> parseNodeAndFilterRelationships(item, nodeType, nodesAccumulator, pathsTree))
+                    .collect(Collectors.toList());
+        } else if (isArray(jsonNode, nodeType)) {
+            return Streams.fromIterable(jsonNode.get(nodeType.getType()))
+                    .map(item -> parseNodeAndFilterRelationships(item, nodeType, nodesAccumulator, pathsTree))
+                    .collect(Collectors.toList());
+        } else {
+            return ImmutableList.of(parseNodeAndFilterRelationships(jsonNode, nodeType, nodesAccumulator, pathsTree));
         }
-        return node;
     }
 
-    private AAITreeNode jsonToAaiNode(String nodeType, JsonNode topLevelJson, ConcurrentSkipListSet<AAITreeNode> nodesAccumulator, AtomicInteger nodesCounter) {
-        AAITreeNode node = fillNodeMetaData(nodeType, topLevelJson, nodesCounter);
+    Pair<AAITreeNode, List<Relationship>> parseNodeAndFilterRelationships(JsonNode jsonNode, NodeType nodeType,
+                                                                          ConcurrentSkipListSet<AAITreeNode> nodesAccumulator,
+                                                                          Tree<AAIServiceTree.AaiRelationship> pathsTree) {
+        AAITreeNode node = createAaiNode(nodeType, jsonNode, nodesAccumulator);
+
+        enrichPlacementData(node);
+
+        List<Relationship> filteredRelationships = getFilteredRelationships(jsonNode, pathsTree);
+
+        return ImmutablePair.of(node, filteredRelationships);
+    }
+
+    boolean isArray(JsonNode json, NodeType nodeType) {
+        return json != null && json.has(nodeType.getType()) && json.get(nodeType.getType()).isArray();
+    }
+
+    boolean isListOfKeyResults(JsonNode jsonNode) {
+        return jsonNode != null && jsonNode.has(RESULTS) && jsonNode.get(RESULTS).isArray();
+    }
+
+    AAITreeNode createAaiNode(NodeType nodeType, JsonNode jsonNode, ConcurrentSkipListSet<AAITreeNode> nodesAccumulator) {
+        AAITreeNode node = jsonNodeToAaiNode(nodeType, jsonNode);
 
         nodesAccumulator.add(node);
 
         return node;
     }
 
-    private void getRelatedVfModules(ExecutorService threadPool, ConcurrentSkipListSet<AAITreeNode> nodesAccumulator, String parentURL, AAITreeNode parentNode, AtomicInteger nodesCounter) {
+    private void addChildren(AAITreeNode node, Future<List<AAITreeNode>> children) {
+        try {
+            node.addChildren(children.get());
+        } catch (Exception e) {
+            node.getChildren().add(createFailureNode(e));
+        }
+    }
+
+    private Map<String,String> convertRelationshipDataToMap(List<RelationshipData> relationshipData) {
+        return relationshipData.stream().collect(
+                Collectors.toMap(RelationshipData::getKey, RelationshipData::getValue));
+    }
+
+    void enrichPlacementData(AAITreeNode node){
+        Optional<Relationship> tenantRelationShip = AAITreeNodeUtils.findFirstRelationshipByRelatedTo(node.getRelationshipList(), "tenant");
+        enrichPlacementDataUsingTenantInfo(node, tenantRelationShip);
+    }
+
+    void enrichPlacementDataUsingTenantInfo(AAITreeNode node, Optional<Relationship> tenantRelationShip) {
+        //no tenant relationship in this node - so no placement data
+        if (!tenantRelationShip.isPresent()) {
+            return;
+        }
+        try {
+            Map<String, String> relationshipsDataMap = convertRelationshipDataToMap(tenantRelationShip.get().getRelationDataList());
+            node.setCloudConfiguration(new CloudConfiguration(
+                    relationshipsDataMap.get("cloud-region.cloud-region-id"),
+                    relationshipsDataMap.get("tenant.tenant-id"),
+                    relationshipsDataMap.get("cloud-region.cloud-owner")));
+        }
+        catch (Exception exception) {
+            LOGGER.error("Failed to extract placement form tenant relationship of {}:{}", node.getType(), node.getId(), exception);
+        }
+    }
+
+    private void getRelatedVfModules(ExecutorService threadPool, ConcurrentSkipListSet<AAITreeNode> nodesAccumulator, String parentURL, AAITreeNode parentNode) {
         /*
         VNFs do not report their direct related-to vf-modules, so try
         directly fetching a resource URI.
@@ -166,73 +207,100 @@ public class AAITreeNodeBuilder {
 
         threadPool.execute(() -> {
             // the response is an array of vf-modules
-            final JsonNode topLevelJson;
+            final JsonNode jsonNode;
             try {
-                topLevelJson = aaiClient.typedAaiGet(Unchecked.toURI(parentURL + "/vf-modules"), JsonNode.class);
+                jsonNode = aaiClient.typedAaiGet(Unchecked.toURI(parentURL + "/vf-modules"), JsonNode.class);
             } catch (ExceptionWithRequestInfo e) {
                 if (e.getHttpCode().equals(404)) {
                     // it's ok, as we're just optimistically fetching
-                    // the /vf-modules uri; 404 says this time it was
-                    // a bad guess
+                    // the /vf-modules uri; 404 says this time it was a bad guess
                     return;
                 } else {
                     throw e;
                 }
             }
 
-            if (topLevelJson != null) {
-                parentNode.getChildren().addAll(
-                        Streams.fromIterable(topLevelJson.get(VF_MODULE))
-                                .map(vfModuleNode -> jsonToAaiNode(VF_MODULE, vfModuleNode, nodesAccumulator, nodesCounter))
-                                .collect(toList())
-                );
+            if (isArray(jsonNode, NodeType.VF_MODULE)) {
+
+                //create list of AAITreeNode represent the VfModules from AAI result
+                List<AAITreeNode> vfModules = Streams.fromIterable(jsonNode.get(NodeType.VF_MODULE.getType()))
+                        .map(vfModuleNode -> createAaiNode(NodeType.VF_MODULE, vfModuleNode, nodesAccumulator))
+                        .collect(toList());
+                //enrich each of the VfModule with placement info
+                vfModules.forEach(vfModule-> enrichPlacementDataUsingTenantInfo(
+                        vfModule,
+                        AAITreeNodeUtils.findFirstRelationshipByRelatedTo(vfModule.getRelationshipList(), "vserver")
+                ));
+                //add all VfModules to children list of parent node
+                parentNode.getChildren().addAll(vfModules);
             } else {
                 LOGGER.error(EELFLoggerDelegate.errorLogger, "Failed to get vf-modules for vnf " + parentNode.getId());
             }
         });
     }
 
-    private void getChildren(ExecutorService threadPool, ConcurrentSkipListSet<AAITreeNode> nodesAccumulator,
-                             List<Relationship> relationships, ConcurrentLinkedQueue<String> visitedNodes, AAITreeNode parent, AtomicInteger nodesCounter, Tree<AAIServiceTree.AaiRelationship> pathsTree) {
-        for (Relationship relationship : relationships) {
-            createChildNode(threadPool, nodesAccumulator, relationship, visitedNodes, parent, nodesCounter, pathsTree);
+    List<Relationship> getFilteredRelationships(JsonNode json, Tree<AAIServiceTree.AaiRelationship> pathsTree) {
+        RelationshipList relationshipList = JACKSON_OBJECT_MAPPER.convertValue(json.get(AAIBaseProperties.RELATIONSHIP_LIST.getAaiKey()), RelationshipList.class);
+        if (relationshipList != null) {
+            return relationshipList.getRelationship().stream()
+                    .filter(rel -> getNextLevelInPathsTree(pathsTree, rel.getRelatedTo()) != null)
+                    .filter(rel -> !Objects.equals(rel.getRelatedTo(), NodeType.VF_MODULE.getType())) // vf-modules are handled separately
+                    .collect(toList());
         }
+
+        return Collections.emptyList();
     }
 
-    private void createChildNode(ExecutorService threadPool, ConcurrentSkipListSet<AAITreeNode> nodesAccumulator,
-                                 Relationship relationship, ConcurrentLinkedQueue<String> visitedNodes, AAITreeNode parent, AtomicInteger nodesCounter, Tree<AAIServiceTree.AaiRelationship> pathsTree) {
-        String newNodeType = relationship.getRelatedTo();
-        Tree<AAIServiceTree.AaiRelationship> subTree = pathsTree.getSubTree(new AAIServiceTree.AaiRelationship(newNodeType));
-        if (subTree!=null) {
-            String newNodeUrl = relationship.getRelatedLink();
-            if (!visitedNodes.contains(newNodeUrl)) {
-                visitedNodes.add(newNodeUrl);
-                threadPool.execute(() -> {
-                            try {
-                                parent.addChildren(buildNode(newNodeType, newNodeUrl, nodesAccumulator, threadPool, visitedNodes, nodesCounter,  subTree));
-                            } catch (Exception e) {
-                                parent.getChildren().add(createFailureNode(e));
-                            }
-                        }
-                );
+    void fetchChildrenAsync(ExecutorService threadPool, ConcurrentSkipListSet<AAITreeNode> nodesAccumulator,
+                            AAITreeNode node, List<Relationship> relationships, Tree<AAIServiceTree.AaiRelationship> pathsTree, long timeout) {
+
+        if (!relationships.isEmpty()) {
+            List<Callable<List<AAITreeNode>>> tasks = relationships.stream()
+                    .map(relationship ->
+                            (Callable<List<AAITreeNode>>) () ->
+                                    getChildNode(threadPool, nodesAccumulator, relationship.getRelatedTo(),
+                                            relationship.getRelatedLink(), pathsTree))
+                    .collect(Collectors.toList());
+
+            try {
+                int depth = pathsTree.getChildrenDepth();
+                threadPool.invokeAll(tasks, timeout * depth, TimeUnit.SECONDS)
+                        .forEach(future ->
+                                addChildren(node, future)
+                        );
+            } catch (Exception e) {
+                throw new GenericUncheckedException(e);
             }
         }
     }
 
-    private AAITreeNode fillNodeMetaData(String nodeType, JsonNode model, @NotNull AtomicInteger nodesCounter) {
+    private List<AAITreeNode> getChildNode(ExecutorService threadPool, ConcurrentSkipListSet<AAITreeNode> nodesAccumulator,
+                                           String childNodeType, String childNodeUrl,
+                                           Tree<AAIServiceTree.AaiRelationship> pathsTree) {
+
+        Tree<AAIServiceTree.AaiRelationship> subTree = getNextLevelInPathsTree(pathsTree, childNodeType);
+
+        return buildNode(NodeType.fromString(childNodeType), childNodeUrl, null, HttpMethod.GET, nodesAccumulator, threadPool, subTree);
+    }
+
+    Tree<AAIServiceTree.AaiRelationship> getNextLevelInPathsTree(Tree<AAIServiceTree.AaiRelationship> pathsTree, String nodeType) {
+        return pathsTree.getSubTree(new AAIServiceTree.AaiRelationship(nodeType));
+    }
+
+    //ADD TEST
+    private AAITreeNode jsonNodeToAaiNode(NodeType nodeType, JsonNode jsonNode) {
         AAITreeNode node = new AAITreeNode();
         node.setType(nodeType);
-        node.setUniqueNumber(nodesCounter.getAndIncrement());
-        node.setOrchestrationStatus(getStringDataFromJsonIfExists(model, AAIBaseProperties.ORCHESTRATION_STATUS.getAaiKey()));
-        node.setProvStatus(getStringDataFromJsonIfExists(model, AAIBaseProperties.PROV_STATUS.getAaiKey()));
-        node.setInMaint(getBooleanDataFromJsonIfExists(model, AAIBaseProperties.IN_MAINT.getAaiKey()));
-        node.setModelVersionId(getStringDataFromJsonIfExists(model, AAIBaseProperties.MODEL_VERSION_ID.getAaiKey()));
-        node.setModelCustomizationId(getStringDataFromJsonIfExists(model, AAIBaseProperties.MODEL_CUSTOMIZATION_ID.getAaiKey()));
-        node.setModelInvariantId(getStringDataFromJsonIfExists(model, AAIBaseProperties.MODEL_INVARIANT_ID.getAaiKey()));
-        node.setId(getStringDataFromJsonIfExists(model, nodeTypeToIdKeyMap.get(nodeType)));
-        node.setName(getStringDataFromJsonIfExists(model, nodeTypeToNameKeyMap.get(nodeType)));
-        node.setAdditionalProperties(aggregateAllOtherProperties(model, nodeType));
-
+        node.setOrchestrationStatus(getStringDataFromJsonIfExists(jsonNode, AAIBaseProperties.ORCHESTRATION_STATUS.getAaiKey()));
+        node.setProvStatus(getStringDataFromJsonIfExists(jsonNode, AAIBaseProperties.PROV_STATUS.getAaiKey()));
+        node.setInMaint(getBooleanDataFromJsonIfExists(jsonNode, AAIBaseProperties.IN_MAINT.getAaiKey()));
+        node.setModelVersionId(getStringDataFromJsonIfExists(jsonNode, AAIBaseProperties.MODEL_VERSION_ID.getAaiKey()));
+        node.setModelCustomizationId(getStringDataFromJsonIfExists(jsonNode, AAIBaseProperties.MODEL_CUSTOMIZATION_ID.getAaiKey()));
+        node.setModelInvariantId(getStringDataFromJsonIfExists(jsonNode, AAIBaseProperties.MODEL_INVARIANT_ID.getAaiKey()));
+        node.setId(getStringDataFromJsonIfExists(jsonNode, nodeType.getId()));
+        node.setName(getStringDataFromJsonIfExists(jsonNode, nodeType.getName()));
+        node.setAdditionalProperties(aggregateAllOtherProperties(jsonNode, nodeType));
+        node.setRelationshipList(JACKSON_OBJECT_MAPPER.convertValue(jsonNode.get(AAIBaseProperties.RELATIONSHIP_LIST.getAaiKey()), RelationshipList.class));
         return node;
     }
 
@@ -241,7 +309,7 @@ public class AAITreeNodeBuilder {
     }
 
     private String getStringDataFromJsonIfExists(JsonNode model, String key) {
-        if (model.has(key)) {
+        if (!NodeType.NONE.equals(key) && model.has(key)) {
             return model.get(key).asText();
         }
         return null;
@@ -254,48 +322,17 @@ public class AAITreeNodeBuilder {
         return false;
     }
 
-    private Map<String, Object> aggregateAllOtherProperties(JsonNode model, String nodeType) {
+    Map<String, Object> aggregateAllOtherProperties(JsonNode model, NodeType nodeType) {
         Set<String> ignoreProperties = Stream.of(AAIBaseProperties.values())
                 .map(AAIBaseProperties::getAaiKey).collect(toSet());
-
         return Streams.fromIterator(model.fields())
-                .filter(not(field -> StringUtils.equals(field.getKey(), nodeTypeToIdKeyMap.get(nodeType))))
-                .filter(not(field -> StringUtils.equals(field.getKey(), nodeTypeToNameKeyMap.get(nodeType))))
+                .filter(not(field -> StringUtils.equals(field.getKey(), nodeType.getId())))
+                .filter(not(field -> StringUtils.equals(field.getKey(), nodeType.getName())))
                 .filter(not(field -> ignoreProperties.contains(field.getKey())))
-                .collect(toMap(Map.Entry::getKey, v -> v.getValue().asText()));
-    }
-
-    private static HashMap<String, String> generateTypeToIdKeyMap() {
-        HashMap<String, String> result = new HashMap<>();
-        result.put(SERVICE_INSTANCE, "service-instance-id");
-        result.put(GENERIC_VNF, "vnf-id");
-        result.put(NETWORK, "network-id");
-        result.put(COLLECTION_RESOURCE, "collection-id");
-        result.put(CONFIGURATION, "configuration-id");
-        result.put(PNF, "pnf-id");
-        result.put(VF_MODULE, "vf-module-id");
-        result.put(INSTANCE_GROUP, "id");
-        result.put(PORT, "l-interface-id");
-        result.put(VG, "volume-group-id");
-        result.put(VLAN_TAG, "vlan-id");
-
-        return result;
+                .collect(toMap(Map.Entry::getKey, v -> ifTextualGetAsText(v.getValue())));
     }
 
-    private static HashMap<String, String> generateTypeToNameKeyMap() {
-        HashMap<String, String> result = new HashMap<>();
-        result.put(SERVICE_INSTANCE, "service-instance-name");
-        result.put(GENERIC_VNF, "vnf-name");
-        result.put(NETWORK, "network-name");
-        result.put(COLLECTION_RESOURCE, "collection-name");
-        result.put(CONFIGURATION, "configuration-name");
-        result.put(PNF, "pnf-name");
-        result.put(VF_MODULE, "vf-module-name");
-        result.put(INSTANCE_GROUP, "instance-group-name");
-        result.put(PORT, "l-interface-name");
-        result.put(VG, "volume-group-name");
-        result.put(VLAN_TAG, "vlan-name");
-
-        return result;
+    private Object ifTextualGetAsText(JsonNode jsonNode) {
+        return jsonNode.isTextual() ? jsonNode.asText() : jsonNode;
     }
-}
+}
\ No newline at end of file