From: mark.j.leonard Date: Thu, 22 Nov 2018 12:24:44 +0000 (+0000) Subject: Refactor Instance Group processing X-Git-Tag: 1.4.1~55 X-Git-Url: https://gerrit.onap.org/r/gitweb?p=aai%2Fbabel.git;a=commitdiff_plain;h=36606e8fbcae1248aff9740717a666120cf9d8a0 Refactor Instance Group processing Minor refactoring and reformatting of Java code using Eclipse. Add private method mergeProperties() to replace duplicated code logic for populating the Group model. Change-Id: I1360bbbf5b065149028a94392dd530af9c9153e8 Issue-ID: AAI-1884 Signed-off-by: mark.j.leonard --- 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 80b75b0..ed7fc19 100644 --- a/src/main/java/org/onap/aai/babel/parser/ArtifactGeneratorToscaParser.java +++ b/src/main/java/org/onap/aai/babel/parser/ArtifactGeneratorToscaParser.java @@ -25,12 +25,14 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Properties; import java.util.stream.Collectors; +import java.util.stream.Stream; import org.onap.aai.babel.logging.ApplicationMsgs; import org.onap.aai.babel.logging.LogHelper; import org.onap.aai.babel.xml.generator.data.WidgetConfigurationUtil; @@ -54,431 +56,463 @@ import org.onap.sdc.toscaparser.api.elements.Metadata; 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. 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 = - "Cannot generate artifacts. Providing Service is missing for allotted resource %s"; - - // Metadata properties - private static final String CATEGORY = "category"; - private static final String ALLOTTED_RESOURCE = "Allotted Resource"; - private static final String SUBCATEGORY = "subcategory"; - private static final String TUNNEL_XCONNECT = "Tunnel XConnect"; - - private static final String VERSION = "version"; - - private ISdcCsarHelper csarHelper; - - /** - * Constructs using csarHelper - * - * @param csarHelper The csar helper - */ - public ArtifactGeneratorToscaParser(ISdcCsarHelper csarHelper) { - this.csarHelper = csarHelper; - } - - /** - * Returns the artifact description - * - * @param model the artifact model - * @return the artifact model's description - */ - public static String getArtifactDescription(Model model) { - String artifactDesc = model.getModelDescription(); - if (model.getModelType().equals(ModelType.SERVICE)) { - artifactDesc = "AAI Service Model"; - } else if (model.getModelType().equals(ModelType.RESOURCE)) { - artifactDesc = "AAI Resource Model"; - } - return artifactDesc; - } - - /** - * Initialises the widget configuration. - * - * @throws IOException - */ - public static void initWidgetConfiguration() throws IOException { - log.debug("Getting Widget Configuration"); - String configLocation = System.getProperty(PROPERTY_ARTIFACT_GENERATOR_CONFIG_FILE); - if (configLocation != null) { - File file = new File(configLocation); - if (file.exists()) { - Properties properties = new Properties(); - properties.load(new FileInputStream(file)); - WidgetConfigurationUtil.setConfig(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_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)); - } - } - - /** - * 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("Processing (TOSCA) Service object"); - - for (NodeTemplate nodeTemplate : nodeTemplates) { - if (nodeTemplate.getMetaData() != null) { - addNodeToService(idTypeStore, service, nodeTemplate); - } else { - log.warn(ApplicationMsgs.MISSING_SERVICE_METADATA, nodeTemplate.getName()); - } - } - } - - /** - * 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) { - resources.addAll(processResourceTosca(idTypeStore, serviceNode, - csarHelper.getNodeTemplateChildren(serviceNode))); - } else { - log.warn(ApplicationMsgs.MISSING_SERVICE_METADATA, serviceNode.getName()); - } - } - return resources; - } - - /** - * @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 nodeTypeName = idTypeStore.get(resourceUuId); - if (nodeTypeName != null) { - Model resourceModel = Model.getModelFor(nodeTypeName, serviceNode.getMetaData().getValue("type")); - - log.debug("Processing resource " + nodeTypeName + ": " + resourceUuId); - Map serviceMetadata = serviceNode.getMetaData().getAllProperties(); - resourceModel.populateModelIdentificationInformation(serviceMetadata); - - idTypeStore.remove(resourceModel.getModelNameVersionId()); - processResourceModels(idTypeStore, resourceModel, resourceNodes); - - if (csarHelper.getServiceVfList() != null) { - processVfModules(resources, resourceModel, serviceNode); - } - - if (hasSubCategoryTunnelXConnect(serviceMetadata) && hasAllottedResource(serviceMetadata)) { - 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 - */ - 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.getMemberNodes(), - group.getMetadata().getAllProperties(), group.getProperties())); - } - } - } - return resources; - } - - /** - * Create an Instance Group Model and populate it with the supplied data. - * - * @param resourceModel the Resource node template Model - * @param memberNodes the Resources and Widgets belonging to the Group - * @param metaProperties the metadata of the Group - * @param properties the properties of the Group - * @return the Instance Group and Member resource models - */ - private List processInstanceGroup(Model resourceModel, ArrayList memberNodes, - Map metaProperties, Map properties) { - List resources = new ArrayList<>(); - - Resource groupModel = new InstanceGroup(); - groupModel.populateModelIdentificationInformation(metaProperties); - groupModel.populateModelIdentificationInformation(populateStringProperties(properties)); - - resourceModel.addResource(groupModel); - resources.add(groupModel); - - if (memberNodes != null && !memberNodes.isEmpty()) { - resources.addAll(generateResourcesAndWidgets(memberNodes, groupModel)); - } - - return resources; - } - - /** - * @param memberNodes - * @param groupModel - * @return - */ - private List generateResourcesAndWidgets(final ArrayList memberNodes, - final Resource groupModel) { - List resources = new ArrayList<>(); - for (NodeTemplate nodeTemplate : memberNodes) { - String nodeTypeName = normaliseNodeTypeName(nodeTemplate); - Model memberModel = Model.getModelFor(nodeTypeName, nodeTemplate.getMetaData().getValue("type")); - memberModel.populateModelIdentificationInformation(nodeTemplate.getMetaData().getAllProperties()); - - log.debug(String.format("Generating grouped %s (%s) from TOSCA type %s", - memberModel.getClass().getSuperclass().getSimpleName(), memberModel.getClass(), nodeTypeName)); - - addRelatedModel(groupModel, memberModel); - if (memberModel instanceof Resource) { - resources.add((Resource) memberModel); - } - } - return resources; - } - - /** - * Add the supplied Node Template to the Service, provided that it is a valid Resource or Widget. If the Node - * Template is a Resource type, this is also recorded in the supplied nodesById Map. - * - * @param nodesById a map of Resource node type names, keyed by UUID - * @param service the Service to which the Node Template should be added - * @param nodeTemplate the Node Template to add (only if this is a Resource or Widget type) - */ - private void addNodeToService(Map nodesById, Service service, NodeTemplate nodeTemplate) { - String nodeTypeName = normaliseNodeTypeName(nodeTemplate); - Model model = Model.getModelFor(nodeTypeName, nodeTemplate.getMetaData().getValue("type")); - if (model != null) { - if (nodeTemplate.getMetaData() != null) { - model.populateModelIdentificationInformation(nodeTemplate.getMetaData().getAllProperties()); - } - - addRelatedModel(service, model); - if (model instanceof Resource) { - nodesById.put(model.getModelNameVersionId(), nodeTypeName); - } - } - } - - /** - * @param model - * @param relation - */ - private void addRelatedModel(final Model model, final Model relation) { - if (relation instanceof Resource) { - model.addResource((Resource) relation); - } else { - model.addWidget((Widget) relation); - } - } - - /** - * 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); - 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, resourceModel, serviceGroup, serviceNode, (VfModule) groupModel); - } - } - } - - private void processVfModule(List resources, Model model, Group groupDefinition, NodeTemplate serviceNode, - VfModule groupModel) { - // Populate group with metadata properties - groupModel.populateModelIdentificationInformation(groupDefinition.getMetadata().getAllProperties()); - // Populate group with non-metadata properties - 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 member : members) { - processGroupMembers(groupModel, member); - } - } - - model.addResource(groupModel); // Added group (VfModule) to the (VF) model - // Check if we have already encountered the same VfModule across all the artifacts - if (!resources.contains(groupModel)) { - resources.add(groupModel); - } - } - - private void processGroupMembers(Model group, NodeTemplate member) { - Model resourceNode; - // L3-network inside vf-module to be generated as Widget a special handling. - if (member.getType().contains("org.openecomp.resource.vl")) { - resourceNode = new L3NetworkWidget(); - } else { - resourceNode = Model.getModelFor(member.getType()); - } - if (resourceNode != null && !(resourceNode instanceof Resource)) { - Widget widget = (Widget) resourceNode; - widget.addKey(member.getName()); - // Add the widget element encountered to the Group model - group.addWidget(widget); - } - } - - private String normaliseNodeTypeName(NodeTemplate nodeType) { - String nodeTypeName = nodeType.getType(); - Metadata metadata = nodeType.getMetaData(); - if (metadata != null && hasAllottedResource(metadata.getAllProperties())) { - if (nodeType.getType().contains("org.openecomp.resource.vf.")) { - nodeTypeName = "org.openecomp.resource.vf.allottedResource"; - } - if (nodeType.getType().contains("org.openecomp.resource.vfc.")) { - nodeTypeName = "org.openecomp.resource.vfc.AllottedResource"; - } - } - return nodeTypeName; - } - - private boolean hasAllottedResource(Map metadata) { - return ALLOTTED_RESOURCE.equals(metadata.get(CATEGORY)); - } - - private boolean hasSubCategoryTunnelXConnect(Map metadata) { - return TUNNEL_XCONNECT.equals(metadata.get(SUBCATEGORY)); - } - - /** - * Create a Map of property name against String property value from the input Map - * - * @param inputMap The input Map - * @return Map of property name against String property value - */ - private Map populateStringProperties(Map inputMap) { - return inputMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, - e -> e.getValue().getValue() == null ? "" : e.getValue().getValue().toString())); - } - - private void processResourceModels(Map idTypeStore, Model resourceModel, - List resourceNodes) { - boolean foundProvidingService = false; - - for (NodeTemplate resourceNodeTemplate : resourceNodes) { - String nodeTypeName = normaliseNodeTypeName(resourceNodeTemplate); - Metadata metaData = resourceNodeTemplate.getMetaData(); - String metaDataType = Optional.ofNullable(metaData).map(m -> m.getValue("type")).orElse(nodeTypeName); - Model resourceNode = Model.getModelFor(nodeTypeName, metaDataType); - foundProvidingService |= processModel(idTypeStore, resourceModel, resourceNodeTemplate, nodeTypeName, - metaData, resourceNode); - } - - if (resourceModel instanceof AllotedResource && !foundProvidingService) { - throw new IllegalArgumentException( - String.format(GENERATOR_AAI_PROVIDING_SERVICE_MISSING, resourceModel.getModelId())); - } - } - - private boolean processModel(Map idTypeStore, Model resourceModel, - NodeTemplate resourceNodeTemplate, String nodeTypeName, Metadata metaData, Model resourceNode) { - boolean foundProvidingService = false; - if (resourceNode instanceof ProvidingService) { - foundProvidingService = true; - processProvidingService(resourceModel, resourceNodeTemplate, resourceNode); - } else if (resourceNode instanceof Resource && !(resourceNode.getWidgetType().equals(Widget.Type.L3_NET))) { - if (metaData != null) { - resourceNode.populateModelIdentificationInformation(metaData.getAllProperties()); - } - idTypeStore.put(resourceNode.getModelNameVersionId(), nodeTypeName); - resourceModel.addResource((Resource) resourceNode); - } - return foundProvidingService; - } - - private void processProvidingService(Model resourceModel, NodeTemplate resourceNodeTemplate, Model resourceNode) { - 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, resourceModel.getModelId())); - } - Map properties = populateStringProperties(nodeProperties); - properties.put(VERSION, "1.0"); - resourceNode.populateModelIdentificationInformation(properties); - resourceModel.addResource((Resource) resourceNode); - } - + 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. 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 = "Cannot generate artifacts. Providing Service is missing for allotted resource %s"; + + // Metadata properties + private static final String CATEGORY = "category"; + private static final String ALLOTTED_RESOURCE = "Allotted Resource"; + private static final String SUBCATEGORY = "subcategory"; + private static final String TUNNEL_XCONNECT = "Tunnel XConnect"; + + private static final String VERSION = "version"; + + private ISdcCsarHelper csarHelper; + + /** + * Constructs using csarHelper + * + * @param csarHelper + * The csar helper + */ + public ArtifactGeneratorToscaParser(ISdcCsarHelper csarHelper) { + this.csarHelper = csarHelper; + } + + /** + * Returns the artifact description + * + * @param model + * the artifact model + * @return the artifact model's description + */ + public static String getArtifactDescription(Model model) { + String artifactDesc = model.getModelDescription(); + if (model.getModelType().equals(ModelType.SERVICE)) { + artifactDesc = "AAI Service Model"; + } else if (model.getModelType().equals(ModelType.RESOURCE)) { + artifactDesc = "AAI Resource Model"; + } + return artifactDesc; + } + + /** + * Initialises the widget configuration. + * + * @throws IOException + */ + public static void initWidgetConfiguration() throws IOException { + log.debug("Getting Widget Configuration"); + String configLocation = System.getProperty(PROPERTY_ARTIFACT_GENERATOR_CONFIG_FILE); + if (configLocation != null) { + File file = new File(configLocation); + if (file.exists()) { + Properties properties = new Properties(); + properties.load(new FileInputStream(file)); + WidgetConfigurationUtil.setConfig(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_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)); + } + } + + /** + * 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("Processing (TOSCA) Service object"); + + for (NodeTemplate nodeTemplate : nodeTemplates) { + if (nodeTemplate.getMetaData() != null) { + addNodeToService(idTypeStore, service, nodeTemplate); + } else { + log.warn(ApplicationMsgs.MISSING_SERVICE_METADATA, nodeTemplate.getName()); + } + } + } + + /** + * Generates a Resource List using input Service Node Templates. + * + * @param serviceNodeTemplates + * input Service Node Templates + * @param idTypeStore + * ID->Type mapping + * + * @return the processed resource models + */ + public List processResourceToscas(List serviceNodeTemplates, + Map idTypeStore) { + List resources = new LinkedList<>(); + for (NodeTemplate serviceNodeTemplate : serviceNodeTemplates) { + if (serviceNodeTemplate.getMetaData() != null) { + resources.addAll(processResourceTosca(idTypeStore, serviceNodeTemplate, + csarHelper.getNodeTemplateChildren(serviceNodeTemplate))); + } else { + log.warn(ApplicationMsgs.MISSING_SERVICE_METADATA, serviceNodeTemplate.getName()); + } + } + return resources; + } + + /** + * @param idTypeStore + * ID->Type mapping + * @param serviceNodeTemplate + * @param resourceNodeTemplates + * the (non-VNF) substituted node templates + * @return the processed resource models + */ + private List processResourceTosca(Map idTypeStore, NodeTemplate serviceNodeTemplate, + List resourceNodeTemplates) { + List resources = new LinkedList<>(); + String resourceUuId = serviceNodeTemplate.getMetaData().getValue("UUID"); + String nodeTypeName = idTypeStore.get(resourceUuId); + if (nodeTypeName != null) { + Model resourceModel = Model.getModelFor(nodeTypeName, serviceNodeTemplate.getMetaData().getValue("type")); + + log.debug("Processing resource " + nodeTypeName + ": " + resourceUuId); + Map serviceMetadata = serviceNodeTemplate.getMetaData().getAllProperties(); + resourceModel.populateModelIdentificationInformation(serviceMetadata); + + idTypeStore.remove(resourceModel.getModelNameVersionId()); + processResourceModels(idTypeStore, resourceModel, resourceNodeTemplates); + + if (csarHelper.getServiceVfList() != null) { + processVfModules(resources, resourceModel, serviceNodeTemplate); + } + + if (hasSubCategoryTunnelXConnect(serviceMetadata) && hasAllottedResource(serviceMetadata)) { + resourceModel.addWidget(new TunnelXconnectWidget()); + } + + resources.addAll(processInstanceGroups(resourceModel, serviceNodeTemplate)); + 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 + */ + List processInstanceGroups(Model resourceModel, NodeTemplate serviceNode) { + List resources = new ArrayList<>(); + if (serviceNode.getSubMappingToscaTemplate() != null) { + List serviceGroups = csarHelper.getGroupsOfOriginOfNodeTemplate(serviceNode); + for (Group group : serviceGroups) { + if (WidgetConfigurationUtil.isSupportedInstanceGroup(group.getType())) { + resources.addAll(processInstanceGroup(resourceModel, group.getMemberNodes(), + group.getMetadata().getAllProperties(), group.getProperties())); + } + } + } + return resources; + } + + /** + * Merge a Map of String values with a Map of TOSCA Property Objects to create a combined Map. If there are + * duplicate keys then the TOSCA Property value takes precedence. + * + * @param stringProps + * initial Map of String property values (e.g. from the TOSCA YAML metadata section) + * @param toscaProps + * Map of TOSCA Property Type Object values to merge in (or overwrite) + * @return a Map of the property values converted to String + */ + private Map mergeProperties(Map stringProps, Map toscaProps) { + Map props = new HashMap<>(stringProps); + toscaProps.forEach((key, toscaProp) -> props.put(key, + toscaProp.getValue() == null ? "" : toscaProp.getValue().toString())); + return props; + } + + /** + * Create an Instance Group Model and populate it with the supplied data. + * + * @param resourceModel + * the Resource node template Model + * @param memberNodes + * the Resources and Widgets belonging to the Group + * @param metaProperties + * the metadata of the Group + * @param properties + * the properties of the Group + * @return the Instance Group and Member resource models + */ + private List processInstanceGroup(Model resourceModel, ArrayList memberNodes, + Map metaProperties, Map properties) { + Resource groupModel = createInstanceGroupModel(mergeProperties(metaProperties, properties)); + resourceModel.addResource(groupModel); + List resources = Stream.of(groupModel).collect(Collectors.toList()); + + if (memberNodes != null && !memberNodes.isEmpty()) { + resources.addAll(generateResourcesAndWidgets(memberNodes, groupModel)); + } + + return resources; + } + + private Resource createInstanceGroupModel(Map properties) { + Resource groupModel = new InstanceGroup(); + groupModel.populateModelIdentificationInformation(properties); + return groupModel; + } + + /** + * @param memberNodes + * @param groupModel + * @return + */ + private List generateResourcesAndWidgets(final ArrayList memberNodes, + final Resource groupModel) { + List resources = new ArrayList<>(); + for (NodeTemplate nodeTemplate : memberNodes) { + String nodeTypeName = normaliseNodeTypeName(nodeTemplate); + Model memberModel = Model.getModelFor(nodeTypeName, nodeTemplate.getMetaData().getValue("type")); + memberModel.populateModelIdentificationInformation(nodeTemplate.getMetaData().getAllProperties()); + + log.debug(String.format("Generating grouped %s (%s) from TOSCA type %s", + memberModel.getClass().getSuperclass().getSimpleName(), memberModel.getClass(), nodeTypeName)); + + addRelatedModel(groupModel, memberModel); + if (memberModel instanceof Resource) { + resources.add((Resource) memberModel); + } + } + return resources; + } + + /** + * Add the supplied Node Template to the Service, provided that it is a valid Resource or Widget. If the Node + * Template is a Resource type, this is also recorded in the supplied nodesById Map. + * + * @param nodesById + * a map of Resource node type names, keyed by UUID + * @param service + * the Service to which the Node Template should be added + * @param nodeTemplate + * the Node Template to add (only if this is a Resource or Widget type) + */ + private void addNodeToService(Map nodesById, Service service, NodeTemplate nodeTemplate) { + String nodeTypeName = normaliseNodeTypeName(nodeTemplate); + Model model = Model.getModelFor(nodeTypeName, nodeTemplate.getMetaData().getValue("type")); + if (model != null) { + if (nodeTemplate.getMetaData() != null) { + model.populateModelIdentificationInformation(nodeTemplate.getMetaData().getAllProperties()); + } + + addRelatedModel(service, model); + if (model instanceof Resource) { + nodesById.put(model.getModelNameVersionId(), nodeTypeName); + } + } + } + + /** + * @param model + * @param relation + */ + private void addRelatedModel(final Model model, final Model relation) { + if (relation instanceof Resource) { + model.addResource((Resource) relation); + } else { + model.addWidget((Widget) relation); + } + } + + /** + * 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); + 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, resourceModel, serviceGroup, serviceNode, (VfModule) groupModel); + } + } + } + + private void processVfModule(List resources, Model model, Group groupDefinition, NodeTemplate serviceNode, + VfModule groupModel) { + groupModel.populateModelIdentificationInformation( + mergeProperties(groupDefinition.getMetadata().getAllProperties(), groupDefinition.getProperties())); + 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 member : members) { + processGroupMembers(groupModel, member); + } + } + + model.addResource(groupModel); // Added group (VfModule) to the (VF) model + // Check if we have already encountered the same VfModule across all the artifacts + if (!resources.contains(groupModel)) { + resources.add(groupModel); + } + } + + private void processGroupMembers(Model group, NodeTemplate member) { + Model resourceNode; + // L3-network inside vf-module to be generated as Widget a special handling. + if (member.getType().contains("org.openecomp.resource.vl")) { + resourceNode = new L3NetworkWidget(); + } else { + resourceNode = Model.getModelFor(member.getType()); + } + if (resourceNode != null && !(resourceNode instanceof Resource)) { + Widget widget = (Widget) resourceNode; + widget.addKey(member.getName()); + // Add the widget element encountered to the Group model + group.addWidget(widget); + } + } + + private String normaliseNodeTypeName(NodeTemplate nodeType) { + String nodeTypeName = nodeType.getType(); + Metadata metadata = nodeType.getMetaData(); + if (metadata != null && hasAllottedResource(metadata.getAllProperties())) { + if (nodeType.getType().contains("org.openecomp.resource.vf.")) { + nodeTypeName = "org.openecomp.resource.vf.allottedResource"; + } + if (nodeType.getType().contains("org.openecomp.resource.vfc.")) { + nodeTypeName = "org.openecomp.resource.vfc.AllottedResource"; + } + } + return nodeTypeName; + } + + private boolean hasAllottedResource(Map metadata) { + return ALLOTTED_RESOURCE.equals(metadata.get(CATEGORY)); + } + + private boolean hasSubCategoryTunnelXConnect(Map metadata) { + return TUNNEL_XCONNECT.equals(metadata.get(SUBCATEGORY)); + } + + /** + * Create a Map of property name against String property value from the input Map + * + * @param inputMap + * The input Map + * @return Map of property name against String property value + */ + private Map populateStringProperties(Map inputMap) { + return inputMap.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, + e -> e.getValue().getValue() == null ? "" : e.getValue().getValue().toString())); + } + + /** + * @param idTypeStore + * @param resourceModel + * @param resourceNodeTemplates + */ + private void processResourceModels(Map idTypeStore, Model resourceModel, + List resourceNodeTemplates) { + boolean foundProvidingService = false; + + for (NodeTemplate resourceNodeTemplate : resourceNodeTemplates) { + String nodeTypeName = normaliseNodeTypeName(resourceNodeTemplate); + Metadata metaData = resourceNodeTemplate.getMetaData(); + String metaDataType = Optional.ofNullable(metaData).map(m -> m.getValue("type")).orElse(nodeTypeName); + Model resourceNode = Model.getModelFor(nodeTypeName, metaDataType); + foundProvidingService |= processModel(idTypeStore, resourceModel, resourceNodeTemplate, nodeTypeName, + metaData, resourceNode); + } + + if (resourceModel instanceof AllotedResource && !foundProvidingService) { + throw new IllegalArgumentException( + String.format(GENERATOR_AAI_PROVIDING_SERVICE_MISSING, resourceModel.getModelId())); + } + } + + private boolean processModel(Map idTypeStore, Model resourceModel, + NodeTemplate resourceNodeTemplate, String nodeTypeName, Metadata metaData, Model resourceNode) { + boolean foundProvidingService = false; + if (resourceNode instanceof ProvidingService) { + foundProvidingService = true; + processProvidingService(resourceModel, resourceNodeTemplate, resourceNode); + } else if (resourceNode instanceof Resource && !(resourceNode.getWidgetType().equals(Widget.Type.L3_NET))) { + if (metaData != null) { + resourceNode.populateModelIdentificationInformation(metaData.getAllProperties()); + } + idTypeStore.put(resourceNode.getModelNameVersionId(), nodeTypeName); + resourceModel.addResource((Resource) resourceNode); + } + return foundProvidingService; + } + + private void processProvidingService(Model resourceModel, NodeTemplate resourceNodeTemplate, Model resourceNode) { + 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, resourceModel.getModelId())); + } + Map properties = populateStringProperties(nodeProperties); + properties.put(VERSION, "1.0"); + resourceNode.populateModelIdentificationInformation(properties); + resourceModel.addResource((Resource) resourceNode); + } } 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 19a08f2..67c0b2f 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 @@ -102,8 +102,8 @@ public class AaiArtifactGenerator implements ArtifactGenerator { * @return the generated Artifacts */ private GenerationData generateService(final String serviceVersion, ISdcCsarHelper csarHelper) { - List serviceNodes = csarHelper.getServiceNodeTemplates(); - if (serviceNodes == null) { + List serviceNodeTemplates = csarHelper.getServiceNodeTemplates(); + if (serviceNodeTemplates == null) { throw new IllegalArgumentException(GENERATOR_AAI_ERROR_MISSING_SERVICE_TOSCA); } @@ -115,12 +115,12 @@ public class AaiArtifactGenerator implements ArtifactGenerator { Map idTypeStore = new HashMap<>(); ArtifactGeneratorToscaParser parser = new ArtifactGeneratorToscaParser(csarHelper); - if (!serviceNodes.isEmpty()) { - parser.processServiceTosca(serviceModel, idTypeStore, serviceNodes); + if (!serviceNodeTemplates.isEmpty()) { + parser.processServiceTosca(serviceModel, idTypeStore, serviceNodeTemplates); } // Process the resource TOSCA files - List resources = parser.processResourceToscas(serviceNodes, idTypeStore); + List resources = parser.processResourceToscas(serviceNodeTemplates, idTypeStore); MDC.put(MDC_PARAM_MODEL_INFO, serviceModel.getModelName() + "," + getArtifactLabel(serviceModel)); String aaiServiceModel = modelGenerator.generateModelFor(serviceModel); diff --git a/src/test/java/org/onap/aai/babel/parser/TestArtifactGeneratorToscaParser.java b/src/test/java/org/onap/aai/babel/parser/TestArtifactGeneratorToscaParser.java index 822cda5..6cf6d31 100644 --- a/src/test/java/org/onap/aai/babel/parser/TestArtifactGeneratorToscaParser.java +++ b/src/test/java/org/onap/aai/babel/parser/TestArtifactGeneratorToscaParser.java @@ -34,7 +34,6 @@ import org.junit.Test; import org.mockito.Mockito; import org.onap.aai.babel.xml.generator.data.WidgetConfigurationUtil; import org.onap.aai.babel.xml.generator.model.InstanceGroup; -import org.onap.aai.babel.xml.generator.model.Model; import org.onap.aai.babel.xml.generator.model.Resource; import org.onap.sdc.tosca.parser.api.ISdcCsarHelper; import org.onap.sdc.toscaparser.api.Group; @@ -47,97 +46,94 @@ import org.onap.sdc.toscaparser.api.SubstitutionMappings; public class TestArtifactGeneratorToscaParser { - private static final String TEST_UUID = "1234"; - - /** - * 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")); - ArtifactGeneratorToscaParser parser = new ArtifactGeneratorToscaParser(null); - parser.processServiceTosca(null, Collections.emptyMap(), nodeTemplateList); - parser.processResourceToscas(nodeTemplateList, null); - } - - /** - * Process a dummy Group object for a Service Resource. - */ - @Test - public void testInstanceGroups() { - final String instanceGroupType = "org.openecomp.groups.ResourceInstanceGroup"; - Properties props = new Properties(); - props.put("AAI.instance-group-types", instanceGroupType); - WidgetConfigurationUtil.setFilterConfig(props); - - ISdcCsarHelper helper = Mockito.mock(ISdcCsarHelper.class); - NodeTemplate serviceNodeTemplate = Mockito.mock(NodeTemplate.class); - SubstitutionMappings sm = Mockito.mock(SubstitutionMappings.class); - - Mockito.when(serviceNodeTemplate.getSubMappingToscaTemplate()).thenReturn(sm); - - NodeTemplate serviceNode = buildNodeTemplate("service", "org.openecomp.resource.cr.a-collection-resource"); - Mockito.when(helper.getNodeTemplateByName(serviceNode.getName())).thenReturn(serviceNodeTemplate); - - ArrayList groups = new ArrayList<>(); - groups.add(buildGroup("group", instanceGroupType)); - Mockito.when(helper.getGroupsOfOriginOfNodeTemplate(serviceNode)).thenReturn(groups); - - ArtifactGeneratorToscaParser parser = new ArtifactGeneratorToscaParser(helper); - Model resourceModel = new InstanceGroup(); - List resources = parser.processInstanceGroups(resourceModel, serviceNode); - - assertThat(resources.size(), is(1)); - Resource resource = resources.get(0); - assertThat(resource.getModelNameVersionId(), is(equalTo(TEST_UUID))); - } - - private NodeTemplate buildNodeTemplate(String name, String type) { - LinkedHashMap nodeTemplateMap = new LinkedHashMap<>(); - nodeTemplateMap.put(name, buildMap("type", type)); - nodeTemplateMap.put(type, buildNodeTemplateCustomDefs()); - return new NodeTemplate(name, nodeTemplateMap, nodeTemplateMap, null, null); - } - - private LinkedHashMap buildNodeTemplateCustomDefs() { - LinkedHashMap customDefs = buildCustomDefs(); - customDefs.put("attributes", null); - customDefs.put("requirements", null); - customDefs.put("capabilities", null); - customDefs.put("artifacts", null); - return customDefs; - } - - private Group buildGroup(String name, String type) { - LinkedHashMap template = new LinkedHashMap<>(); - template.put("type", type); - template.put("metadata", new LinkedHashMap<>()); - template.put("properties", buildMap("UUID", TEST_UUID)); - LinkedHashMap customDefMap = buildMap(name, template); - customDefMap.put(type, buildGroupCustomDefs()); - return new Group(name, template, null, customDefMap); - } - - private LinkedHashMap buildGroupCustomDefs() { - LinkedHashMap customDefs = buildCustomDefs(); - customDefs.put("members", null); - return customDefs; - } - - private LinkedHashMap buildCustomDefs() { - LinkedHashMap customDefs = new LinkedHashMap<>(); - customDefs.put("derived_from", null); - customDefs.put("metadata", null); - customDefs.put("version", null); - customDefs.put("description", null); - customDefs.put("interfaces", null); - customDefs.put("properties", buildMap("UUID", buildMap("type", "java.lang.String"))); - return customDefs; - } - - private LinkedHashMap buildMap(String key, Object value) { - LinkedHashMap map = new LinkedHashMap<>(); - map.put(key, value); - return map; - } + private static final String TEST_UUID = "1234"; + + /** + * 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")); + ArtifactGeneratorToscaParser parser = new ArtifactGeneratorToscaParser(null); + parser.processServiceTosca(null, Collections.emptyMap(), nodeTemplateList); + parser.processResourceToscas(nodeTemplateList, null); + } + + /** + * Process a dummy Group object for a Service Resource. + */ + @Test + public void testInstanceGroups() { + final String instanceGroupType = "org.openecomp.groups.ResourceInstanceGroup"; + Properties props = new Properties(); + props.put("AAI.instance-group-types", instanceGroupType); + WidgetConfigurationUtil.setFilterConfig(props); + + ISdcCsarHelper helper = Mockito.mock(ISdcCsarHelper.class); + SubstitutionMappings sm = Mockito.mock(SubstitutionMappings.class); + + NodeTemplate serviceNode = buildNodeTemplate("service", "org.openecomp.resource.cr.a-collection-resource"); + serviceNode.setSubMappingToscaTemplate(sm); + Mockito.when(helper.getNodeTemplateByName(serviceNode.getName())).thenReturn(serviceNode); + + ArrayList groups = new ArrayList<>(); + groups.add(buildGroup("group", instanceGroupType)); + Mockito.when(helper.getGroupsOfOriginOfNodeTemplate(serviceNode)).thenReturn(groups); + + ArtifactGeneratorToscaParser parser = new ArtifactGeneratorToscaParser(helper); + List resources = parser.processInstanceGroups(new InstanceGroup(), serviceNode); + + assertThat(resources.size(), is(1)); + Resource resource = resources.get(0); + assertThat(resource.getModelNameVersionId(), is(equalTo(TEST_UUID))); + } + + private NodeTemplate buildNodeTemplate(String name, String type) { + LinkedHashMap nodeTemplateMap = new LinkedHashMap<>(); + nodeTemplateMap.put(name, buildMap("type", type)); + nodeTemplateMap.put(type, buildNodeTemplateCustomDefs()); + return new NodeTemplate(name, nodeTemplateMap, nodeTemplateMap, null, null); + } + + private LinkedHashMap buildNodeTemplateCustomDefs() { + LinkedHashMap customDefs = buildCustomDefs(); + customDefs.put("attributes", null); + customDefs.put("requirements", null); + customDefs.put("capabilities", null); + customDefs.put("artifacts", null); + return customDefs; + } + + private Group buildGroup(String name, String type) { + LinkedHashMap template = new LinkedHashMap<>(); + template.put("type", type); + template.put("metadata", new LinkedHashMap<>()); + template.put("properties", buildMap("UUID", TEST_UUID)); + LinkedHashMap customDefMap = buildMap(name, template); + customDefMap.put(type, buildGroupCustomDefs()); + return new Group(name, template, null, customDefMap); + } + + private LinkedHashMap buildGroupCustomDefs() { + LinkedHashMap customDefs = buildCustomDefs(); + customDefs.put("members", null); + return customDefs; + } + + private LinkedHashMap buildCustomDefs() { + LinkedHashMap customDefs = new LinkedHashMap<>(); + customDefs.put("derived_from", null); + customDefs.put("metadata", null); + customDefs.put("version", null); + customDefs.put("description", null); + customDefs.put("interfaces", null); + customDefs.put("properties", buildMap("UUID", buildMap("type", "java.lang.String"))); + return customDefs; + } + + private LinkedHashMap buildMap(String key, Object value) { + LinkedHashMap map = new LinkedHashMap<>(); + map.put(key, value); + return map; + } } 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 8d10412..297bb4d 100644 --- a/src/test/java/org/onap/aai/babel/service/CsarToXmlConverterTest.java +++ b/src/test/java/org/onap/aai/babel/service/CsarToXmlConverterTest.java @@ -53,177 +53,180 @@ 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"; - - static { - if (System.getProperty("APP_HOME") == null) { - System.setProperty("APP_HOME", "."); - } - } - - // The class to be tested. - private CsarToXmlConverter converter; - - @Rule - public ExpectedException exception = ExpectedException.none(); - - @Before - 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(); - } - - @After - public void tearDown() { - converter = null; - } - - @Test(expected = NullPointerException.class) - public void testNullArtifactSupplied() throws CsarConverterException { - converter.generateXmlFromCsar(null, null, null); - } - - @Test(expected = NullPointerException.class) - public void testMissingName() throws CsarConverterException, IOException { - converter.generateXmlFromCsar(CsarTest.SD_WAN_CSAR_FILE.getContent(), null, null); - } - - @Test(expected = NullPointerException.class) - public void testMissingVersion() throws CsarConverterException, IOException { - converter.generateXmlFromCsar(CsarTest.SD_WAN_CSAR_FILE.getContent(), INCORRECT_CSAR_NAME, null); - } - - @Test(expected = CsarConverterException.class) - public void testNoPayloadExists() throws CsarConverterException { - converter.generateXmlFromCsar(new byte[0], INCORRECT_CSAR_NAME, SERVICE_VERSION); - } - - @Test(expected = CsarConverterException.class) - public void testCsarFileHasNoYmlFiles() throws CsarConverterException, IOException { - converter.generateXmlFromCsar(CsarTest.NO_YAML_FILES.getContent(), CsarTest.NO_YAML_FILES.getName(), - SERVICE_VERSION); - } - - /** - * Test that an Exception is thrown when the Artifact Generator properties are not present. - * - * @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("Cannot generate artifacts. System property artifactgenerator.config not configured"); - - // Unset the required system property - System.clearProperty(ArtifactGeneratorToscaParser.PROPERTY_ARTIFACT_GENERATOR_CONFIG_FILE); - converter.generateXmlFromCsar(CsarTest.SD_WAN_CSAR_FILE.getContent(), CsarTest.SD_WAN_CSAR_FILE.getName(), - 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 { - converter.generateXmlFromCsar(CsarTest.MISSING_METADATA_CSAR.getContent(), - CsarTest.MISSING_METADATA_CSAR.getName(), SERVICE_VERSION); - } - - @Test - public void generateXmlFromSdWanCsar() throws IOException, CsarConverterException { - List filesToLoad = new ArrayList<>(); - filesToLoad.add("AAI-SD-WAN-Service-Test-service-1.0.xml"); - filesToLoad.add("AAI-SdWanTestVsp..DUMMY..module-0-resource-2.xml"); - filesToLoad.add("AAI-Tunnel_XConnTest-resource-2.0.xml"); - filesToLoad.add("AAI-SD-WAN-Test-VSP-resource-1.0.xml"); - assertThatGeneratedFilesMatchExpected(createExpectedXmlFiles(filesToLoad), CsarTest.SD_WAN_CSAR_FILE); - } - - @Test - public void generateXmlFromNetworkCollectionCsar() throws IOException, CsarConverterException { - List filesToLoad = new ArrayList<>(); - filesToLoad.add("AAI-TEST SVC_1-service-1.0.xml"); - filesToLoad.add("AAI-TEST CR_1-resource-7.0.xml"); - filesToLoad.add("AAI-testcr_1..NetworkCollection..0-resource-1.xml"); - filesToLoad.add("AAI-ExtVL-resource-40.0.xml"); - assertThatGeneratedFilesMatchExpected(createExpectedXmlFiles(filesToLoad), CsarTest.NETWORK_COLLECTION_CSAR_FILE); - } - - @Test - public void generatePortMirrorConfigurationModel() - throws CsarConverterException, IOException, XmlArtifactGenerationException { - List filesToLoad = new ArrayList<>(); - filesToLoad.add("AAI-Port Mirror_Test-service-1.0.xml"); - filesToLoad.add("AAI-Port Mirroring Configuration-resource-35.0.xml"); - assertThatGeneratedFilesMatchExpected(createExpectedXmlFiles(filesToLoad), CsarTest.PORT_MIRROR_CSAR); - } - - public Matcher matches(final String expected) { - return new BaseMatcher() { - protected String theExpected = expected; - - @Override - public boolean matches(Object item) { - return new ArtifactTestUtils().compareXmlStrings((String) item, theExpected); - } - - @Override - public void describeTo(Description description) { - description.appendText(theExpected.toString()); - } - }; - } - - private Map createExpectedXmlFiles(List filesToLoad) throws IOException { - Map xmlMap = new HashMap<>(); - for (String filename : filesToLoad) { - xmlMap.put(filename, new ArtifactTestUtils().loadResourceAsString("generatedXml/" + filename)); - } - return xmlMap; - } - - private void assertThatGeneratedFilesMatchExpected(Map expectedXmlFiles, CsarTest csarFile) - throws CsarConverterException, IOException { - List generatedArtifacts = - converter.generateXmlFromCsar(csarFile.getContent(), csarFile.getName(), SERVICE_VERSION); - assertThat("Incorrect number of files generated", // - generatedArtifacts.size(), is(equalTo(expectedXmlFiles.size()))); - for (BabelArtifact generated : generatedArtifacts) { - String fileName = generated.getName(); - String expectedXml = expectedXmlFiles.get(fileName); - assertThat("Missing expected content for " + generated.getName(), expectedXml, is(not(nullValue()))); - assertThat("The content of " + generated.getName() + " must match the expected content", - generated.getPayload(), matches(expectedXml)); - } - } + 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"; + + static { + if (System.getProperty("APP_HOME") == null) { + System.setProperty("APP_HOME", "."); + } + } + + // The class to be tested. + private CsarToXmlConverter converter; + + @Rule + public ExpectedException exception = ExpectedException.none(); + + @Before + 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(); + } + + @After + public void tearDown() { + converter = null; + } + + @Test(expected = NullPointerException.class) + public void testNullArtifactSupplied() throws CsarConverterException { + converter.generateXmlFromCsar(null, null, null); + } + + @Test(expected = NullPointerException.class) + public void testMissingName() throws CsarConverterException, IOException { + converter.generateXmlFromCsar(CsarTest.SD_WAN_CSAR_FILE.getContent(), null, null); + } + + @Test(expected = NullPointerException.class) + public void testMissingVersion() throws CsarConverterException, IOException { + converter.generateXmlFromCsar(CsarTest.SD_WAN_CSAR_FILE.getContent(), INCORRECT_CSAR_NAME, null); + } + + @Test(expected = CsarConverterException.class) + public void testNoPayloadExists() throws CsarConverterException { + converter.generateXmlFromCsar(new byte[0], INCORRECT_CSAR_NAME, SERVICE_VERSION); + } + + @Test(expected = CsarConverterException.class) + public void testCsarFileHasNoYmlFiles() throws CsarConverterException, IOException { + converter.generateXmlFromCsar(CsarTest.NO_YAML_FILES.getContent(), CsarTest.NO_YAML_FILES.getName(), + SERVICE_VERSION); + } + + /** + * Test that an Exception is thrown when the Artifact Generator properties are not present. + * + * @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("Cannot generate artifacts. System property artifactgenerator.config not configured"); + + // Unset the required system property + System.clearProperty(ArtifactGeneratorToscaParser.PROPERTY_ARTIFACT_GENERATOR_CONFIG_FILE); + converter.generateXmlFromCsar(CsarTest.SD_WAN_CSAR_FILE.getContent(), CsarTest.SD_WAN_CSAR_FILE.getName(), + 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 { + converter.generateXmlFromCsar(CsarTest.MISSING_METADATA_CSAR.getContent(), + CsarTest.MISSING_METADATA_CSAR.getName(), SERVICE_VERSION); + } + + @Test + public void generateXmlFromSdWanCsar() throws IOException, CsarConverterException { + List filesToLoad = new ArrayList<>(); + filesToLoad.add("AAI-SD-WAN-Service-Test-service-1.0.xml"); + filesToLoad.add("AAI-SdWanTestVsp..DUMMY..module-0-resource-2.xml"); + filesToLoad.add("AAI-Tunnel_XConnTest-resource-2.0.xml"); + filesToLoad.add("AAI-SD-WAN-Test-VSP-resource-1.0.xml"); + assertThatGeneratedFilesMatchExpected(createExpectedXmlFiles(filesToLoad), CsarTest.SD_WAN_CSAR_FILE); + } + + @Test + public void generateXmlFromNetworkCollectionCsar() throws IOException, CsarConverterException { + List filesToLoad = new ArrayList<>(); + filesToLoad.add("AAI-TEST SVC_1-service-1.0.xml"); + filesToLoad.add("AAI-TEST CR_1-resource-7.0.xml"); + filesToLoad.add("AAI-testcr_1..NetworkCollection..0-resource-1.xml"); + filesToLoad.add("AAI-ExtVL-resource-40.0.xml"); + assertThatGeneratedFilesMatchExpected(createExpectedXmlFiles(filesToLoad), + CsarTest.NETWORK_COLLECTION_CSAR_FILE); + } + + @Test + public void generatePortMirrorConfigurationModel() + throws CsarConverterException, IOException, XmlArtifactGenerationException { + List filesToLoad = new ArrayList<>(); + filesToLoad.add("AAI-Port Mirror_Test-service-1.0.xml"); + filesToLoad.add("AAI-Port Mirroring Configuration-resource-35.0.xml"); + assertThatGeneratedFilesMatchExpected(createExpectedXmlFiles(filesToLoad), CsarTest.PORT_MIRROR_CSAR); + } + + public Matcher matches(final String expected) { + return new BaseMatcher() { + protected String theExpected = expected; + + @Override + public boolean matches(Object item) { + return new ArtifactTestUtils().compareXmlStrings((String) item, theExpected); + } + + @Override + public void describeTo(Description description) { + description.appendText(theExpected.toString()); + } + }; + } + + private Map createExpectedXmlFiles(List filesToLoad) throws IOException { + Map xmlMap = new HashMap<>(); + for (String filename : filesToLoad) { + xmlMap.put(filename, new ArtifactTestUtils().loadResourceAsString("generatedXml/" + filename)); + } + return xmlMap; + } + + private void assertThatGeneratedFilesMatchExpected(Map expectedXmlFiles, CsarTest csarFile) + throws CsarConverterException, IOException { + List generatedArtifacts = converter.generateXmlFromCsar(csarFile.getContent(), + csarFile.getName(), SERVICE_VERSION); + assertThat("Incorrect number of files generated", // + generatedArtifacts.size(), is(equalTo(expectedXmlFiles.size()))); + for (BabelArtifact generated : generatedArtifacts) { + String fileName = generated.getName(); + String expectedXml = expectedXmlFiles.get(fileName); + assertThat("Missing expected content for " + generated.getName(), expectedXml, is(not(nullValue()))); + assertThat("The content of " + generated.getName() + " must match the expected content", + generated.getPayload(), matches(expectedXml)); + } + } }