Fix Sonar bugs in Dublin code 28/82428/1
authormark.j.leonard <mark.j.leonard@gmail.com>
Fri, 15 Mar 2019 14:23:37 +0000 (14:23 +0000)
committermark.j.leonard <mark.j.leonard@gmail.com>
Fri, 15 Mar 2019 14:31:08 +0000 (14:31 +0000)
Address issues arising from AAI-2089 and AAI-1957.
Fix 9 bugs relating to null pointer exceptions.
Reduce the calculated complexity of the GizmoTranslator method
generateModelElementId() by reimplementing using Streams.

Change-Id: Ic7983db1e9364d79ff79deb09552028501bbbf2c
Issue-ID: AAI-2264
Signed-off-by: mark.j.leonard <mark.j.leonard@gmail.com>
src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java
src/main/java/org/onap/aai/modelloader/util/GizmoTranslator.java

index b9cd193..7523fce 100644 (file)
@@ -2,8 +2,8 @@
  * ============LICENSE_START=======================================================
  * org.onap.aai
  * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * Copyright © 2017-2018 European Software Marketing Ltd.
+ * Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright (c) 2017-2019 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.
@@ -18,6 +18,7 @@
  * limitations under the License.
  * ============LICENSE_END=========================================================
  */
+
 package org.onap.aai.modelloader.config;
 
 import java.io.File;
@@ -26,7 +27,6 @@ import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Properties;
-
 import org.apache.commons.lang3.StringUtils;
 import org.eclipse.jetty.util.security.Password;
 import org.onap.sdc.api.consumer.IConfiguration;
