Check getMetaData() return value for null 85/59485/1
authormark.j.leonard <mark.j.leonard@gmail.com>
Tue, 7 Aug 2018 15:43:55 +0000 (16:43 +0100)
committermark.j.leonard <mark.j.leonard@gmail.com>
Tue, 7 Aug 2018 15:48:52 +0000 (16:48 +0100)
Added code to check for null metadata.
Decomposed existing methods to avoid Sonar complexity warnings.
Renamed some variables for readability.

Change-Id: Id68be06bb5c105f45870a08f60a4ddc4dfbe5b09
Issue-ID: AAI-1448
Signed-off-by: mark.j.leonard <mark.j.leonard@gmail.com>
src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java
src/main/java/org/onap/aai/babel/parser/ArtifactGeneratorToscaParser.java
src/main/resources/babel-logging-resources.properties
src/test/java/org/onap/aai/babel/parser/TestArtifactGeneratorToscaParser.java [new file with mode: 0644]

index 84b426b..812c4c1 100644 (file)
@@ -37,7 +37,8 @@ public enum ApplicationMsgs implements LogMessageEnum {
   BABEL_RESPONSE_PAYLOAD,
   LOAD_PROPERTIES,
   PROCESSING_VNF_CATALOG_ERROR,
-  TEMP_FILE_ERROR;
+  TEMP_FILE_ERROR,
+  MISSING_SERVICE_METADATA;
     
   // @formatter:on
 
index a95df94..2421d68 100644 (file)
@@ -29,6 +29,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.stream.Collectors;
+import org.onap.aai.babel.logging.ApplicationMsgs;
 import org.onap.aai.babel.logging.LogHelper;
 import org.onap.aai.babel.xml.generator.data.WidgetConfigurationUtil;
 import org.onap.aai.babel.xml.generator.model.AllotedResource;
@@ -46,6 +47,7 @@ import org.onap.sdc.tosca.parser.api.ISdcCsarHelper;
 import org.onap.sdc.toscaparser.api.Group;
 import org.onap.sdc.toscaparser.api.NodeTemplate;
 import org.onap.sdc.toscaparser.api.Property;
+import org.onap.sdc.toscaparser.api.elements.Metadata;
 
 public class ArtifactGeneratorToscaParser {
 
@@ -119,6 +121,39 @@ public class ArtifactGeneratorToscaParser {
         }
     }
 
+    /**
+     * Process the service TOSCA.
+     *
+     * @param service model of the service artifact
+     * @param idTypeStore ID->Type mapping
+     * @param nodeTemplates a list of service nodes
+     *
+     */
+    public void processServiceTosca(Service service, Map<String, String> idTypeStore,
+            List<NodeTemplate> nodeTemplates) {
+        log.debug("Inside Service Tosca ");
+
+        // Get the resource/widgets in the service according to the node-template types
+        for (NodeTemplate node : nodeTemplates) {
+            if (node.getMetaData() != null) {
+                Model model = Model.getModelFor(correctNodeType(node));
+                if (model != null) {
+                    model.populateModelIdentificationInformation(node.getMetaData().getAllProperties());
+                    if (model instanceof Resource) {
+                        // Keeping track of resource types and
+                        // their uuid for identification during resource tosca processing
+                        idTypeStore.put(model.getModelNameVersionId(), correctNodeType(node));
+                        service.addResource((Resource) model);
+                    } else {
+                        service.addWidget((Widget) model);
+                    }
+                }
+            } else {
+                log.warn(ApplicationMsgs.MISSING_SERVICE_METADATA, node.getName());
+            }
+        }
+    }
+
     /**
      * Generates a Resource List using input Service Node Templates.
      *
@@ -129,50 +164,55 @@ public class ArtifactGeneratorToscaParser {
     public List<Resource> processResourceToscas(List<NodeTemplate> serviceNodes, Map<String, String> idTypeStore) {
         List<Resource> resources = new LinkedList<>();
         for (NodeTemplate serviceNode : serviceNodes) {
-            List<NodeTemplate> resourceNodes = csarHelper.getNodeTemplateChildren(serviceNode);
+            if (serviceNode.getMetaData() != null) {
+                List<NodeTemplate> resourceNodes = csarHelper.getNodeTemplateChildren(serviceNode);
+                processResourceTosca(idTypeStore, resources, serviceNode, resourceNodes);
+            } else {
+                log.warn(ApplicationMsgs.MISSING_SERVICE_METADATA, serviceNode.getName());
+            }
+        }
+        return resources;
+    }
 
-            String resourceUuId = serviceNode.getMetaData().getValue("UUID");
-            String mapValue = idTypeStore.get(resourceUuId);
-            if (mapValue != null) {
-                Model model = Model.getModelFor(idTypeStore.get(serviceNode.getMetaData().getValue("UUID")));
+    private void processResourceTosca(Map<String, String> idTypeStore, List<Resource> resources,
+            NodeTemplate serviceNode, List<NodeTemplate> resourceNodes) {
+        String resourceUuId = serviceNode.getMetaData().getValue("UUID");
+        String resourceType = idTypeStore.get(resourceUuId);
+        if (resourceType != null) {
+            Model model = Model.getModelFor(resourceType);
 
-                log.debug("Inside Resource artifact generation for resource");
-                Map<String, String> serviceMetadata = serviceNode.getMetaData().getAllProperties();
-                model.populateModelIdentificationInformation(serviceMetadata);
+            log.debug("Inside Resource artifact generation for resource");
+            Map<String, String> serviceMetadata = serviceNode.getMetaData().getAllProperties();
+            model.populateModelIdentificationInformation(serviceMetadata);
 
-                // Found model from the type store so removing the same
-                idTypeStore.remove(model.getModelNameVersionId());
-                processVfTosca(idTypeStore, model, resourceNodes);
+            // Found model from the type store so removing the same
+            idTypeStore.remove(model.getModelNameVersionId());
+            processVfTosca(idTypeStore, model, resourceNodes);
 
-                // Process group information from tosca for vfModules
-                if (csarHelper.getServiceVfList() != null) {
-                    processVfModules(resources, model, serviceNode);
-                }
+            // Process group information from tosca for vfModules
+            if (csarHelper.getServiceVfList() != null) {
+                processVfModules(resources, model, serviceNode);
+            }
 
-                if (hasSubCategoryTunnelXConnect(serviceMetadata) && hasAllottedResource(serviceMetadata)) {
-                    model.addWidget(new TunnelXconnectWidget());
-                }
-                resources.add((Resource) model);
+            if (hasSubCategoryTunnelXConnect(serviceMetadata) && hasAllottedResource(serviceMetadata)) {
+                model.addWidget(new TunnelXconnectWidget());
             }
+            resources.add((Resource) model);
         }
-        return resources;
     }
 
-    private void processVfModules(List<Resource> resources, Model model, NodeTemplate serviceNode) {
+    private void processVfModules(List<Resource> resources, Model resourceModel, NodeTemplate serviceNode) {
         // Get the customisation UUID for each VF node and use it to get its Groups
         String uuid = csarHelper.getNodeTemplateCustomizationUuid(serviceNode);
-
-        // Populate a Map of Group against NodeTemplates that are members of the Group
         List<Group> serviceGroups = csarHelper.getVfModulesByVf(uuid);
 
         // Process each VF Group
         for (Group serviceGroup : serviceGroups) {
             Model groupModel = Model.getModelFor(serviceGroup.getType());
             if (groupModel instanceof VfModule) {
-                processVfModule(resources, model, serviceGroup, serviceNode, (VfModule) groupModel);
+                processVfModule(resources, resourceModel, serviceGroup, serviceNode, (VfModule) groupModel);
             }
         }
-
     }
 
     private void processVfModule(List<Resource> resources, Model model, Group groupDefinition, NodeTemplate serviceNode,
@@ -183,18 +223,14 @@ public class ArtifactGeneratorToscaParser {
         Map<String, Property> groupProperties = groupDefinition.getProperties();
         Map<String, String> properties = populateStringProperties(groupProperties);
         groupModel.populateModelIdentificationInformation(properties);
-        processVfModuleGroup(resources, model, groupDefinition, serviceNode, groupModel);
-    }
 
-    private void processVfModuleGroup(List<Resource> resources, Model model, Group groupDefinition,
-            NodeTemplate serviceNode, VfModule groupModel) {
         // Get names of the members of the service group
         List<NodeTemplate> members = csarHelper.getMembersOfVfModule(serviceNode, groupDefinition);
         if (members != null && !members.isEmpty()) {
             List<String> memberNames = members.stream().map(NodeTemplate::getName).collect(Collectors.toList());
             groupModel.setMembers(memberNames);
-            for (NodeTemplate nodeTemplate : members) {
-                processNodeTemplate(groupModel, nodeTemplate);
+            for (NodeTemplate member : members) {
+                processGroupMembers(groupModel, member);
             }
         }
 
@@ -205,53 +241,26 @@ public class ArtifactGeneratorToscaParser {
         }
     }
 
-    private static void processNodeTemplate(Model group, NodeTemplate nodeTemplate) {
+    private void processGroupMembers(Model group, NodeTemplate member) {
         Model resourceNode;
         // L3-network inside vf-module to be generated as Widget a special handling.
-        if (nodeTemplate.getType().contains("org.openecomp.resource.vl")) {
+        if (member.getType().contains("org.openecomp.resource.vl")) {
             resourceNode = new L3NetworkWidget();
         } else {
-            resourceNode = Model.getModelFor(nodeTemplate.getType());
+            resourceNode = Model.getModelFor(member.getType());
         }
         if (resourceNode != null && !(resourceNode instanceof Resource)) {
             Widget widget = (Widget) resourceNode;
-            widget.addKey(nodeTemplate.getName());
+            widget.addKey(member.getName());
             // Add the widget element encountered to the Group model
             group.addWidget(widget);
         }
     }
 
-    /**
-     * Process the service tosca
-     *
-     * @param service model of the service artifact
-     * @param idTypeStore ID->Type mapping
-     * @param nodeTemplates a list of service nodes
-     *
-     */
-    public void processServiceTosca(Service service, Map<String, String> idTypeStore,
-            List<NodeTemplate> nodeTemplates) {
-        log.debug("Inside Service Tosca ");
-        // Get the resource/widgets in the service according to the node-template types
-        for (NodeTemplate node : nodeTemplates) {
-            Model model = Model.getModelFor(correctNodeType(node));
-            if (model != null) {
-                model.populateModelIdentificationInformation(node.getMetaData().getAllProperties());
-                if (model instanceof Resource) {
-                    // Keeping track of resource types and
-                    // their uuid for identification during resource tosca processing
-                    idTypeStore.put(model.getModelNameVersionId(), correctNodeType(node));
-                    service.addResource((Resource) model);
-                } else {
-                    service.addWidget((Widget) model);
-                }
-            }
-        }
-    }
-
     private String correctNodeType(NodeTemplate nodeType) {
         String correctedNodeType = nodeType.getType();
-        if (hasAllottedResource(nodeType.getMetaData().getAllProperties())) {
+        Metadata metadata = nodeType.getMetaData();
+        if (metadata != null && hasAllottedResource(metadata.getAllProperties())) {
             if (nodeType.getType().contains("org.openecomp.resource.vf.")) {
                 correctedNodeType = "org.openecomp.resource.vf.allottedResource";
             }
@@ -281,32 +290,33 @@ public class ArtifactGeneratorToscaParser {
                 e -> e.getValue().getValue() == null ? "" : e.getValue().getValue().toString()));
     }
 
-    private void processVfTosca(Map<String, String> idTypeStore, Model model, List<NodeTemplate> resourceNodes) {
-        boolean flag = false;
+    private void processVfTosca(Map<String, String> idTypeStore, Model resourceModel,
+            List<NodeTemplate> resourceNodes) {
+        boolean providingServiceFound = false;
 
         for (NodeTemplate resourceNodeTemplate : resourceNodes) {
             Model resourceNode = Model.getModelFor(correctNodeType(resourceNodeTemplate));
             if (resourceNode instanceof ProvidingService) {
-                flag = true;
+                providingServiceFound = true;
                 Map<String, Property> nodeProperties = resourceNodeTemplate.getProperties();
                 if (nodeProperties.get("providing_service_uuid") == null
                         || nodeProperties.get("providing_service_invariant_uuid") == null) {
-                    throw new IllegalArgumentException(
-                            String.format(GENERATOR_AAI_PROVIDING_SERVICE_METADATA_MISSING, model.getModelId()));
+                    throw new IllegalArgumentException(String.format(GENERATOR_AAI_PROVIDING_SERVICE_METADATA_MISSING,
+                            resourceModel.getModelId()));
                 }
                 Map<String, String> properties = populateStringProperties(nodeProperties);
                 properties.put(VERSION, "1.0");
                 resourceNode.populateModelIdentificationInformation(properties);
-                model.addResource((Resource) resourceNode);
+                resourceModel.addResource((Resource) resourceNode);
             } else if (resourceNode instanceof Resource && !(resourceNode.getWidgetType().equals(Widget.Type.L3_NET))) {
                 idTypeStore.put(resourceNode.getModelNameVersionId(), correctNodeType(resourceNodeTemplate));
-                model.addResource((Resource) resourceNode);
+                resourceModel.addResource((Resource) resourceNode);
             }
         }
 
-        if (model instanceof AllotedResource && !flag) {
+        if (resourceModel instanceof AllotedResource && !providingServiceFound) {
             throw new IllegalArgumentException(
-                    String.format(GENERATOR_AAI_PROVIDING_SERVICE_MISSING, model.getModelId()));
+                    String.format(GENERATOR_AAI_PROVIDING_SERVICE_MISSING, resourceModel.getModelId()));
         }
     }
 }
index 99b2294..5213103 100644 (file)
@@ -76,10 +76,12 @@ BABEL_REQUEST_PAYLOAD=\
                   
 BABEL_RESPONSE_PAYLOAD=\
                                  BABEL0009I|\
-                  Babel response payload: {0}|\      
+                  Babel response payload: {0}|\
     
 MISSING_REQUEST_ID=\
                            BABEL0010I|\
                            Missing request ID. Assigned {0}|\
-                           |\
-    
\ No newline at end of file
+                           
+MISSING_SERVICE_METADATA=\
+                           BABEL0011W|\
+                The service node template: {0} does not provide a metadata section. Skipping...|\
\ No newline at end of file
diff --git a/src/test/java/org/onap/aai/babel/parser/TestArtifactGeneratorToscaParser.java b/src/test/java/org/onap/aai/babel/parser/TestArtifactGeneratorToscaParser.java
new file mode 100644 (file)
index 0000000..a74efaf
--- /dev/null
@@ -0,0 +1,56 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 European Software Marketing Ltd.
+ * ================================================================================
+ * 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.aai.babel.parser;
+
+import java.util.Collections;
+import java.util.LinkedHashMap;
+import java.util.List;
+import org.junit.Test;
+import org.onap.sdc.toscaparser.api.NodeTemplate;
+
+/**
+ * Direct tests of the TOSCA parser-based Artifact Generator, to cover exceptional cases.
+ */
+
+public class TestArtifactGeneratorToscaParser {
+
+    ArtifactGeneratorToscaParser parser = new ArtifactGeneratorToscaParser(null);
+
+    /**
+     * Process a dummy Node Template object for a Service. A WARNING should be logged for the missing metadata.
+     */
+    @Test
+    public void testMissingServiceData() {
+        List<NodeTemplate> nodeTemplateList = Collections.singletonList(buildNodeTemplate("name", "BlockStorage"));
+        parser.processServiceTosca(null, Collections.emptyMap(), nodeTemplateList);
+        parser.processResourceToscas(nodeTemplateList, null);
+    }
+
+    private NodeTemplate buildNodeTemplate(String name, String type) {
+        LinkedHashMap<String, Object> nodeTemplateMap = new LinkedHashMap<>();
+        LinkedHashMap<String, Object> template = new LinkedHashMap<>();
+        template.put("type", type);
+        nodeTemplateMap.put(name, template);
+        return new NodeTemplate(name, nodeTemplateMap, null, null, null);
+    }
+
+}