From a2c5714eabfb87d4a59f106e418c967b599c4212 Mon Sep 17 00:00:00 2001 From: "mark.j.leonard" Date: Tue, 7 Aug 2018 16:43:55 +0100 Subject: [PATCH] Check getMetaData() return value for null 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 --- .../onap/aai/babel/logging/ApplicationMsgs.java | 3 +- .../babel/parser/ArtifactGeneratorToscaParser.java | 156 +++++++++++---------- .../resources/babel-logging-resources.properties | 8 +- .../parser/TestArtifactGeneratorToscaParser.java | 56 ++++++++ 4 files changed, 146 insertions(+), 77 deletions(-) create mode 100644 src/test/java/org/onap/aai/babel/parser/TestArtifactGeneratorToscaParser.java diff --git a/src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java b/src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java index 84b426b..812c4c1 100644 --- a/src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java +++ b/src/main/java/org/onap/aai/babel/logging/ApplicationMsgs.java @@ -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 diff --git a/src/main/java/org/onap/aai/babel/parser/ArtifactGeneratorToscaParser.java b/src/main/java/org/onap/aai/babel/parser/ArtifactGeneratorToscaParser.java index a95df94..2421d68 100644 --- a/src/main/java/org/onap/aai/babel/parser/ArtifactGeneratorToscaParser.java +++ b/src/main/java/org/onap/aai/babel/parser/ArtifactGeneratorToscaParser.java @@ -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 idTypeStore, + List 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 processResourceToscas(List serviceNodes, Map idTypeStore) { List resources = new LinkedList<>(); for (NodeTemplate serviceNode : serviceNodes) { - List resourceNodes = csarHelper.getNodeTemplateChildren(serviceNode); + if (serviceNode.getMetaData() != null) { + List 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 idTypeStore, List resources, + NodeTemplate serviceNode, List 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 serviceMetadata = serviceNode.getMetaData().getAllProperties(); - model.populateModelIdentificationInformation(serviceMetadata); + log.debug("Inside Resource artifact generation for resource"); + Map 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 resources, Model model, NodeTemplate serviceNode) { + private void processVfModules(List 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 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 resources, Model model, Group groupDefinition, NodeTemplate serviceNode, @@ -183,18 +223,14 @@ public class ArtifactGeneratorToscaParser { Map groupProperties = groupDefinition.getProperties(); Map properties = populateStringProperties(groupProperties); groupModel.populateModelIdentificationInformation(properties); - processVfModuleGroup(resources, model, groupDefinition, serviceNode, groupModel); - } - private void processVfModuleGroup(List resources, Model model, Group groupDefinition, - NodeTemplate serviceNode, VfModule groupModel) { // Get names of the members of the service group List members = csarHelper.getMembersOfVfModule(serviceNode, groupDefinition); if (members != null && !members.isEmpty()) { List 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 idTypeStore, - List 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 idTypeStore, Model model, List resourceNodes) { - boolean flag = false; + private void processVfTosca(Map idTypeStore, Model resourceModel, + List resourceNodes) { + boolean providingServiceFound = false; for (NodeTemplate resourceNodeTemplate : resourceNodes) { Model resourceNode = Model.getModelFor(correctNodeType(resourceNodeTemplate)); if (resourceNode instanceof ProvidingService) { - flag = true; + providingServiceFound = true; Map 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 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())); } } } diff --git a/src/main/resources/babel-logging-resources.properties b/src/main/resources/babel-logging-resources.properties index 99b2294..5213103 100644 --- a/src/main/resources/babel-logging-resources.properties +++ b/src/main/resources/babel-logging-resources.properties @@ -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 index 0000000..a74efaf --- /dev/null +++ b/src/test/java/org/onap/aai/babel/parser/TestArtifactGeneratorToscaParser.java @@ -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 nodeTemplateList = Collections.singletonList(buildNodeTemplate("name", "BlockStorage")); + parser.processServiceTosca(null, Collections.emptyMap(), nodeTemplateList); + parser.processResourceToscas(nodeTemplateList, null); + } + + private NodeTemplate buildNodeTemplate(String name, String type) { + LinkedHashMap nodeTemplateMap = new LinkedHashMap<>(); + LinkedHashMap template = new LinkedHashMap<>(); + template.put("type", type); + nodeTemplateMap.put(name, template); + return new NodeTemplate(name, nodeTemplateMap, null, null, null); + } + +} -- 2.16.6