diff options
Diffstat (limited to 'common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap')
7 files changed, 1595 insertions, 0 deletions
diff --git a/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/GeneratorManager.java b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/GeneratorManager.java new file mode 100644 index 0000000000..e0049bd719 --- /dev/null +++ b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/GeneratorManager.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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.sdc.generator; + +import static org.onap.sdc.generator.util.ArtifactGeneratorUtil.logError; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.onap.sdc.generator.data.ArtifactType; +import org.onap.sdc.generator.data.GeneratorConfiguration; +import org.onap.sdc.generator.data.GeneratorConstants; +import org.onap.sdc.generator.intf.ArtifactGenerator; +import org.onap.sdc.generator.intf.Generator; +import org.onap.sdc.generator.util.ArtifactGeneratorUtil; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.reflections.Reflections; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +public class GeneratorManager { + + private static Logger log = LoggerFactory.getLogger(GeneratorManager.class.getName()); + private static Map<ArtifactType, ArtifactGenerator> generators = new HashMap<>(); + + /** + * Gets active artifact generators. + * + * @param clientConfiguration the client configuration + * @return the active artifact generators + * @throws Exception the exception + */ + public static List<ArtifactGenerator> getActiveArtifactGenerators(String clientConfiguration) + throws Exception { + + if (generators.isEmpty()) { + log.debug("Getting list of active generators"); + Reflections reflections = new Reflections("org.onap.sdc.generator"); + Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(Generator.class); + for (Class<?> clazz : annotated) { + Generator generator = clazz.getAnnotation(Generator.class); + generators.put(generator.artifactType(), (ArtifactGenerator) clazz.newInstance()); + } + } + + log.debug("Parsing generator configuration from the client configuration : " + + clientConfiguration); + GeneratorConfiguration gf = getGeneratorConfiguration(clientConfiguration); + List<ArtifactGenerator> generatorList = new ArrayList<>(); + if (gf.getArtifactTypes() != null && !gf.getArtifactTypes().isEmpty()) { + for (ArtifactType type : gf.getArtifactTypes()) { + if (generators.get(type) != null) { + generatorList.add(generators.get(type)); + } + } + } + + return generatorList; + } + + private static GeneratorConfiguration getGeneratorConfiguration(String jsonConfiguration) { + try { + return new ObjectMapper().readValue(jsonConfiguration, GeneratorConfiguration.class); + } catch (Exception exception) { + ArtifactGeneratorUtil + .logError(GeneratorConstants.GENERATOR_ERROR_INVALID_CLIENT_CONFIGURATION, exception); + throw new IllegalArgumentException( + GeneratorConstants.GENERATOR_ERROR_INVALID_CLIENT_CONFIGURATION, exception); + } + } + +} diff --git a/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/GeneratorTask.java b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/GeneratorTask.java new file mode 100644 index 0000000000..66004ec89b --- /dev/null +++ b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/GeneratorTask.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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.sdc.generator; + +import org.onap.sdc.generator.data.Artifact; +import org.onap.sdc.generator.data.GenerationData; +import org.onap.sdc.generator.intf.ArtifactGenerator; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; + +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.RecursiveTask; + +public class GeneratorTask extends RecursiveTask<GenerationData> { + + private static Logger log = LoggerFactory.getLogger(GeneratorTask.class.getName()); + + List<Artifact> input; + List<ArtifactGenerator> generators; + Map<String, String> additionalParams; + + /** + * Instantiates a new Generator task. + * + * @param generators the generators + * @param input the input + * @param additionalParams the additional params + */ + public GeneratorTask(List<ArtifactGenerator> generators, List<Artifact> input, + Map<String, String> additionalParams ) { + this.input = input; + this.generators = generators; + this.additionalParams = additionalParams; + } + + @Override + protected GenerationData compute() { + if (generators.size() == 1) { + log.debug("Instantiating Generator : " + generators.get(0).getClass().getName()); + return generators.remove(0).generateArtifact(input, additionalParams); + } else { + LinkedList<ArtifactGenerator> generator = new LinkedList<>(); + generator.add(generators.remove(0)); + GeneratorTask tobeDone = new GeneratorTask(generator, input, additionalParams); + GeneratorTask tobeForked = + new GeneratorTask(new LinkedList<ArtifactGenerator>(generators), input, additionalParams); + tobeForked.fork(); + GenerationData output = tobeDone.compute(); + output.add(tobeForked.join()); + return output; + } + } + +} diff --git a/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/MockArtifactGenerator.java b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/MockArtifactGenerator.java new file mode 100644 index 0000000000..9753c26a03 --- /dev/null +++ b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/MockArtifactGenerator.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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.sdc.generator; + +import org.onap.sdc.generator.data.GenerationData; +import org.onap.sdc.generator.intf.ArtifactGenerator; +import org.onap.sdc.generator.data.Artifact; +import org.onap.sdc.generator.data.ArtifactType; +import org.onap.sdc.generator.data.GeneratorUtil; +import org.onap.sdc.generator.data.GroupType; +import org.onap.sdc.generator.intf.Generator; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +@Generator(artifactType = ArtifactType.OTHER) +public class MockArtifactGenerator implements ArtifactGenerator { + + @Override + public GenerationData generateArtifact(List<Artifact> input, + Map<String, String> additionalParams) { + final GenerationData data = new GenerationData(); + + String staticArtifactName = "MOCK_Generator-Static-Artifact.xml"; + String staticArtifactLabel = "MOCK-Generator-Static-Artifact"; + final String dynamicArtifactName = "MOCK_Generator-Dynamic-Artifact.xml"; + final String dynamicArtifactLabel = "MOCK-Generator-Dynamic-Artifact"; + String staticArtifact = getStaticArtifact(); + String dynamicArtifact = getDynamicArtifact(); + + Artifact staticArtifactModel = new Artifact(ArtifactType.OTHER.name(), GroupType.OTHER.name(), + GeneratorUtil.checkSum(staticArtifact.getBytes()), + GeneratorUtil.encode(staticArtifact.getBytes())); + staticArtifactModel.setName(staticArtifactName); + staticArtifactModel.setLabel(staticArtifactLabel); + staticArtifactModel.setDescription("Mock Generator"); + + Artifact dynamicArtifactModel = new Artifact(ArtifactType.OTHER.name(), GroupType.OTHER.name(), + GeneratorUtil.checkSum(dynamicArtifact.getBytes()), + GeneratorUtil.encode(dynamicArtifact.getBytes())); + dynamicArtifactModel.setName(dynamicArtifactName); + dynamicArtifactModel.setLabel(dynamicArtifactLabel); + dynamicArtifactModel.setDescription("Mock Generator"); + + data.add(staticArtifactModel); + data.add(dynamicArtifactModel); + + return data; + + } + + private String getStaticArtifact() { + return "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><theObj><name>Hi I'm Static</name></theObj>"; + } + + private String getDynamicArtifact() { + return + "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><theObj><name>Hi I'm Static</name><timestamp>" + + new Date() + "</timestamp></theObj>"; + } + +} diff --git a/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/aai/AaiArtifactGenerator.java b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/aai/AaiArtifactGenerator.java new file mode 100644 index 0000000000..995d0846be --- /dev/null +++ b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/aai/AaiArtifactGenerator.java @@ -0,0 +1,684 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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.sdc.generator.aai; + +import static org.onap.sdc.generator.util.ArtifactGeneratorUtil.logError; + +import org.onap.sdc.generator.aai.model.AllotedResource; +import org.onap.sdc.generator.aai.model.ProvidingService; +import org.onap.sdc.generator.aai.model.Resource; +import org.onap.sdc.generator.aai.model.Service; +import org.onap.sdc.generator.aai.model.Widget; +import org.onap.sdc.generator.aai.tosca.GroupDefinition; +import org.onap.sdc.generator.aai.types.ModelType; +import org.onap.sdc.generator.data.AdditionalParams; +import org.onap.sdc.generator.data.ArtifactType; +import org.onap.sdc.generator.data.GenerationData; +import org.onap.sdc.generator.data.GeneratorConstants; +import org.onap.sdc.generator.data.GroupType; +import org.onap.sdc.generator.data.WidgetConfigurationUtil; +import org.onap.sdc.generator.intf.ArtifactGenerator; +import org.onap.sdc.generator.intf.Generator; +import org.onap.sdc.generator.util.ArtifactGeneratorUtil; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.onap.sdc.generator.aai.model.L3NetworkWidget; +import org.onap.sdc.generator.aai.model.Model; +import org.onap.sdc.generator.aai.model.TunnelXconnectWidget; +import org.onap.sdc.generator.aai.model.VfModule; +import org.onap.sdc.generator.aai.tosca.NodeTemplate; +import org.onap.sdc.generator.aai.tosca.ToscaTemplate; +import org.onap.sdc.generator.data.Artifact; +import org.onap.sdc.generator.data.GeneratorUtil; +import org.onap.sdc.generator.logging.annotations.Audit; +import org.slf4j.MDC; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +@Generator(artifactType = ArtifactType.AAI) +public class AaiArtifactGenerator implements ArtifactGenerator { + + private static Logger log = LoggerFactory.getLogger(AaiArtifactGenerator.class.getName()); + + /** + * Implementation of the method to generate AAI artifacts. + * + * @param input List of input tosca files + * @return Translated/Error data as a {@link GenerationData} object + */ + @Override + @Audit + public GenerationData generateArtifact(List<Artifact> input, + Map<String, String> additionalParams) { + try { + if (input != null && input.size() != 0 ) { + ArtifactGeneratorUtil.initializeArtifactLoggingContext(input.get(0)); + } + initWidgetConfiguration(); + return generateArtifactInternal(input, additionalParams); + } catch (Exception exception) { + ArtifactGeneratorUtil.logError(exception.getMessage(), exception); + GenerationData generationData = new GenerationData(); + generationData.add(ArtifactType.AAI.name(), exception.getMessage()); + return generationData; + } + } + + /** + * Helper method to generate AAI artifacts. + * + * @param input List of input tosca files + * @return Translated/Error data as a {@link GenerationData} object + */ + private GenerationData generateArtifactInternal(List<Artifact> input, + Map<String, String> additionalParams) { + final GenerationData generationData = new GenerationData(); + + List<Resource> resources = new LinkedList<>(); + Map<String, String> idTypeStore = new HashMap<>(); + Map<String, String> resourcesVersion = new HashMap<>(); + + List<ToscaTemplate> toscas = new LinkedList<>(); + + String serviceVersion = additionalParams.get(AdditionalParams.ServiceVersion.getName()); + if (serviceVersion == null) { + throw new IllegalArgumentException(GeneratorConstants + .GENERATOR_AAI_ERROR_MISSING_SERVICE_VERSION); + } else { + String versionRegex = "^[1-9]\\d*(\\.0)$"; + if (! (serviceVersion.matches(versionRegex))) { + throw new IllegalArgumentException(String + .format(GeneratorConstants + .GENERATOR_AAI_INVALID_SERVICE_VERSION)); + } + } + + for (Artifact inputArtifact : input) { + ToscaTemplate tosca = getToscaModel(inputArtifact, serviceVersion); + validateTosca(tosca, inputArtifact); + ToscaTemplate processedTosca = preProcessingTosca(tosca); + toscas.add(processedTosca); + } + + //Get the service tosca from the list of artifacts + ToscaTemplate serviceTosca = getServiceTosca(toscas); + if (serviceTosca == null) { + throw new IllegalArgumentException(GeneratorConstants + .GENERATOR_AAI_ERROR_MISSING_SERVICE_TOSCA); + } + + Service service = new Service(); + //Populate basic service model metadata + service.populateModelIdentificationInformation(serviceTosca.getMetadata()); + + if (serviceTosca.getTopology_template() != null + && serviceTosca.getTopology_template().getNode_templates() != null) { + processServiceTosca(service, idTypeStore,resourcesVersion, serviceTosca,resources); + } + validateResourceToscaAgainstService(idTypeStore, toscas); + + //Process the resource tosca files + int counter = 0; + List<Resource> currentToscaResources = new LinkedList<>(); + while (toscas.size() > 0) { + ToscaTemplate resourceTemplate = toscas.remove(0); + String resourceUuId = resourceTemplate.getMetadata().get("UUID"); + String mapValue = idTypeStore.get(resourceUuId); + if (mapValue == null) { + log.warn( + "Additional tosca file found with resource version id : " + + resourceUuId); + continue; + } + //update resource version with version from service tosca + String resourceVersion = resourcesVersion.get(resourceUuId); + resourceTemplate.getMetadata().put("version", resourceVersion); + Model model = Model.getModelFor(idTypeStore.get(resourceTemplate.getModelVersionId())); + + log.debug("Inside Resource artifact generation for resource"); + model.populateModelIdentificationInformation( + resourceTemplate.getMetadata()); //Get base resource metadata information + //Found model from the type store so removing the same + idTypeStore.remove(model.getModelNameVersionId()); + if (resourceTemplate.getTopology_template() != null + && resourceTemplate.getTopology_template().getNode_templates() != null) { + processVfTosca(idTypeStore, resourceTemplate, model); + } + + //Process group information from tosca for vfModules + if (resourceTemplate.getTopology_template() != null + && resourceTemplate.getTopology_template().getGroups() != null) { + processVfModule(resources, currentToscaResources, resourceTemplate, model); + } else { + model.getWidgets().clear(); + } + + if ("Tunnel XConnect".equals(resourceTemplate.getMetadata().get("subcategory")) + && "Allotted Resource".equals(resourceTemplate.getMetadata().get("category"))) { + model.addWidget(new TunnelXconnectWidget()); + } + + resources.add((Resource) model); + currentToscaResources + .clear(); //Clearing the current tosca resource list for the next iteration + counter = 0; + } + + AaiModelGenerator modelGenerator = AaiModelGenerator.getInstance(); + //Generate AAI XML service model + MDC.put(GeneratorConstants.ARTIFACT_MODEL_INFO , service.getModelName() + "," + getArtifactLabel(service)); + String aaiServiceModel = modelGenerator.generateModelFor(service); + generationData.add(getServiceArtifact(service, aaiServiceModel)); + + //Generate AAI XML resource model + for (Resource res : resources) { + MDC.put(GeneratorConstants.ARTIFACT_MODEL_INFO , res.getModelName() + "," + getArtifactLabel(res)); + String aaiResourceModel = modelGenerator.generateModelFor(res); + generationData.add(getResourceArtifact(res, aaiResourceModel)); + } + + //Resetting logging parameters since they get overridden while writing metrics logs + // recursively for service, resource and widgets. + if (input != null && input.size() != 0 ) { + ArtifactGeneratorUtil.initializeArtifactLoggingContext(input.get(0)); + } + + return generationData; + } + + private void validateResourceToscaAgainstService(Map<String, String> idTypeStore, + List<ToscaTemplate> toscas) { + Iterator entries = idTypeStore.entrySet().iterator(); + while (entries.hasNext()) { + Map.Entry entry = (Map.Entry) entries.next(); + String resourceUuidFromService = (String)entry.getKey(); + Iterator<ToscaTemplate> itr = toscas.iterator(); + boolean toscaFound = false; + while (itr.hasNext()) { + ToscaTemplate toscaTemplate = itr.next(); + String resourceUuId = toscaTemplate.getMetadata().get("UUID"); + if (resourceUuidFromService.equals(resourceUuId)) { + toscaFound = true; + break; + } + } + if (toscaFound == false) { + throw new IllegalArgumentException(String + .format(GeneratorConstants.GENERATOR_AAI_ERROR_MISSING_RESOURCE_TOSCA, + resourceUuidFromService)); + } + } + + } + + private ToscaTemplate preProcessingTosca(ToscaTemplate tosca) { + ToscaTemplate processedTosca = tosca; + if (tosca.getTopology_template() != null + && tosca.getTopology_template().getNode_templates() != null) { + Collection<NodeTemplate> coll = + processedTosca.getTopology_template().getNode_templates().values(); + for (NodeTemplate node : coll) { + + if (node.getType().contains("org.openecomp.resource.vf.") && node.getMetadata().get("category") + .equals("Allotted Resource")) { + node.setType("org.openecomp.resource.vf.allottedResource"); + } + if (node.getType().contains("org.openecomp.resource.vfc.") && node.getMetadata().get + ("category") + .equals("Allotted Resource")) { + node.setType("org.openecomp.resource.vfc.AllottedResource"); + } + } + } + return processedTosca; + } + + private void processVfTosca(Map<String, String> idTypeStore, ToscaTemplate resourceTemplate, + Model model) { + Set<String> keys = resourceTemplate.getTopology_template().getNode_templates().keySet(); + boolean flag = false; + for (String key : keys) { + NodeTemplate node = resourceTemplate.getTopology_template().getNode_templates().get(key); + Model resourceNode = Model.getModelFor(node.getType()); + if (resourceNode != null) { + if (resourceNode instanceof ProvidingService) { + flag = true; + Map<String, String> properties = new HashMap<>(); + Map<String, Object> nodeProperties = node.getProperties(); + if (nodeProperties.get("providing_service_uuid") == null || nodeProperties.get( + "providing_service_invariant_uuid") == null) { + throw new IllegalArgumentException(String.format( + GeneratorConstants.GENERATOR_AAI_PROVIDING_SERVICE_METADATA_MISSING + , model.getModelId())); + } + for (String key1 : nodeProperties.keySet()) { + if (nodeProperties.get(key1) instanceof String) { + properties.put(key1, nodeProperties.get(key1).toString()); + } + } + properties.put("version","1.0"); + resourceNode.populateModelIdentificationInformation(properties); + model.addResource((Resource) resourceNode); + } else if (resourceNode instanceof Resource && !(resourceNode.getWidgetType().equals( + Widget.Type + .L3_NET))) { + //resourceNode.populateModelIdentificationInformation(node.getMetadata()); + idTypeStore.put(resourceNode.getModelNameVersionId(), node.getType()); + model.addResource((Resource) resourceNode); + } + } + } + if(model instanceof AllotedResource){ + if(!flag) { + throw new IllegalArgumentException(String.format( + GeneratorConstants.GENERATOR_AAI_PROVIDING_SERVICE_MISSING, + model.getModelId())); + } + } + } + + /* private void vfWarnScenario(Map<String, String> idTypeStore, ToscaTemplate resourceTemplate) { + if (idTypeStore.size() == 0) { + //Log message for extra model file + log.warn( + "Additional tosca file found with resource version id : " + + resourceTemplate.getModelVersionId()); + } else { + //Log message for missing model files.. Replace with logger statement + log.warn("Service-Resource Tosca mapping not found for : " + + idTypeStore.keySet().toString()); + } + return; + }*/ + + private void processVfModule(List<Resource> resources, List<Resource> currentToscaResources, + ToscaTemplate resourceTemplate, Model model) { + log.debug("Inside Resource artifact generation for group/vfModule"); + Collection<GroupDefinition> groups = + resourceTemplate.getTopology_template().getGroups().values(); + Set<String> nodeNameListForGroups = new HashSet<>(); + for (GroupDefinition gd : groups) { + Model group = Model.getModelFor(gd.getType()); + if (group != null) { + group.populateModelIdentificationInformation(gd.getMetadata()); + Map<String, String> properties = new HashMap<>(); + Map<String, Object> groupProperties = gd.getProperties(); + for (String key : groupProperties.keySet()) { + if (groupProperties.get(key) instanceof String) { + properties.put(key, groupProperties.get(key).toString()); + } + } + group.populateModelIdentificationInformation(properties); + if (group instanceof VfModule && !currentToscaResources.contains(group)) { + if (gd.getMembers() != null && !gd.getMembers().isEmpty()) { + Set<String> groupMembers = new HashSet<>(); + ((VfModule) group).setMembers(gd.getMembers()); + nodeNameListForGroups.addAll(gd.getMembers()); + groupMembers.addAll(gd.getMembers()); + + for (String member : groupMembers) { + NodeTemplate node = + resourceTemplate.getTopology_template().getNode_templates().get(member); + if (node != null) { + Model resourceNode = null; + //L3-network inside vf-module to be generated as Widget a special handling. + if (node.getType().contains("org.openecomp.resource.vl")) { + resourceNode = new L3NetworkWidget(); + } else { + resourceNode = Model.getModelFor(node.getType()); + } + if (resourceNode != null) { + if (!(resourceNode instanceof Resource)) { + Widget widget = (Widget) resourceNode; + widget.addKey(member); + //Add the widget element encountered + // in the resource tosca in the resource model + boolean isAdded = group.addWidget(widget); + + //Add only widgets which are members of vf module and remove others + if (isAdded) { + model.addWidget(widget); + } + } + } + } + } + } + + model.addResource((Resource) group); //Added group (VfModule) to the (VF) model + currentToscaResources + .add((Resource) group); //Adding the VfModule group to file specific resources + //Check if we have already encountered the same VfModule across all the artifacts + if (!resources.contains(group)) { + resources.add((Resource) group); + } + } + } + } + + Iterator<Widget> iter = model.getWidgets().iterator(); + while (iter.hasNext()) { + if (iter.next().allInstancesUsed(nodeNameListForGroups) || true) { + iter.remove(); + } + } + } + + private void processServiceTosca(Service service, Map<String, String> idTypeStore,Map<String, + String> resourcesVersion,ToscaTemplate serviceTosca, List<Resource> resources) { + Collection<NodeTemplate> coll = + serviceTosca.getTopology_template().getNode_templates().values(); + log.debug("Inside Service Tosca "); + //Get the resource/widgets in the service according to the node-template types + for (NodeTemplate node : coll) { + Model model = Model.getModelFor(node.getType()); + if (model != null) { + model.populateModelIdentificationInformation(node.getMetadata()); + if (model instanceof Resource) { + String resourceVersion = node.getMetadata().get("version"); + validateVersion(resourceVersion,model.getModelNameVersionId()); + //Keeping track of resource types and + // their uuid for identification during resource tosca processing + idTypeStore.put(model.getModelNameVersionId(), node.getType()); + resourcesVersion.put(model.getModelNameVersionId(),resourceVersion); + service.addResource((Resource) model); + } else { + service.addWidget((Widget) model); + } + } + } + } + + /** + * Create Service artifact model from the AAI xml model string. + * + * @param serviceModel Model of the service artifact + * @param aaiServiceModel AAI model as string + * @return Generated {@link Artifact} model for the service + */ + private Artifact getServiceArtifact(Model serviceModel, String aaiServiceModel) { + Artifact artifact = + new Artifact(ArtifactType.MODEL_INVENTORY_PROFILE.name(), GroupType.DEPLOYMENT.name(), + GeneratorUtil.checkSum(aaiServiceModel.getBytes()), + GeneratorUtil.encode(aaiServiceModel.getBytes())); + String serviceArtifactName = getArtifactName(serviceModel); + String serviceArtifactLabel = getArtifactLabel(serviceModel); + artifact.setName(serviceArtifactName); + artifact.setLabel(serviceArtifactLabel); + String description = getArtifactDescription(serviceModel); + artifact.setDescription(description); + return artifact; + } + + /** + * Create Resource artifact model from the AAI xml model string. + * + * @param resourceModel Model of the resource artifact + * @param aaiResourceModel AAI model as string + * @return Generated {@link Artifact} model for the resource + */ + private Artifact getResourceArtifact(Model resourceModel, String aaiResourceModel) { + Artifact artifact = + new Artifact(ArtifactType.MODEL_INVENTORY_PROFILE.name(), GroupType.DEPLOYMENT.name(), + GeneratorUtil.checkSum(aaiResourceModel.getBytes()), + GeneratorUtil.encode(aaiResourceModel.getBytes())); + String resourceArtifactName = getArtifactName(resourceModel); + String resourceArtifactLabel = getArtifactLabel(resourceModel); + artifact.setName(resourceArtifactName); + artifact.setLabel(resourceArtifactLabel); + String description = getArtifactDescription(resourceModel); + artifact.setDescription(description); + return artifact; + } + + /** + * Method to generate the artifact name for an AAI model. + * + * @param model AAI artifact model + * @return Model artifact name + */ + private String getArtifactName(Model model) { + StringBuilder artifactName = new StringBuilder(ArtifactType.AAI.name()); + artifactName.append("-"); + + String truncatedArtifactName = ""; + truncatedArtifactName = truncateName(model.getModelName()); + artifactName.append(truncatedArtifactName); + + artifactName.append("-"); + artifactName.append(model.getModelType().name().toLowerCase()); + artifactName.append("-"); + artifactName.append(model.getModelVersion()); + + //artifactName.append(model.getModelVersion()); + artifactName.append("."); + artifactName.append(GeneratorConstants.GENERATOR_AAI_GENERATED_ARTIFACT_EXTENSION); + return artifactName.toString(); + } + + private String getArtifactLabel(Model model) { + // String label = ""; + StringBuilder artifactName = new StringBuilder(ArtifactType.AAI.name()); + artifactName.append("-"); + artifactName.append(model.getModelType().name().toLowerCase()); + artifactName.append("-"); + artifactName.append(hashCodeUuId(model.getModelNameVersionId())); + String label = (artifactName.toString()).replaceAll("[^a-zA-Z0-9 +]+", "-"); + return label; + } + + private int hashCodeUuId(String uuId) { + int hashcode = 0; + for (int i = 0; i < uuId.length(); i++) { + hashcode = 31 * hashcode + uuId.charAt(i); + } + return hashcode; + } + + + private String truncateName(String name) { + String truncatedName = name; + if (name.length() >= 200) { + truncatedName = name.substring(0, 199); + } + return truncatedName; + } + + private 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; + } + + private void validateVersion(String version, String uuId) { + String versionRegex = "^[0-9]\\d*(\\.\\d+)$"; + if (null == version || version == "") { + throw new IllegalArgumentException(String + .format(GeneratorConstants.GENERATOR_AAI_ERROR_NULL_RESOURCE_VERSION_IN_SERVICE_TOSCA, + uuId)); + } else if ( version.equals("0.0") || !(version.matches(versionRegex))) { + throw new IllegalArgumentException(String + .format(GeneratorConstants.GENERATOR_AAI_ERROR_INVALID_RESOURCE_VERSION_IN_SERVICE_TOSCA, + uuId)); + } + } + /** + * Get the tosca java model from the tosca input artifact. + * + * @param input Input tosca file and its metadata information as {@link Artifact} object + * @return Translated {@link ToscaTemplate tosca} object + */ + + private ToscaTemplate getToscaModel(Artifact input, String serviceVersion) + throws SecurityException { + byte[] decodedInput = GeneratorUtil.decoder(input.getPayload()); + String checksum = GeneratorUtil.checkSum(decodedInput); + ToscaTemplate tosca = null; + if (checksum.equalsIgnoreCase(input.getChecksum())) { + try { + log.debug("Input yaml name " + input.getName() + "payload " + new String(decodedInput)); + tosca = GeneratorUtil.translateTosca(new String(decodedInput), ToscaTemplate.class); + tosca.getMetadata().put("version", serviceVersion); + return tosca; + } catch (Exception exception) { + throw new IllegalArgumentException( + String.format(GeneratorConstants.GENERATOR_AAI_ERROR_INVALID_TOSCA, input.getName()), exception); + } + } else { + throw new SecurityException(GeneratorConstants.GENERATOR_AAI_ERROR_CHECKSUM_MISMATCH); + } + } + + private void validateTosca(ToscaTemplate tosca, Artifact input) { + log.debug("Validating tosca for Artifact: " + input.getName()); + if (tosca.getMetadata().containsKey("invariantUUID")) { + if (tosca.getMetadata().get("invariantUUID") == null + || tosca.getMetadata().get("invariantUUID") == "") { + throw new IllegalArgumentException(String + .format(GeneratorConstants.GENERATOR_AAI_ERROR_MANDATORY_METADATA_DEFINITION, + "invariantUUID", + input.getName())); + } else if (tosca.getMetadata().get("invariantUUID").length() != GeneratorConstants.ID_LENGTH) { + throw new IllegalArgumentException(String.format( + GeneratorConstants.GENERATOR_AAI_ERROR_INVALID_ID, "invariantUUID", input.getName())); + } + } + + if (tosca.getMetadata().containsKey("UUID")) { + if (tosca.getMetadata().get("UUID") == null || tosca.getMetadata().get("UUID") == "") { + throw new IllegalArgumentException(String + .format(GeneratorConstants.GENERATOR_AAI_ERROR_MANDATORY_METADATA_DEFINITION, "UUID", + input.getName())); + } else if (tosca.getMetadata().get("UUID").length() != GeneratorConstants.ID_LENGTH) { + throw new IllegalArgumentException(String + .format(GeneratorConstants.GENERATOR_AAI_ERROR_INVALID_ID, "UUID", input.getName())); + } + + } + if (tosca.getMetadata().containsKey("name")) { + if (tosca.getMetadata().get("name") == null || tosca.getMetadata().get("name") == "") { + throw new IllegalArgumentException(String + .format(GeneratorConstants.GENERATOR_AAI_ERROR_MANDATORY_METADATA_DEFINITION, "name", + input.getName())); + } + } + + //Validate VFmodule + if (tosca.getTopology_template() != null && tosca.getTopology_template().getGroups() != null) { + Collection<GroupDefinition> groups = tosca.getTopology_template().getGroups().values(); + for (GroupDefinition gd : groups) { + Model group = Model.getModelFor(gd.getType()); + if (group != null && group instanceof VfModule) { + if (gd.getMetadata().containsKey("vfModuleModelName") + && gd.getMetadata().get("vfModuleModelName") == null) { + throw new IllegalArgumentException(String + .format(GeneratorConstants.GENERATOR_AAI_ERROR_MANDATORY_METADATA_DEFINITION, + "vfModuleModelName", + input.getName())); + } + if (gd.getMetadata().containsKey("vfModuleModelInvariantUUID") + && gd.getMetadata().get("vfModuleModelInvariantUUID") == null) { + throw new IllegalArgumentException(String + .format(GeneratorConstants.GENERATOR_AAI_ERROR_MANDATORY_METADATA_DEFINITION, + "vfModuleModelInvariantUUID", input.getName())); + } else if (gd.getMetadata().get("vfModuleModelInvariantUUID").length() != GeneratorConstants.ID_LENGTH) { + throw new IllegalArgumentException(String.format( + GeneratorConstants.GENERATOR_AAI_ERROR_INVALID_ID, "vfModuleModelInvariantUUID", + input.getName())); + } + + if (gd.getMetadata().containsKey("vfModuleModelUUID") + && gd.getMetadata().get("vfModuleModelUUID") == null) { + throw new IllegalArgumentException(String + .format(GeneratorConstants.GENERATOR_AAI_ERROR_MANDATORY_METADATA_DEFINITION, + "vfModuleModelUUID", + input.getName())); + } else if (gd.getMetadata().get("vfModuleModelUUID").length() != GeneratorConstants.ID_LENGTH) { + throw new IllegalArgumentException(String.format( + GeneratorConstants.GENERATOR_AAI_ERROR_INVALID_ID, "vfModuleModelUUID", + input.getName())); + } + if (gd.getMetadata().containsKey("vfModuleModelVersion") + && gd.getMetadata().get("vfModuleModelVersion") == null) { + throw new IllegalArgumentException(String + .format(GeneratorConstants.GENERATOR_AAI_ERROR_MANDATORY_METADATA_DEFINITION, + "vfModuleModelVersion", + input.getName())); + } + } + } + } + } + + /** + * Identify the service tosca artifact from the list of translated tosca inputs. + * + * @param input List of translated {@link ToscaTemplate tosca} object models + * @return Identified service {@link ToscaTemplate tosca} + */ + private ToscaTemplate getServiceTosca(List<ToscaTemplate> input) { + Iterator<ToscaTemplate> iter = input.iterator(); + while (iter.hasNext()) { + ToscaTemplate tosca = iter.next(); + if (tosca.isService()) { + iter.remove(); + return tosca; + } + } + return null; + } + + private void initWidgetConfiguration() throws IOException { + log.debug("Getting Widget Configuration"); + String configLocation = System.getProperty("artifactgenerator.config"); + Properties properties = null; + if (configLocation != null) { + File file = new File(configLocation); + if (file.exists()) { + properties = new Properties(); + properties.load(new FileInputStream(file)); + WidgetConfigurationUtil.setConfig(properties); + } else { + throw new IllegalArgumentException(String.format( + GeneratorConstants.GENERATOR_AAI_CONFIGFILE_NOT_FOUND, + configLocation)); + } + } else { + throw new IllegalArgumentException(GeneratorConstants.GENERATOR_AAI_CONFIGLOCATION_NOT_FOUND); + } + } + +} diff --git a/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/aai/AaiModelGeneratorImpl.java b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/aai/AaiModelGeneratorImpl.java new file mode 100644 index 0000000000..4a4f9f0923 --- /dev/null +++ b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/aai/AaiModelGeneratorImpl.java @@ -0,0 +1,278 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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.sdc.generator.aai; + +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.onap.sdc.generator.aai.model.Resource; +import org.onap.sdc.generator.aai.model.Service; +import org.onap.sdc.generator.aai.model.Widget; +import org.onap.sdc.generator.aai.xml.Model; +import org.onap.sdc.generator.aai.xml.ModelElement; +import org.onap.sdc.generator.aai.xml.ModelElements; +import org.onap.sdc.generator.aai.xml.ModelVer; +import org.onap.sdc.generator.aai.xml.ModelVers; +import org.onap.sdc.generator.aai.xml.Relationship; +import org.onap.sdc.generator.aai.xml.RelationshipData; +import org.onap.sdc.generator.aai.xml.RelationshipList; +import org.onap.sdc.generator.logging.annotations.Metrics; +import org.w3c.dom.DOMException; + +import java.io.StringWriter; +import java.util.List; +import java.util.Set; +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; + +/** + * Implementation of the {@link AaiModelGenerator} which generates the XML models from the + * Service/Resource/Widget java models. + */ +public class AaiModelGeneratorImpl implements AaiModelGenerator { + private static Logger log = LoggerFactory.getLogger(AaiModelGeneratorImpl.class.getName()); + + /** + * Method to generate the AAI model for a Service. + * + * @param service Java object model representing an AAI {@link Service} model + * @return XML representation of the service model in String format + */ + @Override + @Metrics + public String generateModelFor(Service service) { + //Create a JAXB Model for AAI service model + Model aaiServiceModel = new Model(); + log.debug("Generating Model for Service with ModelName: " + service.getModelName()); + // after new model + aaiServiceModel.setModelInvariantId(service.getModelId()); + aaiServiceModel.setModelVers(new ModelVers()); + ModelVer modelVer = new ModelVer(); + modelVer.setModelDescription(service.getModelDescription()); + modelVer.setModelName(service.getModelName()); + modelVer.setModelVersion(service.getModelVersion()); + modelVer.setModelVersionId(service.getModelNameVersionId()); + modelVer.setModelElements(new ModelElements()); + ModelElements modelElements = modelVer.getModelElements(); + //Populate basic model details + aaiServiceModel + .setModelType(service.getModelType().name().toLowerCase()); //Using enum name as model type + List<ModelElement> modelElementList = modelElements.getModelElement(); + + //Add service base widget model element + ModelElement serviceWidgetModelRelationshipElement = + createRelationshipModelElement(getNewDataDelFlagValue(service.getDeleteFlag()), + service.getWidgetId(),service.getWidgetInvariantId()); + modelElementList.add(serviceWidgetModelRelationshipElement); + + //Add the resource model elements + ModelElements serviceModelElements = serviceWidgetModelRelationshipElement.getModelElements(); + List<ModelElement> serviceModelElementList = serviceModelElements.getModelElement(); + Set<Resource> serviceResources = service.getResources(); + if (serviceResources != null && !serviceResources.isEmpty()) { + for (Resource resourceModel : serviceResources) { + ModelElement aaiResourceModelElement = + createRelationshipModelElement(getNewDataDelFlagValue(resourceModel.getDeleteFlag()), + resourceModel.getModelNameVersionId(),resourceModel.getModelId()); + serviceModelElementList.add(aaiResourceModelElement); + } + } + + //Add the widget model elements + Set<Widget> serviceWidgets = service.getWidgets(); + if (serviceWidgets != null && !serviceWidgets.isEmpty()) { + for (Widget widgetModel : serviceWidgets) { + ModelElement widgetModelElement = + createRelationshipModelElement(getNewDataDelFlagValue(widgetModel.getDeleteFlag()), + widgetModel.getId(),widgetModel.getWidgetId()); + serviceModelElementList.add(widgetModelElement); + } + } + ModelVers modelVers = aaiServiceModel.getModelVers(); + List<ModelVer> modelVerList = modelVers.getModelVer(); + modelVerList.add(modelVer); + return getModelAsString(aaiServiceModel); + } + + /** + * Method to generate the AAI model for a Resource. + * + * @param resource Java object model representing an AAI {@link Resource} model + * @return XML representation of the resource model in String format + */ + @Override + @Metrics + public String generateModelFor(Resource resource) { + //Create a JAXB Model for AAI Resource model + Model aaiResourceModel = new Model(); + log.debug("Generating Model for Resource with ModelName: " + resource.getModelName()); + aaiResourceModel.setModelInvariantId(resource.getModelId()); + aaiResourceModel.setModelVers(new ModelVers()); + ModelVer modelVer = new ModelVer(); + modelVer.setModelDescription(resource.getModelDescription()); + modelVer.setModelName(resource.getModelName()); + modelVer.setModelVersion(resource.getModelVersion()); + modelVer.setModelVersionId(resource.getModelNameVersionId()); + modelVer.setModelElements(new ModelElements()); + ModelElements modelElements = modelVer.getModelElements(); + aaiResourceModel + .setModelType(resource.getModelType().name().toLowerCase()); //Using enum name as model type + List<ModelElement> modelElementList = modelElements.getModelElement(); + + //Add resource base widget model element + ModelElement resourceWidgetModelRelationshipElement = + createRelationshipModelElement(getNewDataDelFlagValue(resource.getDeleteFlag()), + resource.getWidgetId(),resource.getWidgetInvariantId()); + modelElementList.add(resourceWidgetModelRelationshipElement); + + //Add the child resources to the base widget model element list + ModelElements baseResourceWidgetModelElements = + resourceWidgetModelRelationshipElement.getModelElements(); + List<ModelElement> baseResourceWidgetModelElementList = + baseResourceWidgetModelElements.getModelElement(); + Set<Resource> childResources = resource.getResources(); + if (childResources != null && !childResources.isEmpty()) { + for (Resource childResourceModel : childResources) { + ModelElement aaiChildResourceModelElement = createRelationshipModelElement( + getNewDataDelFlagValue(childResourceModel.getDeleteFlag()), + childResourceModel.getModelNameVersionId(),childResourceModel.getModelId()); + baseResourceWidgetModelElementList.add(aaiChildResourceModelElement); + } + } + //Add resource widgets/resources to the resource widget model relationship element + Set<Widget> resourceWidgets = resource.getWidgets(); + if (resourceWidgets != null && !resourceWidgets.isEmpty()) { + generateWidgetChildren(resourceWidgetModelRelationshipElement, resourceWidgets); + } + + ModelVers modelVers = aaiResourceModel.getModelVers(); + List<ModelVer> modelVerList = modelVers.getModelVer(); + modelVerList.add(modelVer); + return getModelAsString(aaiResourceModel); + + } + + /** + * Method to create the <model-element></model-element> holding the relationship value for a + * resource/widget + * model. + * + * @param newDataDelFlag Value of the <new-data-del-flag></new-data-del-flag> attribute for + * a widget/resource in + * the model xml + * @param relationshipValue Value of the <relationship-value></relationship-value> attribute + * for the widget/resource in + * the model xml + * @return Java object representation for the <model-element></model-element> holding the + relationship + */ + private ModelElement createRelationshipModelElement(String newDataDelFlag, + String modelVersionId,String + modelInvariantId) { + ModelElement relationshipModelElement = new ModelElement(); + relationshipModelElement.setNewDataDelFlag(newDataDelFlag); //Set new-data-del-flag value + relationshipModelElement.setCardinality("unbounded"); + RelationshipList relationShipList = new RelationshipList(); + final List<Relationship> relationships = relationShipList.getRelationship(); + Relationship relationship = new Relationship(); + relationship.setRelatedTo("model-ver"); + List<RelationshipData> relationshipDataList = relationship.getRelationshipData(); + + RelationshipData modelVersionRelationshipData = new RelationshipData(); + modelVersionRelationshipData.setRelationshipKey("model-ver.model-version-id"); + modelVersionRelationshipData.setRelationshipValue( + modelVersionId); //Set the widget/resource name-version-uuid as value + relationshipDataList.add(modelVersionRelationshipData); + RelationshipData modelInvariantRelationshipData = new RelationshipData(); + modelInvariantRelationshipData.setRelationshipKey("model.model-invariant-id"); + modelInvariantRelationshipData.setRelationshipValue( + modelInvariantId); + relationshipDataList.add(modelInvariantRelationshipData); + relationships.add(relationship); + relationshipModelElement.setRelationshipList(relationShipList); + relationshipModelElement.setModelElements(new ModelElements()); + return relationshipModelElement; + } + + /** + * Method to create the child model elements of the widget. Handles the generation of recursive + * child widget elements (if any) + * + * @param parent Reference to the parent widget model element + * @param widgetChildrenSet Set of children obtained from the tosca/widget definition + */ + private void generateWidgetChildren(ModelElement parent, Set<Widget> widgetChildrenSet) { + for (Widget widget : widgetChildrenSet) { + Set<Widget> widgetSubChildren = widget.getWidgets(); + if (widgetSubChildren != null && !widgetSubChildren.isEmpty()) { + ModelElement widgetChildRelationshipElement = + createRelationshipModelElement(getNewDataDelFlagValue(widget.getDeleteFlag()), + widget.getId(),widget.getWidgetId()); + //Recursive call for getting the children of widgets (if any) + generateWidgetChildren(widgetChildRelationshipElement, widgetSubChildren); + parent.getModelElements().getModelElement().add(widgetChildRelationshipElement); + } else { + ModelElement widgetChildRelationshipElement = + createRelationshipModelElement(getNewDataDelFlagValue(widget.getDeleteFlag()), + widget.getId(),widget.getWidgetId() + ); + parent.getModelElements().getModelElement().add(widgetChildRelationshipElement); + } + } + } + + /** + * Converts the data delete flag value from boolean to String as per AAI model. + * + * @param delFlag Boolean value as true/false from the annotation + * @return Converted value to a flag as per AAI model + */ + private String getNewDataDelFlagValue(boolean delFlag) { + if (delFlag) { + return "T"; + } else { + return "F"; + } + } + + /** + * JAXB marshalling helper method to convert the Java object model to XML String. + * + * @param model Java Object model of a service/widget/resource + * @return XML representation of the Java model in String format + */ + private String getModelAsString(Model model) { + JAXBContext jaxbContext; + StringWriter modelStringWriter = new StringWriter(); + try { + jaxbContext = JAXBContext.newInstance(Model.class); + Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); + jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); + jaxbMarshaller.setProperty(Marshaller.JAXB_ENCODING, "US-ASCII"); + jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); + jaxbMarshaller.marshal(model, modelStringWriter); + } catch (JAXBException jaxbException) { + throw new DOMException(DOMException.SYNTAX_ERR, jaxbException.getMessage()); + } + + return modelStringWriter.toString(); + } +} diff --git a/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/impl/ArtifactGenerationServiceImpl.java b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/impl/ArtifactGenerationServiceImpl.java new file mode 100644 index 0000000000..42975478fe --- /dev/null +++ b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/impl/ArtifactGenerationServiceImpl.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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.sdc.generator.impl; + +import static org.onap.sdc.generator.util.ArtifactGeneratorUtil.logError; + +import org.onap.sdc.generator.data.GeneratorConstants; +import org.onap.sdc.generator.util.ArtifactGeneratorUtil; +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.onap.sdc.generator.GeneratorManager; +import org.onap.sdc.generator.GeneratorTask; +import org.onap.sdc.generator.data.Artifact; +import org.onap.sdc.generator.data.GenerationData; +import org.onap.sdc.generator.intf.ArtifactGenerator; +import org.onap.sdc.generator.service.ArtifactGenerationService; + +import java.util.List; +import java.util.Map; +import java.util.concurrent.ForkJoinPool; + +/** + * Artifact Generation Service implementation class. + */ +public class ArtifactGenerationServiceImpl implements ArtifactGenerationService { + + private static Logger log = + LoggerFactory.getLogger(ArtifactGenerationServiceImpl.class.getName()); + + /** + * Artifact generator method. + * + * @param input List of input files as {@link Artifact} models + * @param overridingConfiguration Configuration data for invoking generators + * @param additionalParams Additional Parameters + * @return Generated artifacts/Error data in a {@link GenerationData} object + */ + @Override + public GenerationData generateArtifact(List<Artifact> input, String overridingConfiguration, + Map<String, String> additionalParams) { + try { + //Initialize artifact generation logging context + ArtifactGeneratorUtil.initializeLoggingContext(); + + List<ArtifactGenerator> generatorsToBeUsed = + GeneratorManager.getActiveArtifactGenerators(overridingConfiguration); + if (generatorsToBeUsed.size() > 0) { + return ForkJoinPool.commonPool().invoke(new GeneratorTask(generatorsToBeUsed, input, + additionalParams)); + } else { + return new GenerationData(); + } + } catch (IllegalArgumentException iae) { + //Invalid client configuration + ArtifactGeneratorUtil + .logError(GeneratorConstants.GENERATOR_ERROR_ARTIFACT_GENERATION_FAILED, iae); + GenerationData errorData = new GenerationData(); + errorData.add(GeneratorConstants.GENERATOR_INVOCATION_ERROR_CODE, iae.getMessage()); + return errorData; + } catch (Exception ex) { + ArtifactGeneratorUtil + .logError(GeneratorConstants.GENERATOR_ERROR_ARTIFACT_GENERATION_FAILED, ex); + GenerationData errorData = new GenerationData(); + errorData.add(GeneratorConstants.GENERATOR_INVOCATION_ERROR_CODE, + GeneratorConstants.GENERATOR_ERROR_ARTIFACT_GENERATION_FAILED); + return errorData; + } + } +} diff --git a/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/util/ArtifactGeneratorUtil.java b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/util/ArtifactGeneratorUtil.java new file mode 100644 index 0000000000..8e6e2c0829 --- /dev/null +++ b/common/onap-sdc-artifact-generator-lib/onap-sdc-artifact-generator-core/src/main/java/org/onap/sdc/generator/util/ArtifactGeneratorUtil.java @@ -0,0 +1,298 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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.sdc.generator.util; + +import static org.onap.sdc.generator.data.GeneratorConstants.BEGIN_TIMESTAMP; +import static org.onap.sdc.generator.data.GeneratorConstants.BE_FQDN; +import static org.onap.sdc.generator.data.GeneratorConstants.CATEGORY_LOG_LEVEL; +import static org.onap.sdc.generator.data.GeneratorConstants.CLIENT_IP; +import static org.onap.sdc.generator.data.GeneratorConstants.ELAPSED_TIME; +import static org.onap.sdc.generator.data.GeneratorConstants.END_TIMESTAMP; +import static org.onap.sdc.generator.data.GeneratorConstants.ERROR_CATEGORY; +import static org.onap.sdc.generator.data.GeneratorConstants.ERROR_CODE; +import static org.onap.sdc.generator.data.GeneratorConstants.ERROR_DESCRIPTION; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_CONFIGFILE_NOT_FOUND; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_CONFIGLOCATION_NOT_FOUND; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_CONFIGLPROP_NOT_FOUND; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_PROVIDING_SERVICE_METADATA_MISSING; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_PROVIDING_SERVICE_MISSING; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_ERROR_INVALID_ID; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_ERROR_INVALID_RESOURCE_VERSION_IN_SERVICE_TOSCA; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_ERROR_INVALID_TOSCA_MSG; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_ERROR_MANDATORY_METADATA_DEFINITION_MSG; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_ERROR_MISSING_RESOURCE_TOSCA; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_ERROR_MISSING_SERVICE_TOSCA_MSG; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_ERROR_MISSING_SERVICE_VERSION; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_ERROR_NULL_RESOURCE_VERSION_IN_SERVICE_TOSCA; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_AAI_INVALID_SERVICE_VERSION; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_ERROR_ARTIFACT_GENERATION_FAILED_MSG; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_ERROR_INVALID_CLIENT_CONFIGURATION_MSG; +import static org.onap.sdc.generator.data.GeneratorConstants.GENERATOR_PARTNER_NAME; +import static org.onap.sdc.generator.data.GeneratorConstants.INSTANCE_UUID; +import static org.onap.sdc.generator.data.GeneratorConstants.LOCAL_ADDR; +import static org.onap.sdc.generator.data.GeneratorConstants.MDC_SDC_INSTANCE_UUID; +import static org.onap.sdc.generator.data.GeneratorConstants.PARTNER_NAME; +import static org.onap.sdc.generator.data.GeneratorConstants.REMOTE_HOST; +import static org.onap.sdc.generator.data.GeneratorConstants.REQUEST_ID; +import static org.onap.sdc.generator.data.GeneratorConstants.RESPONSE_CODE; +import static org.onap.sdc.generator.data.GeneratorConstants.RESPONSE_DESCRIPTION; +import static org.onap.sdc.generator.data.GeneratorConstants.SERVICE_INSTANCE_ID; +import static org.onap.sdc.generator.data.GeneratorConstants.SERVICE_METRIC_BEGIN_TIMESTAMP; +import static org.onap.sdc.generator.data.GeneratorConstants.SERVICE_NAME; +import static org.onap.sdc.generator.data.GeneratorConstants.STATUS_CODE; +import static org.onap.sdc.generator.data.GeneratorConstants.TARGET_ENTITY; +import static org.onap.sdc.generator.data.GeneratorConstants.TARGET_SERVICE_NAME; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.INTERNAL_SERVER_ERROR; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.INVALID_CLIENT_CONFIGURATION; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.INVALID_ID_VALUE; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.INVALID_RESOURCE_VERSION; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.INVALID_SERVICE_VERSION; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.INVALID_TOSCA_YAML; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.MANDATORY_ATTRIBUTE_MISSING; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.MISSING_CONFIG_PROPERTIES_FILE; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.MISSING_PRO_SERVICE; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.MISSING_PRO_SERVICE_METADATA; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.MISSING_RESOURCE_VERSION; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.MISSING_SERVICE_VERSION; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.MISSING_SYSTME_PROPERY_CONFIGURATION; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.MISSING_WIDGET_CONFIGURATION; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.RESOURCE_TOSCA_MISSING; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.SERVICE_TOSCA_MISSING; +import static org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode.UNABLE_TO_GENERATE_ARTIFACT; + +import org.openecomp.sdc.logging.api.Logger; +import org.openecomp.sdc.logging.api.LoggerFactory; +import org.onap.sdc.generator.data.Artifact; +import org.onap.sdc.generator.logging.ArtifactGeneratorLogResponseCode; +import org.onap.sdc.generator.logging.CategoryLogLevel; +import org.onap.sdc.generator.logging.StatusCode; +import org.slf4j.MDC; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.TimeZone; + + +public class ArtifactGeneratorUtil { + + private static Logger log = LoggerFactory.getLogger(ArtifactGeneratorUtil.class.getName()); + private static final String LOG_UTC_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS"; + + /** + * Artifact Generator Error logging Helper. + * @param errorDescription Description of the error + */ + public static void logError(String errorDescription) { + logError(errorDescription, ""); + } + + /** + * Artifact Generator Error logging Helper. + * @param errorDescription Description of the error + * @param ex Exception object for stackstrace + */ + public static void logError(String errorDescription, Exception ex) { + StringWriter sw = new StringWriter(); + ex.printStackTrace(new PrintWriter(sw)); + String detailMessage = sw.toString(); + logError(CategoryLogLevel.ERROR, errorDescription, detailMessage); + } + + /** + * Artifact Generator Error logging Helper. + * @param errorDescription Description of the error + * @param detailMessage Detailed Error message + */ + public static void logError(String errorDescription, String detailMessage) { + logError(CategoryLogLevel.ERROR, errorDescription, detailMessage); + } + + /** + * Artifact Generator Error logging Helper. + * @param errorCategory ERROR + * @param errorDescription Description of the error + * @param detailMessage Detailed Error message + */ + public static void logError(CategoryLogLevel errorCategory, + String errorDescription, String detailMessage) { + MDC.put(ERROR_CATEGORY, errorCategory.name()); + MDC.put(STATUS_CODE, StatusCode.ERROR.name()); + artifactGeneratorErrorLogProcessor(errorCategory,errorDescription); + log.error(detailMessage); + resetLoggingContext(); + } + + /** + * Initialize generic MDC attributes for logging the current request. + * + */ + public static void initializeLoggingContext() { + log.debug("Initializing generic logging context "); + MDC.put(PARTNER_NAME, GENERATOR_PARTNER_NAME); + MDC.put(SERVICE_METRIC_BEGIN_TIMESTAMP, String.valueOf(System.currentTimeMillis())); + MDC.put(INSTANCE_UUID, MDC_SDC_INSTANCE_UUID); + MDC.put(STATUS_CODE, StatusCode.COMPLETE.name()); + MDC.put(CLIENT_IP, MDC.get(REMOTE_HOST)); + + try { + InetAddress ip = InetAddress.getLocalHost(); + MDC.put(LOCAL_ADDR, ip.getHostAddress()); + String hostname = ip.getHostName(); + MDC.put(BE_FQDN, hostname); + } catch (UnknownHostException uhe) { + log.error("Failed to get server FQDN", uhe); + } + + if (log.isDebugEnabled()) { + MDC.put(CATEGORY_LOG_LEVEL, CategoryLogLevel.DEBUG.name()); + } else if (log.isInfoEnabled()) { + MDC.put(CATEGORY_LOG_LEVEL, CategoryLogLevel.INFO.name()); + } else if (log.isWarnEnabled()) { + MDC.put(CATEGORY_LOG_LEVEL, CategoryLogLevel.WARN.name()); + } else if (log.isErrorEnabled()) { + MDC.put(CATEGORY_LOG_LEVEL, CategoryLogLevel.ERROR.name()); + } + } + + /** + * Initialize MDC for logging the current artifact request. + * + * @param artifact Current artifact + */ + public static void initializeArtifactLoggingContext(Artifact artifact) { + log.debug("Initializing logging context for " + artifact.getLabel()); + MDC.put(REQUEST_ID, artifact.getLabel()); + MDC.put(SERVICE_NAME, artifact.getType()); + MDC.put(SERVICE_INSTANCE_ID, artifact.getName()); + } + + /** + * Reset the logging context after a Audit/Metrics logging operation. + */ + public static void resetLoggingContext() { + MDC.remove(ERROR_CATEGORY); + MDC.remove(ERROR_CODE); + MDC.remove(STATUS_CODE); + MDC.remove(ERROR_DESCRIPTION); + MDC.remove(BEGIN_TIMESTAMP); + MDC.remove(END_TIMESTAMP); + MDC.remove(ELAPSED_TIME); + MDC.put(STATUS_CODE, StatusCode.COMPLETE.name()); + MDC.remove(RESPONSE_CODE); + MDC.remove(RESPONSE_DESCRIPTION); + MDC.remove(TARGET_ENTITY); + MDC.remove(TARGET_SERVICE_NAME); + } + + /** + * Convert timestamp to UTC format date string. + * + * @param timeStamp UTC timestamp to be converted to the UTC Date format. + * @return UTC formatted Date string from timestamp. + */ + public static String getLogUtcDateStringFromTimestamp(Date timeStamp) { + DateFormat df = new SimpleDateFormat(LOG_UTC_DATE_FORMAT); + df.setTimeZone(TimeZone.getTimeZone("GMT")); + return df.format(timeStamp); + } + + /** + * Artifact Gnenerator Error logging Helper. + * + * @param errorCategory WARN or ERROR. + * @param errorDescription Description of the error. + */ + public static void artifactGeneratorErrorLogProcessor(CategoryLogLevel errorCategory, + String errorDescription) { + MDC.put(ERROR_CATEGORY, errorCategory.name()); + if (errorDescription != null) { + String errorType = ""; + switch (errorCategory) { + case WARN: + errorType = "W"; + break; + case ERROR: + errorType = "E"; + break; + case FATAL: + errorType = "F"; + break; + default: + break; + } + MDC.put(ERROR_CODE, getLogResponseCode(errorDescription) + errorType); + } + MDC.put(ERROR_DESCRIPTION, errorDescription); + } + + + /** + * + * @return Audit log code corresponding to the Artifact Generator exception. + */ + public static int getLogResponseCode(String errorDescription) { + ArtifactGeneratorLogResponseCode responseCode = INTERNAL_SERVER_ERROR; + if (errorDescription.contains(GENERATOR_AAI_ERROR_MANDATORY_METADATA_DEFINITION_MSG)) { + responseCode = MANDATORY_ATTRIBUTE_MISSING; + } else if (errorDescription.contains(GENERATOR_AAI_ERROR_INVALID_TOSCA_MSG)) { + responseCode = INVALID_TOSCA_YAML; + } else if (errorDescription.contains(GENERATOR_AAI_ERROR_MISSING_SERVICE_TOSCA_MSG)) { + responseCode = SERVICE_TOSCA_MISSING; + } else if (errorDescription.contains(GENERATOR_ERROR_INVALID_CLIENT_CONFIGURATION_MSG)) { + responseCode = INVALID_CLIENT_CONFIGURATION; + } else if (errorDescription.contains(GENERATOR_ERROR_ARTIFACT_GENERATION_FAILED_MSG)) { + responseCode = UNABLE_TO_GENERATE_ARTIFACT; + } else if (errorDescription.contains(GENERATOR_AAI_CONFIGLOCATION_NOT_FOUND.split("%s")[0])) { + responseCode = MISSING_SYSTME_PROPERY_CONFIGURATION; + } else if (errorDescription.contains(GENERATOR_AAI_CONFIGFILE_NOT_FOUND.split("%s")[0])) { + responseCode = MISSING_CONFIG_PROPERTIES_FILE; + } else if (errorDescription.contains(GENERATOR_AAI_CONFIGLPROP_NOT_FOUND.split("%s")[0])) { + responseCode = MISSING_WIDGET_CONFIGURATION; + } else if (errorDescription.contains(GENERATOR_AAI_ERROR_INVALID_ID.split("%s")[0])) { + responseCode = INVALID_ID_VALUE; + } else if (errorDescription.contains(GENERATOR_AAI_ERROR_MISSING_RESOURCE_TOSCA.split("%s")[0])) + { + responseCode = RESOURCE_TOSCA_MISSING; + } else if(errorDescription.contains(GENERATOR_AAI_ERROR_MISSING_SERVICE_VERSION)) { + responseCode = MISSING_SERVICE_VERSION; + } else if(errorDescription.contains(GENERATOR_AAI_INVALID_SERVICE_VERSION)) + { + responseCode = INVALID_SERVICE_VERSION; + } else if(errorDescription.contains(GENERATOR_AAI_ERROR_NULL_RESOURCE_VERSION_IN_SERVICE_TOSCA. + split("%s")[0])) { + responseCode = MISSING_RESOURCE_VERSION; + } else if(errorDescription.contains( + GENERATOR_AAI_ERROR_INVALID_RESOURCE_VERSION_IN_SERVICE_TOSCA.split("%s")[0])) { + responseCode = INVALID_RESOURCE_VERSION; + } else if(errorDescription.contains(GENERATOR_AAI_PROVIDING_SERVICE_MISSING.split("%s")[0])) { + responseCode = MISSING_PRO_SERVICE; + } else if(errorDescription.contains( + GENERATOR_AAI_PROVIDING_SERVICE_METADATA_MISSING.split("%s")[0])) { + responseCode = MISSING_PRO_SERVICE_METADATA; + } + return responseCode.getValue(); + } +} |