From e4cc64bb1b7c0acba0fe11160469c03b94bd5be2 Mon Sep 17 00:00:00 2001 From: "mark.j.leonard" Date: Mon, 10 Sep 2018 15:53:13 +0100 Subject: [PATCH] Add support for InstanceGroup resource models Generate models for Instance Groups (for specific supported types). Process groups with a metadata type of CR or Configuration. Add InstanceGroup Widget to the supported Widgets. Add support for a group filter properties resource/file (with the single property key "AAI.instance-group-types" which provides a comma-separated list of supported types). Add the System Propery groupfilter.config to define the file path. Change-Id: I6153e6284965c57ae43291b1dc3ee4a1d11e6583 Issue-ID: AAI-1579 Signed-off-by: mark.j.leonard --- README.md | 24 ++-- src/main/bin/start.sh | 6 +- .../babel/parser/ArtifactGeneratorToscaParser.java | 150 +++++++++++++++++---- .../xml/generator/api/AaiArtifactGenerator.java | 6 +- .../generator/data/WidgetConfigurationUtil.java | 15 +++ .../babel/xml/generator/model/InstanceGroup.java | 28 ++++ .../xml/generator/model/InstanceGroupWidget.java | 31 +++++ .../onap/aai/babel/xml/generator/model/Model.java | 25 +++- .../aai/babel/xml/generator/model/VfModule.java | 2 +- .../onap/aai/babel/xml/generator/model/Widget.java | 33 +++-- .../org/onap/aai/babel/parser/TestToscaParser.java | 4 + .../aai/babel/service/CsarToXmlConverterTest.java | 34 ++++- .../service/TestGenerateArtifactsServiceImpl.java | 19 ++- .../aai/babel/xml/generator/model/TestModel.java | 9 +- src/test/resources/artifact-generator.properties | 5 +- src/test/resources/filter-types.properties | 1 + 16 files changed, 323 insertions(+), 69 deletions(-) create mode 100644 src/main/java/org/onap/aai/babel/xml/generator/model/InstanceGroup.java create mode 100644 src/main/java/org/onap/aai/babel/xml/generator/model/InstanceGroupWidget.java create mode 100644 src/test/resources/filter-types.properties diff --git a/README.md b/README.md index 9943c93..30f2dec 100644 --- a/README.md +++ b/README.md @@ -1,40 +1,36 @@ # ONAP aai/babel ## Introduction -Babel is a microservice in the AAI project that can be used by clients that work with TOSCA CSAR files. +Babel is a microservice in the AAI project which can be used by clients that work with TOSCA CSAR files. -It parses the TOSCA CSAR to generate xml files from a set of YAML files found in the TOSCA CSAR file. +It parses TOSCA YAML files extracted from a CSAR payload and generates XML files containing AAI Model data. -## Compiling Babel -Babel service can be compiled easily using maven command `mvn clean install` +## Building Babel +The Babel service can be built with Maven, e.g. by issuing the command `mvn clean install` -The compiled results will be the following artifacts in the "target" folder: +Maven will produce the following artifacts in the "target" folder: -* babel_v{major-version}.zip -* babel_v{major-version}_props.zip -* babel-{version}.jar -* babel-{version}-client.jar -* babel-{version}-runtimeEnvironment.zip +* babel.jar +* babel-client.jar * Dockerfile * start.sh Maven will install the following artifacts in the local repository: * babel-{version}.jar * babel-{version}-client.jar -* babel-{version}-runtimeEnvironment.zip -Create the docker image: +To create the docker image run: docker build -t aai/babel target ## Babel Client -The project will build a client jar that can be used by clients when using the Babel service. +The project will build a client jar which can be used by clients invoking the Babel service. The client jar contains two objects that are used in the Babel service API. BabelRequest is used to supply the inputs into the Babel service. BabelArtifact is the response artifact in the list of artifacts returned from the Babel service. -### Deploying The Micro Service +### Deploying The Microservice Push the Docker image that you have built to your Docker repository and pull it down to the location that you will be running Babel from. diff --git a/src/main/bin/start.sh b/src/main/bin/start.sh index b91c396..c71acca 100644 --- a/src/main/bin/start.sh +++ b/src/main/bin/start.sh @@ -19,8 +19,7 @@ # limitations under the License. # ============LICENSE_END========================================================= -BASEDIR="/opt/app/babel" -APP_HOME="${BASEDIR}" +APP_HOME="${APP_HOME:-/opt/app/babel}" if [ -z "${CONFIG_HOME}" ]; then echo "CONFIG_HOME must be set in order to start up process" @@ -35,7 +34,8 @@ fi PROPS="-DAPP_HOME=${APP_HOME}" PROPS="${PROPS} -DCONFIG_HOME=${CONFIG_HOME}" PROPS="${PROPS} -Dartifactgenerator.config=${CONFIG_HOME}/artifact-generator.properties" +PROPS="${PROPS} -Dgroupfilter.config=${CONFIG_HOME}/filter-types.properties" PROPS="${PROPS} -DKEY_STORE_PASSWORD=${KEY_STORE_PASSWORD}" JVM_MAX_HEAP=${MAX_HEAP:-1024} -exec java -Xmx${JVM_MAX_HEAP}m ${PROPS} -jar ${APP_HOME}/babel.jar \ No newline at end of file +exec java -Xmx${JVM_MAX_HEAP}m ${PROPS} -jar ${APP_HOME}/babel.jar 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 24e8199..b85ffab 100644 --- a/src/main/java/org/onap/aai/babel/parser/ArtifactGeneratorToscaParser.java +++ b/src/main/java/org/onap/aai/babel/parser/ArtifactGeneratorToscaParser.java @@ -24,6 +24,7 @@ package org.onap.aai.babel.parser; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -33,6 +34,7 @@ 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; +import org.onap.aai.babel.xml.generator.model.InstanceGroup; import org.onap.aai.babel.xml.generator.model.L3NetworkWidget; import org.onap.aai.babel.xml.generator.model.Model; import org.onap.aai.babel.xml.generator.model.ProvidingService; @@ -54,11 +56,12 @@ public class ArtifactGeneratorToscaParser { private static Logger log = LogHelper.INSTANCE; public static final String PROPERTY_ARTIFACT_GENERATOR_CONFIG_FILE = "artifactgenerator.config"; + public static final String PROPERTY_GROUP_FILTERS_CONFIG_FILE = "groupfilter.config"; private static final String GENERATOR_AAI_CONFIGFILE_NOT_FOUND = "Cannot generate artifacts. Artifact Generator Configuration file not found at %s"; private static final String GENERATOR_AAI_CONFIGLOCATION_NOT_FOUND = - "Cannot generate artifacts. artifactgenerator.config system property not configured"; + "Cannot generate artifacts. System property %s not configured"; private static final String GENERATOR_AAI_PROVIDING_SERVICE_METADATA_MISSING = "Cannot generate artifacts. Providing Service Metadata is missing for allotted resource %s"; private static final String GENERATOR_AAI_PROVIDING_SERVICE_MISSING = @@ -117,7 +120,31 @@ public class ArtifactGeneratorToscaParser { throw new IllegalArgumentException(String.format(GENERATOR_AAI_CONFIGFILE_NOT_FOUND, configLocation)); } } else { - throw new IllegalArgumentException(GENERATOR_AAI_CONFIGLOCATION_NOT_FOUND); + throw new IllegalArgumentException( + String.format(GENERATOR_AAI_CONFIGLOCATION_NOT_FOUND, PROPERTY_ARTIFACT_GENERATOR_CONFIG_FILE)); + } + } + + /** + * Initialises the group filter configuration. + * + * @throws IOException + */ + public static void initGroupFilterConfiguration() throws IOException { + log.debug("Getting Filter Tyoes Configuration"); + String configLocation = System.getProperty(PROPERTY_GROUP_FILTERS_CONFIG_FILE); + if (configLocation != null) { + File file = new File(configLocation); + if (file.exists()) { + Properties properties = new Properties(); + properties.load(new FileInputStream(file)); + WidgetConfigurationUtil.setFilterConfig(properties); + } else { + throw new IllegalArgumentException(String.format(GENERATOR_AAI_CONFIGFILE_NOT_FOUND, configLocation)); + } + } else { + throw new IllegalArgumentException( + String.format(GENERATOR_AAI_CONFIGLOCATION_NOT_FOUND, PROPERTY_GROUP_FILTERS_CONFIG_FILE)); } } @@ -142,20 +169,20 @@ public class ArtifactGeneratorToscaParser { } } - /** * Generates a Resource List using input Service Node Templates. * * @param serviceNodes input Service Node Templates * @param idTypeStore ID->Type mapping + * * @return the processed resource models */ public List processResourceToscas(List serviceNodes, Map idTypeStore) { List resources = new LinkedList<>(); for (NodeTemplate serviceNode : serviceNodes) { if (serviceNode.getMetaData() != null) { - List resourceNodes = csarHelper.getNodeTemplateChildren(serviceNode); - processResourceTosca(idTypeStore, resources, serviceNode, resourceNodes); + resources.addAll(processResourceTosca(idTypeStore, serviceNode, + csarHelper.getNodeTemplateChildren(serviceNode))); } else { log.warn(ApplicationMsgs.MISSING_SERVICE_METADATA, serviceNode.getName()); } @@ -163,31 +190,96 @@ public class ArtifactGeneratorToscaParser { return resources; } - private void processResourceTosca(Map idTypeStore, List resources, - NodeTemplate serviceNode, List resourceNodes) { + /** + * @param idTypeStore ID->Type mapping + * @param serviceNode + * @param resourceNodes + * @return the processed resource models + */ + private List processResourceTosca(Map idTypeStore, NodeTemplate serviceNode, + List resourceNodes) { + List resources = new LinkedList<>(); String resourceUuId = serviceNode.getMetaData().getValue("UUID"); - String resourceType = idTypeStore.get(resourceUuId); - if (resourceType != null) { - Model model = Model.getModelFor(resourceType); + String nodeTypeName = idTypeStore.get(resourceUuId); + if (nodeTypeName != null) { + Model resourceModel = Model.getModelFor(nodeTypeName, serviceNode.getMetaData().getValue("type")); - log.debug("Inside Resource artifact generation for resource"); + log.debug("Processing resource " + nodeTypeName + ": " + resourceUuId); Map serviceMetadata = serviceNode.getMetaData().getAllProperties(); - model.populateModelIdentificationInformation(serviceMetadata); + resourceModel.populateModelIdentificationInformation(serviceMetadata); - // Found model from the type store so removing the same - idTypeStore.remove(model.getModelNameVersionId()); - processVfTosca(idTypeStore, model, resourceNodes); + idTypeStore.remove(resourceModel.getModelNameVersionId()); + processVfTosca(idTypeStore, resourceModel, resourceNodes); - // Process group information from tosca for vfModules if (csarHelper.getServiceVfList() != null) { - processVfModules(resources, model, serviceNode); + processVfModules(resources, resourceModel, serviceNode); } if (hasSubCategoryTunnelXConnect(serviceMetadata) && hasAllottedResource(serviceMetadata)) { - model.addWidget(new TunnelXconnectWidget()); + resourceModel.addWidget(new TunnelXconnectWidget()); + } + + resources.addAll(processInstanceGroups(resourceModel, serviceNode)); + resources.add((Resource) resourceModel); + } + return resources; + } + + /** + * Process groups for this service node, according to the defined filter. + * + * @param resourceModel + * @param serviceNode + * @return resources for which XML Models should be generated + */ + private List processInstanceGroups(Model resourceModel, NodeTemplate serviceNode) { + List resources = new ArrayList<>(); + if (csarHelper.getNodeTemplateByName(serviceNode.getName()).getSubMappingToscaTemplate() != null) { + List serviceGroups = csarHelper.getGroupsOfOriginOfNodeTemplate(serviceNode); + for (Group group : serviceGroups) { + if (WidgetConfigurationUtil.isSupportedInstanceGroup(group.getType())) { + resources.addAll(processInstanceGroup(resourceModel, group)); + } + } + } + return resources; + } + + /** + * Create an Instance Group Model for the supplied Service Group and relate this to the supplied resource Model. + * + * @param resourceModel the Resource node template Model + * @param group the Service Group + * @return the Instance Group and Member resource models + */ + private List processInstanceGroup(Model resourceModel, Group group) { + List resources = new ArrayList<>(); + + Resource groupModel = new InstanceGroup(); + groupModel.populateModelIdentificationInformation(group.getMetadata().getAllProperties()); + groupModel.populateModelIdentificationInformation(populateStringProperties(group.getProperties())); + + resourceModel.addResource(groupModel); + resources.add(groupModel); + + List members = group.getMemberNodes(); + if (members != null && !members.isEmpty()) { + for (NodeTemplate nodeTemplate : members) { + String nodeTypeName = normaliseNodeTypeName(nodeTemplate); + Model memberModel = Model.getModelFor(nodeTypeName, nodeTemplate.getMetaData().getValue("type")); + memberModel.populateModelIdentificationInformation(nodeTemplate.getMetaData().getAllProperties()); + if (memberModel instanceof Resource) { + log.debug("Generating grouped Resource " + nodeTypeName); + groupModel.addResource((Resource) memberModel); + resources.add((Resource) memberModel); + } else { + log.debug("Generating grouped Widget " + nodeTypeName); + groupModel.addWidget((Widget) memberModel); + } } - resources.add((Resource) model); } + + return resources; } /** @@ -200,7 +292,7 @@ public class ArtifactGeneratorToscaParser { */ private void addNodeToService(Map nodesById, Service service, NodeTemplate nodeTemplate) { String nodeTypeName = normaliseNodeTypeName(nodeTemplate); - Model model = Model.getModelFor(nodeTypeName); + Model model = Model.getModelFor(nodeTypeName, nodeTemplate.getMetaData().getValue("type")); if (model != null) { if (nodeTemplate.getMetaData() != null) { model.populateModelIdentificationInformation(nodeTemplate.getMetaData().getAllProperties()); @@ -215,6 +307,13 @@ public class ArtifactGeneratorToscaParser { } } + /** + * Process TOSCA Group information for VF Modules. + * + * @param resources + * @param model + * @param 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); @@ -237,7 +336,11 @@ 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()) { @@ -306,13 +409,13 @@ public class ArtifactGeneratorToscaParser { private void processVfTosca(Map idTypeStore, Model resourceModel, List resourceNodes) { - boolean providingServiceFound = false; + boolean foundProvidingService = false; for (NodeTemplate resourceNodeTemplate : resourceNodes) { String nodeTypeName = normaliseNodeTypeName(resourceNodeTemplate); Model resourceNode = Model.getModelFor(nodeTypeName); if (resourceNode instanceof ProvidingService) { - providingServiceFound = true; + foundProvidingService = true; Map nodeProperties = resourceNodeTemplate.getProperties(); if (nodeProperties.get("providing_service_uuid") == null || nodeProperties.get("providing_service_invariant_uuid") == null) { @@ -329,9 +432,10 @@ public class ArtifactGeneratorToscaParser { } } - if (resourceModel instanceof AllotedResource && !providingServiceFound) { + if (resourceModel instanceof AllotedResource && !foundProvidingService) { throw new IllegalArgumentException( String.format(GENERATOR_AAI_PROVIDING_SERVICE_MISSING, resourceModel.getModelId())); } } + } diff --git a/src/main/java/org/onap/aai/babel/xml/generator/api/AaiArtifactGenerator.java b/src/main/java/org/onap/aai/babel/xml/generator/api/AaiArtifactGenerator.java index 79c7492..ca4cfa2 100644 --- a/src/main/java/org/onap/aai/babel/xml/generator/api/AaiArtifactGenerator.java +++ b/src/main/java/org/onap/aai/babel/xml/generator/api/AaiArtifactGenerator.java @@ -64,6 +64,7 @@ public class AaiArtifactGenerator implements ArtifactGenerator { try { ArtifactGeneratorToscaParser.initWidgetConfiguration(); + ArtifactGeneratorToscaParser.initGroupFilterConfiguration(); String serviceVersion = validateServiceVersion(additionalParams); GenerationData generationData = new GenerationData(); @@ -100,10 +101,10 @@ public class AaiArtifactGenerator implements ArtifactGenerator { // Generate AAI XML resource model for (Resource res : resources) { + log.info(ApplicationMsgs.DISTRIBUTION_EVENT, "Generating resource model"); MDC.put(MDC_PARAM_MODEL_INFO, res.getModelName() + "," + getArtifactLabel(res)); String aaiResourceModel = modelGenerator.generateModelFor(res); generationData.add(getResourceArtifact(res, aaiResourceModel)); - } } return generationData; @@ -237,8 +238,7 @@ public class AaiArtifactGenerator implements ArtifactGenerator { } else { String versionRegex = "^[1-9]\\d*(\\.0)$"; if (!(serviceVersion.matches(versionRegex))) { - throw new IllegalArgumentException( - String.format(GENERATOR_AAI_INVALID_SERVICE_VERSION)); + throw new IllegalArgumentException(String.format(GENERATOR_AAI_INVALID_SERVICE_VERSION)); } } return serviceVersion; diff --git a/src/main/java/org/onap/aai/babel/xml/generator/data/WidgetConfigurationUtil.java b/src/main/java/org/onap/aai/babel/xml/generator/data/WidgetConfigurationUtil.java index d36982d..9f8cbf8 100644 --- a/src/main/java/org/onap/aai/babel/xml/generator/data/WidgetConfigurationUtil.java +++ b/src/main/java/org/onap/aai/babel/xml/generator/data/WidgetConfigurationUtil.java @@ -20,11 +20,15 @@ */ package org.onap.aai.babel.xml.generator.data; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import java.util.Properties; public class WidgetConfigurationUtil { private static Properties config; + private static List instanceGroups = Collections.emptyList(); /* * Private constructor to prevent instantiation @@ -40,4 +44,15 @@ public class WidgetConfigurationUtil { public static void setConfig(Properties config) { WidgetConfigurationUtil.config = config; } + + public static void setFilterConfig(Properties properties) { + String instanceGroupsList = (String) properties.get("AAI.instance-group-types"); + if (instanceGroupsList != null) { + instanceGroups = Arrays.asList(instanceGroupsList.split(",")); + } + } + + public static boolean isSupportedInstanceGroup(String groupType) { + return instanceGroups.contains(groupType); + } } diff --git a/src/main/java/org/onap/aai/babel/xml/generator/model/InstanceGroup.java b/src/main/java/org/onap/aai/babel/xml/generator/model/InstanceGroup.java new file mode 100644 index 0000000..f312064 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/xml/generator/model/InstanceGroup.java @@ -0,0 +1,28 @@ +/** + * ============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.xml.generator.model; + +import org.onap.aai.babel.xml.generator.types.Cardinality; +import org.onap.aai.babel.xml.generator.types.Model; + +@Model(widget = Widget.Type.INSTANCE_GROUP, cardinality = Cardinality.UNBOUNDED, dataDeleteFlag = true) +public class InstanceGroup extends Resource { +} diff --git a/src/main/java/org/onap/aai/babel/xml/generator/model/InstanceGroupWidget.java b/src/main/java/org/onap/aai/babel/xml/generator/model/InstanceGroupWidget.java new file mode 100644 index 0000000..dabce34 --- /dev/null +++ b/src/main/java/org/onap/aai/babel/xml/generator/model/InstanceGroupWidget.java @@ -0,0 +1,31 @@ +/** + * ============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.xml.generator.model; + +import org.onap.aai.babel.xml.generator.types.Cardinality; +import org.onap.aai.babel.xml.generator.types.ModelType; +import org.onap.aai.babel.xml.generator.types.ModelWidget; + +@org.onap.aai.babel.xml.generator.types.Model(widget = Widget.Type.INSTANCE_GROUP, cardinality = Cardinality.UNBOUNDED, + dataDeleteFlag = true) +@ModelWidget(type = ModelType.WIDGET, name = "instance-group") +public class InstanceGroupWidget extends Widget { +} diff --git a/src/main/java/org/onap/aai/babel/xml/generator/model/Model.java b/src/main/java/org/onap/aai/babel/xml/generator/model/Model.java index 8e9c062..7b2fc42 100644 --- a/src/main/java/org/onap/aai/babel/xml/generator/model/Model.java +++ b/src/main/java/org/onap/aai/babel/xml/generator/model/Model.java @@ -20,7 +20,6 @@ */ package org.onap.aai.babel.xml.generator.model; -import java.lang.reflect.InvocationTargetException; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -159,14 +158,33 @@ public abstract class Model { if (clazz != null) { try { modelToBeReturned = Optional.ofNullable(clazz.getConstructor().newInstance()); - } catch (InstantiationException | java.lang.IllegalAccessException | IllegalArgumentException - | InvocationTargetException | NoSuchMethodException | SecurityException e) { + } catch (Exception e) { log.error(ApplicationMsgs.INVALID_CSAR_FILE, e); } } return modelToBeReturned; } + /** + * Gets the object (model) corresponding to the supplied TOSCA type information, prioritising the metadata + * information. + * + * @param toscaType + * the TOSCA type + * @param metaDataType + * the type from the TOSCA metadata + * @return the model for the type, or null + */ + public static Model getModelFor(String toscaType, String metaDataType) { + if ("Configuration".equals(metaDataType)) { + return new Configuration(); + } else if ("CR".equals(metaDataType)) { + return new CR(); + } else { + return getModelFor(toscaType); + } + } + public abstract boolean addResource(Resource resource); public abstract boolean addWidget(Widget resource); @@ -291,4 +309,5 @@ public abstract class Model { throw new IllegalAccessException(GENERATOR_AAI_ERROR_UNSUPPORTED_WIDGET_OPERATION); } } + } diff --git a/src/main/java/org/onap/aai/babel/xml/generator/model/VfModule.java b/src/main/java/org/onap/aai/babel/xml/generator/model/VfModule.java index 8b8913d..d6d3a2d 100644 --- a/src/main/java/org/onap/aai/babel/xml/generator/model/VfModule.java +++ b/src/main/java/org/onap/aai/babel/xml/generator/model/VfModule.java @@ -38,7 +38,7 @@ public class VfModule extends Resource { } /** - * Adds Widget. + * Adds a Widget. * * @param widget the widget * @return the boolean diff --git a/src/main/java/org/onap/aai/babel/xml/generator/model/Widget.java b/src/main/java/org/onap/aai/babel/xml/generator/model/Widget.java index 49e3811..d78e2e6 100644 --- a/src/main/java/org/onap/aai/babel/xml/generator/model/Widget.java +++ b/src/main/java/org/onap/aai/babel/xml/generator/model/Widget.java @@ -38,10 +38,28 @@ import org.onap.aai.cl.api.Logger; public abstract class Widget extends Model { - public static final String GENERATOR_AAI_CONFIGLPROP_NOT_FOUND = "Cannot generate artifacts. Widget configuration not found for %s"; + public static final String GENERATOR_AAI_CONFIGLPROP_NOT_FOUND = + "Cannot generate artifacts. Widget configuration not found for %s"; public enum Type { - SERVICE, VF, VFC, VSERVER, VOLUME, FLAVOR, TENANT, VOLUME_GROUP, LINT, L3_NET, VFMODULE, IMAGE, OAM_NETWORK, ALLOTTED_RESOURCE, TUNNEL_XCONNECT, CONFIGURATION, CR; + SERVICE, + VF, + VFC, + VSERVER, + VOLUME, + FLAVOR, + TENANT, + VOLUME_GROUP, + LINT, + L3_NET, + VFMODULE, + IMAGE, + OAM_NETWORK, + ALLOTTED_RESOURCE, + TUNNEL_XCONNECT, + CONFIGURATION, + CR, + INSTANCE_GROUP; } private static Logger log = LogHelper.INSTANCE; @@ -67,13 +85,13 @@ public abstract class Widget extends Model { typeToWidget.put(Type.TUNNEL_XCONNECT, TunnelXconnectWidget.class); typeToWidget.put(Type.CONFIGURATION, ConfigurationWidget.class); typeToWidget.put(Type.CR, CRWidget.class); + typeToWidget.put(Type.INSTANCE_GROUP, InstanceGroupWidget.class); } /** * Gets widget. * - * @param type - * the type + * @param type the type * @return the widget */ public static Widget getWidget(Type type) { @@ -139,8 +157,7 @@ public abstract class Widget extends Model { /** * Equals method that compares Widget IDs. * - * @param obj - * the Widget object to compare + * @param obj the Widget object to compare * @return whether or not obj is equal to this Widget */ @Override @@ -163,8 +180,7 @@ public abstract class Widget extends Model { /** * Determine whether one or more keys belonging to this Widget appear in the specified Collection. * - * @param keys - * the keys + * @param keys the keys * @return the boolean */ public boolean memberOf(Collection keys) { @@ -183,5 +199,4 @@ public abstract class Widget extends Model { public boolean addWidget(Widget widget) { return true; } - } diff --git a/src/test/java/org/onap/aai/babel/parser/TestToscaParser.java b/src/test/java/org/onap/aai/babel/parser/TestToscaParser.java index f340132..3bab915 100644 --- a/src/test/java/org/onap/aai/babel/parser/TestToscaParser.java +++ b/src/test/java/org/onap/aai/babel/parser/TestToscaParser.java @@ -54,12 +54,16 @@ public class TestToscaParser { } private static final String ARTIFACT_GENERATOR_CONFIG = "artifact-generator.properties"; + private static final String FILTER_TYPES_CONFIG = "filter-types.properties"; @Before public void setup() throws FileNotFoundException, IOException { System.setProperty(ArtifactGeneratorToscaParser.PROPERTY_ARTIFACT_GENERATOR_CONFIG_FILE, new ArtifactTestUtils().getResourcePath(ARTIFACT_GENERATOR_CONFIG)); + System.setProperty(ArtifactGeneratorToscaParser.PROPERTY_GROUP_FILTERS_CONFIG_FILE, + new ArtifactTestUtils().getResourcePath(FILTER_TYPES_CONFIG)); + InputStream in = TestToscaParser.class.getClassLoader().getResourceAsStream("artifact-generator.properties"); Properties properties = new Properties(); properties.load(in); diff --git a/src/test/java/org/onap/aai/babel/service/CsarToXmlConverterTest.java b/src/test/java/org/onap/aai/babel/service/CsarToXmlConverterTest.java index 67539bb..bf970a6 100644 --- a/src/test/java/org/onap/aai/babel/service/CsarToXmlConverterTest.java +++ b/src/test/java/org/onap/aai/babel/service/CsarToXmlConverterTest.java @@ -52,6 +52,8 @@ import org.onap.aai.babel.xml.generator.XmlArtifactGenerationException; public class CsarToXmlConverterTest { private static final String ARTIFACT_GENERATOR_CONFIG = "artifact-generator.properties"; + private static final String FILTER_TYPES_CONFIG = "filter-types.properties"; + private static final String INCORRECT_CSAR_NAME = "the_name_of_the_csar_file.csar"; private static final String SERVICE_VERSION = "1.0"; @@ -71,6 +73,10 @@ public class CsarToXmlConverterTest { public void setup() { System.setProperty(ArtifactGeneratorToscaParser.PROPERTY_ARTIFACT_GENERATOR_CONFIG_FILE, new ArtifactTestUtils().getResourcePath(ARTIFACT_GENERATOR_CONFIG)); + + System.setProperty(ArtifactGeneratorToscaParser.PROPERTY_GROUP_FILTERS_CONFIG_FILE, + new ArtifactTestUtils().getResourcePath(FILTER_TYPES_CONFIG)); + converter = new CsarToXmlConverter(); } @@ -110,15 +116,14 @@ public class CsarToXmlConverterTest { * * @throws CsarConverterException if there is an error either extracting the YAML files or generating XML artifacts * @throws IOException if an I/O exception occurs loading the test CSAR file + * @throws IOException + * @throws XmlArtifactGenerationException + * @throws CsarConverterException */ @Test public void testArtifactGeneratorConfigMissing() throws CsarConverterException, IOException { exception.expect(CsarConverterException.class); - exception.expectMessage( - "An error occurred trying to generate XML files from a collection of YAML files :" - + " org.onap.aai.babel.xml.generator.XmlArtifactGenerationException: " - + "Error occurred during artifact generation: " - + "{AAI=[Cannot generate artifacts. artifactgenerator.config system property not configured]}"); + exception.expectMessage("Cannot generate artifacts. System property artifactgenerator.config not configured"); // Unset the required system property System.clearProperty(ArtifactGeneratorToscaParser.PROPERTY_ARTIFACT_GENERATOR_CONFIG_FILE); @@ -126,6 +131,25 @@ public class CsarToXmlConverterTest { SERVICE_VERSION); } + /** + * Test that an Exception is thrown when the Artifact Generator's Group Filter properties are not present. + * + * @throws IOException + * @throws XmlArtifactGenerationException + * @throws CsarConverterException + */ + @Test + public void generateXmlFromCsarFilterTypesSystemPropertyNotSet() + throws IOException, XmlArtifactGenerationException, CsarConverterException { + exception.expect(CsarConverterException.class); + exception.expectMessage("Cannot generate artifacts. System property groupfilter.config not configured"); + + // Unset the required system property + System.clearProperty(ArtifactGeneratorToscaParser.PROPERTY_GROUP_FILTERS_CONFIG_FILE); + converter.generateXmlFromCsar(CsarTest.SD_WAN_CSAR_FILE.getContent(), CsarTest.SD_WAN_CSAR_FILE.getName(), + SERVICE_VERSION); + } + @Test public void testServiceMetadataMissing() throws IOException, XmlArtifactGenerationException, CsarConverterException { diff --git a/src/test/java/org/onap/aai/babel/service/TestGenerateArtifactsServiceImpl.java b/src/test/java/org/onap/aai/babel/service/TestGenerateArtifactsServiceImpl.java index 599b3ff..78e02f4 100644 --- a/src/test/java/org/onap/aai/babel/service/TestGenerateArtifactsServiceImpl.java +++ b/src/test/java/org/onap/aai/babel/service/TestGenerateArtifactsServiceImpl.java @@ -55,7 +55,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; * */ @RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(locations = {"classpath:/babel-beans.xml"}) +@ContextConfiguration(locations = { "classpath:/babel-beans.xml" }) public class TestGenerateArtifactsServiceImpl { static { @@ -66,6 +66,7 @@ public class TestGenerateArtifactsServiceImpl { } private static final String ARTIFACT_GENERATOR_CONFIG = "artifact-generator.properties"; + private static final String FILTER_TYPES_CONFIG = "filter-types.properties"; @Inject private AAIMicroServiceAuth auth; @@ -74,6 +75,8 @@ public class TestGenerateArtifactsServiceImpl { public static void setup() { System.setProperty(ArtifactGeneratorToscaParser.PROPERTY_ARTIFACT_GENERATOR_CONFIG_FILE, new ArtifactTestUtils().getResourcePath(ARTIFACT_GENERATOR_CONFIG)); + System.setProperty(ArtifactGeneratorToscaParser.PROPERTY_GROUP_FILTERS_CONFIG_FILE, + new ArtifactTestUtils().getResourcePath(FILTER_TYPES_CONFIG)); } @Test @@ -148,8 +151,10 @@ public class TestGenerateArtifactsServiceImpl { * * @param csar * @return the Response from the HTTP API - * @throws URISyntaxException if the URI cannot be created - * @throws IOException if the resource cannot be loaded + * @throws URISyntaxException + * if the URI cannot be created + * @throws IOException + * if the resource cannot be loaded */ private Response processJsonRequest(CsarTest csar) throws IOException, URISyntaxException { String jsonString = csar.getJsonRequest(); @@ -159,9 +164,11 @@ public class TestGenerateArtifactsServiceImpl { /** * Create a (mocked) HTTPS request and invoke the Babel generate artifacts API. * - * @param jsonString the JSON request + * @param jsonString + * the JSON request * @return the Response from the HTTP API - * @throws URISyntaxException if the URI cannot be created + * @throws URISyntaxException + * if the URI cannot be created */ private Response invokeService(String jsonString) throws URISyntaxException { UriInfo mockUriInfo = Mockito.mock(UriInfo.class); @@ -192,7 +199,7 @@ public class TestGenerateArtifactsServiceImpl { Mockito.when(mockCertificate.getSubjectX500Principal()) .thenReturn(new X500Principal("CN=test, OU=qa, O=Test Ltd, L=London, ST=London, C=GB")); - servletRequest.setAttribute("javax.servlet.request.X509Certificate", new X509Certificate[] {mockCertificate}); + servletRequest.setAttribute("javax.servlet.request.X509Certificate", new X509Certificate[] { mockCertificate }); servletRequest.setAttribute("javax.servlet.request.cipher_suite", ""); GenerateArtifactsServiceImpl service = new GenerateArtifactsServiceImpl(auth); diff --git a/src/test/java/org/onap/aai/babel/xml/generator/model/TestModel.java b/src/test/java/org/onap/aai/babel/xml/generator/model/TestModel.java index 2bd6fc7..9b5700d 100644 --- a/src/test/java/org/onap/aai/babel/xml/generator/model/TestModel.java +++ b/src/test/java/org/onap/aai/babel/xml/generator/model/TestModel.java @@ -45,7 +45,7 @@ import org.onap.aai.babel.xml.generator.types.ModelType; public class TestModel { private Service serviceModel = new Service(); - private List resourceModels = Arrays.asList(new VirtualFunction()); + private List resourceModels = Arrays.asList(new VirtualFunction(), new InstanceGroup()); private Widget widgetModel = new OamNetwork(); private Model anonymousModel; @@ -109,6 +109,13 @@ public class TestModel { assertThat(Model.getModelFor("org.openecomp.resource.vfc.nodes.heat.cinder"), instanceOf(VolumeWidget.class)); assertThat(Model.getModelFor("org.openecomp.nodes.PortMirroringConfiguration"), instanceOf(Configuration.class)); + assertThat(Model.getModelFor("org.openecomp.nodes.PortMirroringConfiguration", "Configuration"), + instanceOf(Configuration.class)); + assertThat(Model.getModelFor("any.string", "Configuration"), instanceOf(Configuration.class)); + assertThat(Model.getModelFor("org.openecomp.resource.cr.Kk1806Cr1", "CR"), instanceOf(CR.class)); + assertThat(Model.getModelFor("any.string", "CR"), instanceOf(CR.class)); + + assertThat(Model.getModelFor("org.openecomp.resource.vfc", "an.unknown.type"), instanceOf(VServerWidget.class)); } @Test diff --git a/src/test/resources/artifact-generator.properties b/src/test/resources/artifact-generator.properties index ba207cf..1a905b6 100644 --- a/src/test/resources/artifact-generator.properties +++ b/src/test/resources/artifact-generator.properties @@ -1,4 +1,4 @@ -#action widget details +#action widget details AAI.model-version-id.action=action-version-id AAI.model-invariant-id.action=action-invariant-id #action-data widget details @@ -265,3 +265,6 @@ AAI.model-version-id.vpn-binding=vpn-binding-version-id #vserver widget details AAI.model-invariant-id.vserver=vserver-invariant-id AAI.model-version-id.vserver=vserver-version-id +#cr (Collection Resource) widget details +AAI.model-version-id.cr=collection-resource-version-id +AAI.model-invariant-id.cr=collection-resource-invariant-id diff --git a/src/test/resources/filter-types.properties b/src/test/resources/filter-types.properties new file mode 100644 index 0000000..fcf139f --- /dev/null +++ b/src/test/resources/filter-types.properties @@ -0,0 +1 @@ +AAI.instance-group-types=org.openecomp.groups.NetworkCollection,org.openecomp.groups.VfcInstanceGroup -- 2.16.6