@@ -99,8 +99,8 @@ public class ModelLoaderConfig implements IConfiguration {
     private static String configHome;
     private Properties modelLoaderProperties = null;
     private String certLocation = ".";
-    private List<String> artifactTypes = null;
-    private List<String> msgBusAddrs = null;
+    private List<String> artifactTypes = new ArrayList<>();
+    private List<String> msgBusAddrs = new ArrayList<>();
     private String modelVersion = null;
 
     public ModelLoaderConfig(Properties configProperties) {
@@ -111,28 +111,26 @@ public class ModelLoaderConfig implements IConfiguration {
      * Original constructor
      *
      * @param modelLoaderProperties
-     *        properties needed to be configured for the model loader
+     *            properties needed to be configured for the model loader
      * @param certLocation
-     *        location of the certificate
+     *            location of the certificate
      */
     public ModelLoaderConfig(Properties modelLoaderProperties, String certLocation) {
         this.modelLoaderProperties = modelLoaderProperties;
         this.certLocation = certLocation;
 
-        // Get list of artifacts
-        artifactTypes = new ArrayList<>();
-        if (get(PROP_ML_DISTRIBUTION_ARTIFACT_TYPES) != null) {
-            String[] artTypeList = get(PROP_ML_DISTRIBUTION_ARTIFACT_TYPES).split(",");
-            for (String artType : artTypeList) {
+        // Get list of artifact types
+        String types = get(PROP_ML_DISTRIBUTION_ARTIFACT_TYPES);
+        if (types != null) {
+            for (String artType : types.split(",")) {
                 artifactTypes.add(artType);
             }
         }
 
         // Get list of message bus addresses
-        msgBusAddrs = new ArrayList<>();
-        if (get(PROP_ML_DISTRIBUTION_MSG_BUS_ADDRESSES) != null) {
-            String[] msgBusList = get(PROP_ML_DISTRIBUTION_MSG_BUS_ADDRESSES).split(",");
-            for (String addr : msgBusList) {
+        String addresses = get(PROP_ML_DISTRIBUTION_MSG_BUS_ADDRESSES);
+        if (addresses != null) {
+            for (String addr : addresses.split(",")) {
                 msgBusAddrs.add(addr);
             }
         }
@@ -271,15 +269,15 @@ public class ModelLoaderConfig implements IConfiguration {
 
     public String getAaiModelUrl(String version) {
         setModelVersion(version);
-        return updatePropertyOXMVersion(modelLoaderProperties, PROP_AAI_MODEL_RESOURCE_URL, version);
+        return updatePropertyOXMVersion(PROP_AAI_MODEL_RESOURCE_URL, version);
     }
 
     public String getAaiNamedQueryUrl(String version) {
-        return updatePropertyOXMVersion(modelLoaderProperties, PROP_AAI_NAMED_QUERY_RESOURCE_URL, version);
+        return updatePropertyOXMVersion(PROP_AAI_NAMED_QUERY_RESOURCE_URL, version);
     }
 
     public String getAaiVnfImageUrl() {
-        return updatePropertyOXMVersion(modelLoaderProperties, PROP_AAI_VNF_IMAGE_RESOURCE_URL, getModelVersion());
+        return updatePropertyOXMVersion(PROP_AAI_VNF_IMAGE_RESOURCE_URL, getModelVersion());
     }
 
     public String getAaiAuthenticationUser() {
@@ -321,13 +319,20 @@ public class ModelLoaderConfig implements IConfiguration {
     }
 
     /**
-     * @return a String value of the defined property with the oxm version
+     * Read the value of the property and replace any wildcard OXM version "v*" with the supplied default OXM version
+     * 
+     * @param propertyName
+     *            the name of the property storing the OXM version (possibly containing v*)
+     * @param version
+     *            the default OXM version
+     * @return the String value of the defined property (with any wildcard OXM version defaulted)
      */
-    private String updatePropertyOXMVersion(Properties modelLoaderProperties, String propertyName, String version) {
-        if (version != null)
-            return get(propertyName).replace("v*", version);
-        else
-            return get(propertyName);
+    private String updatePropertyOXMVersion(String propertyName, String version) {
+        String value = get(propertyName);
+        if (version != null && value != null) {
+            value = value.replace("v*", version);
+        }
+        return value;
     }
 
     /**
@@ -336,22 +341,19 @@ public class ModelLoaderConfig implements IConfiguration {
     public boolean getASDCConnectionDisabled() {
         String propValue = get(PROP_ML_DISTRIBUTION_ASDC_CONNECTION_DISABLED);
         return propValue != null && "true".equalsIgnoreCase(propValue);
-
     }
 
     private String getDeobfuscatedValue(String property) {
-        if (property.startsWith("OBF:")) {
+        if (property != null && property.startsWith("OBF:")) {
             return Password.deobfuscate(property);
         }
-
-        // Property is not obfuscated
         return property;
     }
 
     private String get(String key) {
         String value = modelLoaderProperties.getProperty(key);
 
-        if(value!= null && value.startsWith("ENV:")) {
+        if (value != null && value.startsWith("ENV:")) {
             value = System.getenv(StringUtils.removeStart(value, "ENV:"));
         }
         return value;
index 2f4469f..a8c5d17 100644 (file)
@@ -2,14 +2,14 @@
  * ============LICENSE_START==========================================
  * org.onap.aai
  * ===================================================================
- * Copyright Â© 2017-2018 AT&T Intellectual Property. All rights reserved.
- * Copyright Â© 2017-2018 Amdocs
+ * Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright (c) 2017-2019 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
+ *       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,
  * limitations under the License.
  * ============LICENSE_END============================================
  */
+
 package org.onap.aai.modelloader.util;
 
 import java.io.IOException;
 import java.io.StringReader;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.ParserConfigurationException;
@@ -46,25 +51,14 @@ import org.xml.sax.SAXException;
 public class GizmoTranslator {
 
     private enum NodeType {
-        VERTEX,
-        ATTRIBUTE,
-        CONTAINER,
-        RELATIONSHIP_LIST,
-        RELATIONSHIP,
-        RELATED_TO,
-        RELATIONSHIP_DATA,
-        RELATIONSHIP_KEY,
-        RELATIONSHIP_VALUE,
-        MODEL_ELEMENT_VERTEX,
-        NQ_ELEMENT_VERTEX,
-        UNKNOWN
+        VERTEX, ATTRIBUTE, CONTAINER, RELATIONSHIP_LIST, RELATIONSHIP, RELATED_TO, RELATIONSHIP_DATA, RELATIONSHIP_KEY, RELATIONSHIP_VALUE, MODEL_ELEMENT_VERTEX, NQ_ELEMENT_VERTEX, UNKNOWN
     }
 
     private static Logger logger = LoggerFactory.getInstance().getLogger(GizmoTranslator.class.getName());
 
     public static String translate(String xmlPayload) throws ParserConfigurationException, SAXException, IOException {
         logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Process XML model artifact: " + xmlPayload);
-        
+
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
         factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
         DocumentBuilder builder = factory.newDocumentBuilder();
@@ -78,7 +72,8 @@ public class GizmoTranslator {
         return gizmoPayload.toJson();
     }
 
-    private static void processNode(Node node, Node parentNode, GizmoVertexOperation parentVertexOp, GizmoBulkPayload gizmoPayload) {
+    private static void processNode(Node node, Node parentNode, GizmoVertexOperation parentVertexOp,
+            GizmoBulkPayload gizmoPayload) {
         if (!(node instanceof Element)) {
             return;
         }
@@ -87,23 +82,23 @@ public class GizmoTranslator {
         NodeType nodeType = getNodeType(node);
 
         switch (nodeType) {
-        case VERTEX:
-        case MODEL_ELEMENT_VERTEX:
-        case NQ_ELEMENT_VERTEX:
-            parentVertexOp = createGizmoVertexOp(node, GizmoBulkPayload.ADD_OP);
-            gizmoPayload.addVertexOperation(parentVertexOp);
-            if (parentNode != null) {
-                gizmoPayload.addEdgeOperation(createGizmoEdgeOp(node, parentNode));
-            }
-            newParent = node;
-            break;
-        case RELATIONSHIP:
-            processRelationship((Element)node, parentVertexOp, gizmoPayload);
-            newParent = parentNode;
-            break;
-        default:
-            newParent = parentNode;
-            break;
+            case VERTEX:
+            case MODEL_ELEMENT_VERTEX:
+            case NQ_ELEMENT_VERTEX:
+                parentVertexOp = createGizmoVertexOp(node, GizmoBulkPayload.ADD_OP);
+                gizmoPayload.addVertexOperation(parentVertexOp);
+                if (parentNode != null) {
+                    gizmoPayload.addEdgeOperation(createGizmoEdgeOp(node, parentNode));
+                }
+                newParent = node;
+                break;
+            case RELATIONSHIP:
+                processRelationship((Element) node, parentVertexOp, gizmoPayload);
+                newParent = parentNode;
+                break;
+            default:
+                newParent = parentNode;
+                break;
         }
 
         NodeList childNodes = node.getChildNodes();
@@ -112,7 +107,8 @@ public class GizmoTranslator {
         }
     }
 
-    private static void processRelationship(Element relationshipNode, GizmoVertexOperation sourceNode, GizmoBulkPayload gizmoPayload) {
+    private static void processRelationship(Element relationshipNode, GizmoVertexOperation sourceNode,
+            GizmoBulkPayload gizmoPayload) {
         NodeList relatedToList = relationshipNode.getElementsByTagName("related-to");
         if (relatedToList.getLength() != 1) {
             logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Unable to resolve relationship");
@@ -124,12 +120,13 @@ public class GizmoTranslator {
 
         NodeList relationData = relationshipNode.getElementsByTagName("relationship-data");
         for (int ix = 0; ix < relationData.getLength(); ix++) {
-            Element relationNode = (Element)relationData.item(ix);
+            Element relationNode = (Element) relationData.item(ix);
             NodeList keyList = relationNode.getElementsByTagName("relationship-key");
             NodeList valueList = relationNode.getElementsByTagName("relationship-value");
 
-            if ( (keyList.getLength() != 1) || (valueList.getLength() != 1) ) {
-                logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Unable to resolve relationship.  Missing key/value.");
+            if ((keyList.getLength() != 1) || (valueList.getLength() != 1)) {
+                logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+                        "Unable to resolve relationship.  Missing key/value.");
                 return;
             }
 
@@ -141,14 +138,16 @@ public class GizmoTranslator {
             }
         }
 
-        gizmoPayload.addVertexOperation(new GizmoVertexOperation(GizmoBulkPayload.EXISTS_OP, getVertexId(targetVertex), targetVertex));
+        gizmoPayload.addVertexOperation(
+                new GizmoVertexOperation(GizmoBulkPayload.EXISTS_OP, getVertexId(targetVertex), targetVertex));
 
         GizmoEdge edge = new GizmoEdge();
 
         edge.setSource("$" + getVertexId(sourceNode.getVertex()));
         edge.setTarget("$" + getVertexId(targetVertex));
 
-        gizmoPayload.addEdgeOperation(new GizmoEdgeOperation(GizmoBulkPayload.ADD_OP, edge.getSource() + "_" + edge.getTarget(), edge));
+        gizmoPayload.addEdgeOperation(
+                new GizmoEdgeOperation(GizmoBulkPayload.ADD_OP, edge.getSource() + "_" + edge.getTarget(), edge));
     }
 
     private static GizmoEdgeOperation createGizmoEdgeOp(Node node, Node parentNode) {
@@ -183,18 +182,19 @@ public class GizmoTranslator {
 
         for (int ix = 0; ix < childNodes.getLength(); ix++) {
             if (getNodeType(childNodes.item(ix)).equals(NodeType.ATTRIBUTE)) {
-                vertex.setProperty(childNodes.item(ix).getNodeName().trim(), childNodes.item(ix).getTextContent().trim());
+                vertex.setProperty(childNodes.item(ix).getNodeName().trim(),
+                        childNodes.item(ix).getTextContent().trim());
             }
         }
 
         // Special case for model-element, where we need to generate an id field
         if (getNodeType(node).equals(NodeType.MODEL_ELEMENT_VERTEX)) {
-            vertex.setProperty("model-element-uuid", generateModelElementId((Element)node));
+            vertex.setProperty("model-element-uuid", generateModelElementId((Element) node));
         }
 
         // Special case for nq-element, where we need to generate an id field
         if (getNodeType(node).equals(NodeType.NQ_ELEMENT_VERTEX)) {
-            vertex.setProperty("named-query-element-uuid", generateModelElementId((Element)node));
+            vertex.setProperty("named-query-element-uuid", generateModelElementId((Element) node));
         }
 
         return vertex;
@@ -202,37 +202,36 @@ public class GizmoTranslator {
 
     // Generate a unique hash to store as the id for this node
     private static String generateModelElementId(Element node) {
-        Set<String> elemSet = new HashSet<>();
-
         // Get the parent model version / named query version
-        String parentVersion = null;
+        Optional<String> parentVersion = Optional.empty();
+
         Node parentNode = node.getParentNode();
-        while ( (parentNode != null) && (parentVersion == null) ) {
-            if (getNodeType(parentNode).equals(NodeType.VERTEX)) {
-                NodeList childNodes = ((Element)parentNode).getElementsByTagName("*");
-                for (int ix = 0; ix < childNodes.getLength(); ix++) {
-                    if (childNodes.item(ix).getNodeName().equalsIgnoreCase("named-query-uuid") || 
-                            childNodes.item(ix).getNodeName().equalsIgnoreCase("model-version-id")) {
-                        parentVersion = childNodes.item(ix).getTextContent().trim();
-                        break;
-                    }
-                }
+        while (parentNode != null && !parentVersion.isPresent()) {
+            if (getNodeType(parentNode) == NodeType.VERTEX) {
+                NodeList childNodes = ((Element) parentNode).getElementsByTagName("*");
+                parentVersion = IntStream.range(0, childNodes.getLength()) //
+                        .mapToObj(childNodes::item) //
+                        .filter(child -> child.getNodeName().equalsIgnoreCase("named-query-uuid")
+                                || child.getNodeName().equalsIgnoreCase("model-version-id")) //
+                        .map(child -> child.getTextContent().trim()) //
+                        .findFirst();
             }
-            
             parentNode = parentNode.getParentNode();
         }
-        
-        if (parentVersion != null) {
-            elemSet.add(parentVersion);
-        }
-        
+
+        Set<String> elemSet = new HashSet<>();
+        parentVersion.ifPresent(elemSet::add);
+
+        Set<NodeType> validNodeTypes = //
+                Stream.of(NodeType.ATTRIBUTE, NodeType.RELATIONSHIP_KEY, NodeType.RELATIONSHIP_VALUE)
+                        .collect(Collectors.toSet());
+
         NodeList childNodes = node.getElementsByTagName("*");
-        for (int ix = 0; ix < childNodes.getLength(); ix++) {
-            NodeType nt = getNodeType(childNodes.item(ix));
-            if ( nt.equals(NodeType.ATTRIBUTE) || nt.equals(NodeType.RELATIONSHIP_KEY) || nt.equals(NodeType.RELATIONSHIP_VALUE) ) {
-                elemSet.add(childNodes.item(ix).getTextContent().trim());
-            }
-        }
+        IntStream.range(0, childNodes.getLength()) //
+                .mapToObj(childNodes::item) //
+                .filter(child -> validNodeTypes.contains(getNodeType(child))) //
+                .map(child -> child.getTextContent().trim()) //
+                .forEachOrdered(elemSet::add);
 
         return Integer.toString(elemSet.hashCode());
     }
@@ -277,7 +276,7 @@ public class GizmoTranslator {
         NodeList childNodes = node.getChildNodes();
         int childElements = countChildElements(childNodes);
 
-        if ( (childElements == 0) && (node.getTextContent() != null) && (!node.getTextContent().trim().isEmpty()) ) {
+        if ((childElements == 0) && (node.getTextContent() != null) && (!node.getTextContent().trim().isEmpty())) {
             return NodeType.ATTRIBUTE;
         }