diff options
author | mark.j.leonard <mark.j.leonard@gmail.com> | 2018-09-10 15:53:13 +0100 |
---|---|---|
committer | mark.j.leonard <mark.j.leonard@gmail.com> | 2018-09-10 15:56:03 +0100 |
commit | e4cc64bb1b7c0acba0fe11160469c03b94bd5be2 (patch) | |
tree | 380095337e0b2cd88ea3d6621adf0a828842c684 /src/main/java/org/onap | |
parent | 64bebc790795869a3dde4093296f3d55294b4f40 (diff) |
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 <mark.j.leonard@gmail.com>
Diffstat (limited to 'src/main/java/org/onap')
8 files changed, 251 insertions, 39 deletions
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<Resource> processResourceToscas(List<NodeTemplate> serviceNodes, Map<String, String> idTypeStore) { List<Resource> resources = new LinkedList<>(); for (NodeTemplate serviceNode : serviceNodes) { if (serviceNode.getMetaData() != null) { - List<NodeTemplate> 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<String, String> idTypeStore, List<Resource> resources, - NodeTemplate serviceNode, List<NodeTemplate> resourceNodes) { + /** + * @param idTypeStore ID->Type mapping + * @param serviceNode + * @param resourceNodes + * @return the processed resource models + */ + private List<Resource> processResourceTosca(Map<String, String> idTypeStore, NodeTemplate serviceNode, + List<NodeTemplate> resourceNodes) { + List<Resource> 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<String, String> 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<Resource> processInstanceGroups(Model resourceModel, NodeTemplate serviceNode) { + List<Resource> resources = new ArrayList<>(); + if (csarHelper.getNodeTemplateByName(serviceNode.getName()).getSubMappingToscaTemplate() != null) { + List<Group> 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<Resource> processInstanceGroup(Model resourceModel, Group group) { + List<Resource> resources = new ArrayList<>(); + + Resource groupModel = new InstanceGroup(); + groupModel.populateModelIdentificationInformation(group.getMetadata().getAllProperties()); + groupModel.populateModelIdentificationInformation(populateStringProperties(group.getProperties())); + + resourceModel.addResource(groupModel); + resources.add(groupModel); + + List<NodeTemplate> 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<String, String> 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<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); @@ -237,7 +336,11 @@ 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()) { @@ -306,13 +409,13 @@ public class ArtifactGeneratorToscaParser { private void processVfTosca(Map<String, String> idTypeStore, Model resourceModel, List<NodeTemplate> 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<String, Property> 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<String> 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<String> keys) { @@ -183,5 +199,4 @@ public abstract class Widget extends Model { public boolean addWidget(Widget widget) { return true; } - } |