From 7e6fe8c29c5a5cfa5caf6ab47b30280e1fc20432 Mon Sep 17 00:00:00 2001 From: "mark.j.leonard" Date: Thu, 7 Jun 2018 16:45:38 +0100 Subject: Add support for loading VNF Catalog XML files Issue-ID: AAI-1214 Change-Id: I5d0eb3456916e6f3e5ba3a9b4e828feaff0cde4e Signed-off-by: mark.j.leonard --- .../aai/modelloader/config/ModelLoaderConfig.java | 67 +++--- .../onap/aai/modelloader/entity/ArtifactType.java | 3 +- .../entity/catalog/VnfCatalogArtifact.java | 1 + .../entity/catalog/VnfCatalogArtifactHandler.java | 190 ++++++++++++---- .../extraction/VnfCatalogExtractor.java | 107 +++++++++ .../notification/ArtifactDownloadManager.java | 36 ++- .../notification/NotificationPublisher.java | 2 +- .../aai/modelloader/service/ModelLoaderMsgs.java | 245 +++++++++++---------- .../aai/modelloader/util/JsonXmlConverter.java | 4 +- 9 files changed, 449 insertions(+), 206 deletions(-) create mode 100644 src/main/java/org/onap/aai/modelloader/extraction/VnfCatalogExtractor.java (limited to 'src/main/java') diff --git a/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java b/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java index 0a2bc85..01505ba 100644 --- a/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java +++ b/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java @@ -21,6 +21,8 @@ package org.onap.aai.modelloader.config; import java.io.File; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.List; import java.util.Properties; @@ -47,29 +49,29 @@ public class ModelLoaderConfig implements IConfiguration { private static final String SUFFIX_TRUSTSTORE_PASS = "TRUSTSTORE_PASSWORD"; // Configuration file properties - protected static final String PROP_ML_DISTRIBUTION_ACTIVE_SERVER_TLS_AUTH = PREFIX_DISTRIBUTION_CLIENT - + "ACTIVE_SERVER_TLS_AUTH"; - protected static final String PROP_ML_DISTRIBUTION_ASDC_CONNECTION_DISABLED = PREFIX_DISTRIBUTION_CLIENT - + "ASDC_CONNECTION_DISABLE"; + protected static final String PROP_ML_DISTRIBUTION_ACTIVE_SERVER_TLS_AUTH = + PREFIX_DISTRIBUTION_CLIENT + "ACTIVE_SERVER_TLS_AUTH"; + protected static final String PROP_ML_DISTRIBUTION_ASDC_CONNECTION_DISABLED = + PREFIX_DISTRIBUTION_CLIENT + "ASDC_CONNECTION_DISABLE"; protected static final String PROP_ML_DISTRIBUTION_ASDC_ADDRESS = PREFIX_DISTRIBUTION_CLIENT + "ASDC_ADDRESS"; protected static final String PROP_ML_DISTRIBUTION_CONSUMER_GROUP = PREFIX_DISTRIBUTION_CLIENT + "CONSUMER_GROUP"; protected static final String PROP_ML_DISTRIBUTION_CONSUMER_ID = PREFIX_DISTRIBUTION_CLIENT + "CONSUMER_ID"; - protected static final String PROP_ML_DISTRIBUTION_ENVIRONMENT_NAME = PREFIX_DISTRIBUTION_CLIENT - + "ENVIRONMENT_NAME"; - protected static final String PROP_ML_DISTRIBUTION_KEYSTORE_PASSWORD = PREFIX_DISTRIBUTION_CLIENT - + SUFFIX_KEYSTORE_PASS; - protected static final String PROP_ML_DISTRIBUTION_KEYSTORE_FILE = PREFIX_DISTRIBUTION_CLIENT - + SUFFIX_KEYSTORE_FILE; + protected static final String PROP_ML_DISTRIBUTION_ENVIRONMENT_NAME = + PREFIX_DISTRIBUTION_CLIENT + "ENVIRONMENT_NAME"; + protected static final String PROP_ML_DISTRIBUTION_KEYSTORE_PASSWORD = + PREFIX_DISTRIBUTION_CLIENT + SUFFIX_KEYSTORE_PASS; + protected static final String PROP_ML_DISTRIBUTION_KEYSTORE_FILE = + PREFIX_DISTRIBUTION_CLIENT + SUFFIX_KEYSTORE_FILE; protected static final String PROP_ML_DISTRIBUTION_PASSWORD = PREFIX_DISTRIBUTION_CLIENT + "PASSWORD"; - protected static final String PROP_ML_DISTRIBUTION_POLLING_INTERVAL = PREFIX_DISTRIBUTION_CLIENT - + "POLLING_INTERVAL"; + protected static final String PROP_ML_DISTRIBUTION_POLLING_INTERVAL = + PREFIX_DISTRIBUTION_CLIENT + "POLLING_INTERVAL"; protected static final String PROP_ML_DISTRIBUTION_POLLING_TIMEOUT = PREFIX_DISTRIBUTION_CLIENT + "POLLING_TIMEOUT"; protected static final String PROP_ML_DISTRIBUTION_USER = PREFIX_DISTRIBUTION_CLIENT + "USER"; protected static final String PROP_ML_DISTRIBUTION_ARTIFACT_TYPES = PREFIX_DISTRIBUTION_CLIENT + "ARTIFACT_TYPES"; - protected static final String PROP_ML_DISTRIBUTION_MSG_BUS_ADDRESSES = PREFIX_DISTRIBUTION_CLIENT - + "MSG_BUS_ADDRESSES"; - protected static final String PROP_ML_DISTRIBUTION_HTTPS_WITH_DMAAP = PREFIX_DISTRIBUTION_CLIENT - + "USE_HTTPS_WITH_DMAAP"; + protected static final String PROP_ML_DISTRIBUTION_MSG_BUS_ADDRESSES = + PREFIX_DISTRIBUTION_CLIENT + "MSG_BUS_ADDRESSES"; + protected static final String PROP_ML_DISTRIBUTION_HTTPS_WITH_DMAAP = + PREFIX_DISTRIBUTION_CLIENT + "USE_HTTPS_WITH_DMAAP"; protected static final String PROP_AAI_BASE_URL = PREFIX_AAI + "BASE_URL"; protected static final String PROP_AAI_KEYSTORE_FILE = PREFIX_AAI + SUFFIX_KEYSTORE_FILE; @@ -88,29 +90,16 @@ public class ModelLoaderConfig implements IConfiguration { protected static final String PROP_BABEL_GENERATE_RESOURCE_URL = PREFIX_BABEL + "GENERATE_ARTIFACTS_URL"; protected static final String PROP_DEBUG_INGEST_SIMULATOR = PREFIX_DEBUG + "INGEST_SIMULATOR"; - private static String configHome; + protected static final String FILESEP = + (System.getProperty("file.separator") == null) ? "/" : System.getProperty("file.separator"); + private static String configHome; private Properties modelLoaderProperties = null; - private String certLocation = "."; - private List artifactTypes = null; - private List msgBusAddrs = null; - private String modelVersion = null; - protected static final String FILESEP = (System.getProperty("file.separator") == null) ? "/" - : System.getProperty("file.separator"); - - public static void setConfigHome(String configHome) { - ModelLoaderConfig.configHome = configHome; - } - - public static String propertiesFile() { - return configHome + FILESEP + "model-loader.properties"; - } - public ModelLoaderConfig(Properties configProperties) { this(configProperties, ModelLoaderConfig.configHome + FILESEP + "auth" + FILESEP); } @@ -118,10 +107,8 @@ public class ModelLoaderConfig implements IConfiguration { /** * Original constructor * - * @param modelLoaderProperties - * properties needed to be configured for the model loader - * @param certLocation - * location of the certificate + * @param modelLoaderProperties properties needed to be configured for the model loader + * @param certLocation location of the certificate */ public ModelLoaderConfig(Properties modelLoaderProperties, String certLocation) { this.modelLoaderProperties = modelLoaderProperties; @@ -146,6 +133,14 @@ public class ModelLoaderConfig implements IConfiguration { } } + public static void setConfigHome(String configHome) { + ModelLoaderConfig.configHome = configHome; + } + + public static Path propertiesFile() { + return Paths.get(configHome, "model-loader.properties"); + } + @Override public boolean activateServerTLSAuth() { String value = modelLoaderProperties.getProperty(PROP_ML_DISTRIBUTION_ACTIVE_SERVER_TLS_AUTH); diff --git a/src/main/java/org/onap/aai/modelloader/entity/ArtifactType.java b/src/main/java/org/onap/aai/modelloader/entity/ArtifactType.java index a58c874..587b474 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/ArtifactType.java +++ b/src/main/java/org/onap/aai/modelloader/entity/ArtifactType.java @@ -24,5 +24,6 @@ public enum ArtifactType { MODEL, MODEL_V8, NAMED_QUERY, - VNF_CATALOG; + VNF_CATALOG, + VNF_CATALOG_XML; } diff --git a/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifact.java b/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifact.java index 9a84cf2..7447726 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifact.java +++ b/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifact.java @@ -28,6 +28,7 @@ public class VnfCatalogArtifact extends Artifact { public VnfCatalogArtifact(String payload) { this(ArtifactType.VNF_CATALOG, payload); } + public VnfCatalogArtifact(ArtifactType artifactType, String payload) { super(artifactType); setPayload(payload); diff --git a/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifactHandler.java b/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifactHandler.java index 3480c68..c54d7b2 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifactHandler.java +++ b/src/main/java/org/onap/aai/modelloader/entity/catalog/VnfCatalogArtifactHandler.java @@ -1,5 +1,5 @@ /** - * ============LICENSE_START======================================================= + * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. @@ -22,14 +22,20 @@ package org.onap.aai.modelloader.entity.catalog; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -import java.io.UnsupportedEncodingException; +import java.io.StringReader; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.UUID; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; import org.apache.commons.text.StringEscapeUtils; +import org.apache.http.client.utils.URIBuilder; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.modelloader.config.ModelLoaderConfig; @@ -38,7 +44,11 @@ import org.onap.aai.modelloader.entity.ArtifactHandler; import org.onap.aai.modelloader.restclient.AaiRestClient; import org.onap.aai.modelloader.service.ModelLoaderMsgs; import org.onap.aai.restclient.client.OperationResult; -import org.springframework.web.util.UriUtils; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; /** * VNF Catalog specific handling @@ -80,11 +90,47 @@ public class VnfCatalogArtifactHandler extends ArtifactHandler { return true; } + /* + * If something fails in the middle of ingesting the catalog we want to roll back any changes to the DB + */ + @Override + public void rollback(List completedArtifacts, String distributionId, AaiRestClient aaiClient) { + for (Artifact completedArtifact : completedArtifacts) { + Map data = new Gson().fromJson(completedArtifact.getPayload(), + new TypeToken>() {}.getType()); + String url = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" + data.get(ATTR_UUID); + // Try to delete the image. If something goes wrong we can't really do anything here + aaiClient.getAndDeleteResource(url, distributionId); + } + } + private void distributeVnfcData(AaiRestClient restClient, String distributionId, Artifact vnfcArtifact, List completedArtifacts) throws VnfImageException { + List> vnfcData; + switch (vnfcArtifact.getType()) { + case VNF_CATALOG: + vnfcData = unmarshallVnfcData(vnfcArtifact); + break; + case VNF_CATALOG_XML: + vnfcData = parseXmlVnfcData(vnfcArtifact); + break; + default: + throw new VnfImageException("Unsupported type " + vnfcArtifact.getType()); + } + distributeVnfcData(restClient, distributionId, completedArtifacts, vnfcData); + } - List> vnfcData = unmarshallVnfcData(vnfcArtifact); - + /** + * Build a VNF image from each of the supplied data items, and distribute to AAI + * + * @param restClient + * @param distributionId + * @param completedArtifacts + * @param vnfcData + * @throws VnfImageException + */ + private void distributeVnfcData(AaiRestClient restClient, String distributionId, List completedArtifacts, + List> vnfcData) throws VnfImageException { for (Map dataItem : vnfcData) { // If an empty dataItem is supplied, do nothing. if (dataItem.isEmpty()) { @@ -92,49 +138,47 @@ public class VnfCatalogArtifactHandler extends ArtifactHandler { continue; } - String urlParams; - StringBuilder imageId = new StringBuilder("vnf image"); - - try { - urlParams = buildUrlImgIdStrings(imageId, dataItem); - } catch (UnsupportedEncodingException e) { - throw new VnfImageException(e); + StringBuilder imageIdBuilder = new StringBuilder("vnf image"); + for (Entry entry : dataItem.entrySet()) { + imageIdBuilder.append(" ").append(entry.getValue()); } + String imageId = imageIdBuilder.toString(); + int resultCode = getVnfImage(restClient, distributionId, imageId, dataItem); - OperationResult tryGet = - restClient.getResource(config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "?" + urlParams, - distributionId, MediaType.APPLICATION_JSON_TYPE); - - if (tryGet == null) { - throw new VnfImageException(imageId.toString()); - } - - int resultCode = tryGet.getResultCode(); if (resultCode == Response.Status.NOT_FOUND.getStatusCode()) { // This vnf-image is missing, so add it boolean success = putVnfImage(restClient, dataItem, distributionId); - if (!success) { - throw new VnfImageException(imageId.toString()); + if (success) { + completedArtifacts.add(new VnfCatalogArtifact(new Gson().toJson(dataItem))); + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, imageId + " successfully ingested."); + } else { + throw new VnfImageException(imageId); } - completedArtifacts.add(vnfcArtifact); - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, imageId + " successfully ingested."); } else if (resultCode == Response.Status.OK.getStatusCode()) { logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, imageId + " already exists. Skipping ingestion."); } else { // if other than 404 or 200, something went wrong - throw new VnfImageException(imageId.toString(), resultCode); + throw new VnfImageException(imageId, resultCode); } } } - private String buildUrlImgIdStrings(StringBuilder imageId, Map dataItem) - throws UnsupportedEncodingException { - StringBuilder urlParams = new StringBuilder(); - for (Entry entry : dataItem.entrySet()) { - urlParams.append(entry.getKey()).append("=").append(UriUtils.encode(entry.getValue(), "UTF-8")).append("&"); - imageId.append(" ").append(entry.getValue()); + private int getVnfImage(AaiRestClient restClient, String distributionId, String imageId, + Map dataItem) throws VnfImageException { + try { + URIBuilder b = new URIBuilder(config.getAaiBaseUrl() + config.getAaiVnfImageUrl()); + for (Entry entry : dataItem.entrySet()) { + b.addParameter(entry.getKey(), entry.getValue()); + } + OperationResult tryGet = + restClient.getResource(b.build().toString(), distributionId, MediaType.APPLICATION_JSON_TYPE); + if (tryGet == null) { + throw new VnfImageException(imageId); + } + return tryGet.getResultCode(); + } catch (URISyntaxException ex) { + throw new VnfImageException(ex); } - return urlParams.deleteCharAt(urlParams.length() - 1).toString(); } private boolean putVnfImage(AaiRestClient restClient, Map dataItem, String distributionId) { @@ -155,19 +199,79 @@ public class VnfCatalogArtifactHandler extends ArtifactHandler { new TypeToken>>() {}.getType()); } - /* - * If something fails in the middle of ingesting the catalog we want to roll back any changes to the DB + /** + * Parse the VNF Catalog XML and transform into Key/Value pairs. + * + * @param vnfcArtifact + * @return VNF Image data in Map form + * @throws VnfImageException */ - @Override - public void rollback(List completedArtifacts, String distributionId, AaiRestClient aaiClient) { - for (Artifact completedArtifact : completedArtifacts) { - List> completedImageData = unmarshallVnfcData(completedArtifact); - for (Map data : completedImageData) { - String url = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" + data.get(ATTR_UUID); - // Try to delete the image. If something goes wrong we can't really do anything here - aaiClient.getAndDeleteResource(url, distributionId); + private List> parseXmlVnfcData(Artifact vnfcArtifact) throws VnfImageException { + List> vnfcData = new ArrayList<>(); + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + DocumentBuilder builder = factory.newDocumentBuilder(); + InputSource is = new InputSource(new StringReader(vnfcArtifact.getPayload())); + Document doc = builder.parse(is); + doc.getDocumentElement().normalize(); + + NodeList pnl = doc.getElementsByTagName("part-number-list"); + for (int i = 0; i < pnl.getLength(); i++) { + Node partNumber = pnl.item(i); + if (partNumber.getNodeType() == Node.ELEMENT_NODE) { + Element vendorInfo = getFirstChildNodeByName(partNumber, "vendor-info"); + if (vendorInfo != null) { + Map application = new HashMap<>(); + application.put("application", + vendorInfo.getElementsByTagName("vendor-model").item(0).getTextContent()); + application.put("application-vendor", + vendorInfo.getElementsByTagName("vendor-name").item(0).getTextContent()); + populateSoftwareVersions(vnfcData, application, partNumber); + } + } + } + } catch (Exception ex) { + throw new VnfImageException(ex); + } + return vnfcData; + } + + /** + * @param vnfcData to populate + * @param applicationData + * @param partNumber + */ + private void populateSoftwareVersions(List> vnfcData, Map applicationData, + Node partNumber) { + NodeList nodes = partNumber.getChildNodes(); + for (int i = 0; i < nodes.getLength(); i++) { + Node childNode = nodes.item(i); + if (childNode.getNodeName().equalsIgnoreCase("software-version-list")) { + Element softwareVersion = getFirstChildNodeByName(childNode, "software-version"); + if (softwareVersion != null) { + HashMap vnfImageData = new HashMap<>(applicationData); + vnfImageData.put("application-version", softwareVersion.getTextContent()); + vnfcData.add(vnfImageData); + } + } + } + } + + /** + * @param node + * @param childNodeName + * @return the first child node matching the given name + */ + private Element getFirstChildNodeByName(Node node, String childNodeName) { + NodeList nodes = node.getChildNodes(); + for (int i = 0; i < nodes.getLength(); i++) { + Node childNode = nodes.item(i); + if (childNode.getNodeName().equalsIgnoreCase(childNodeName)) { + return (Element) childNode; } } + return null; } } diff --git a/src/main/java/org/onap/aai/modelloader/extraction/VnfCatalogExtractor.java b/src/main/java/org/onap/aai/modelloader/extraction/VnfCatalogExtractor.java new file mode 100644 index 0000000..5682774 --- /dev/null +++ b/src/main/java/org/onap/aai/modelloader/extraction/VnfCatalogExtractor.java @@ -0,0 +1,107 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.extraction; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.regex.Pattern; +import org.apache.commons.compress.archivers.zip.ZipArchiveEntry; +import org.apache.commons.compress.archivers.zip.ZipFile; +import org.apache.commons.compress.utils.SeekableInMemoryByteChannel; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.modelloader.entity.Artifact; +import org.onap.aai.modelloader.entity.ArtifactType; +import org.onap.aai.modelloader.entity.catalog.VnfCatalogArtifact; +import org.onap.aai.modelloader.service.ModelLoaderMsgs; + + +/** + * The purpose of this class is to process a .csar file in the form of a byte array and extract VNF Catalog XML files + * from it. + * + * A .csar file is a compressed archive like a zip file and this class will treat the byte array as it if were a zip + * file. + */ +public class VnfCatalogExtractor { + private static final Logger logger = LoggerFactory.getInstance().getLogger(VnfCatalogExtractor.class.getName()); + + private static final Pattern VNFCFILE_EXTENSION_REGEX = + Pattern.compile("(?i)artifacts(\\\\|\\/)deployment(\\\\|\\/)vnf_catalog(\\\\|\\/).*\\.xml$"); + + /** + * This method is responsible for filtering the contents of the supplied archive and returning a collection of + * {@link Artifact}s that represent the VNF Catalog files that have been found in the archive.
+ *
+ * If the archive contains no VNF Catalog files it will return an empty list.
+ * + * @param archive the zip file in the form of a byte array containing zero or more VNF Catalog files + * @param name the name of the archive file + * @return List collection of VNF Catalog XML files found in the archive + * @throws InvalidArchiveException if an error occurs trying to extract the VNFC files from the archive or if the + * archive is not a zip file + */ + public List extract(byte[] archive, String name) throws InvalidArchiveException { + validateRequest(archive, name); + + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Extracting CSAR archive: " + name); + + List vnfcFiles = new ArrayList<>(); + try (SeekableInMemoryByteChannel inMemoryByteChannel = new SeekableInMemoryByteChannel(archive); + ZipFile zipFile = new ZipFile(inMemoryByteChannel)) { + for (Enumeration enumeration = zipFile.getEntries(); enumeration.hasMoreElements();) { + ZipArchiveEntry entry = enumeration.nextElement(); + if (fileShouldBeExtracted(entry)) { + vnfcFiles.add(new VnfCatalogArtifact(ArtifactType.VNF_CATALOG_XML, + IOUtils.toString(zipFile.getInputStream(entry)))); + } + } + } catch (IOException e) { + throw new InvalidArchiveException( + "An error occurred trying to create a ZipFile. Is the content being converted really a csar file?", + e); + } + + logger.debug(ModelLoaderMsgs.DISTRIBUTION_EVENT, vnfcFiles.size() + " VNF Catalog files extracted."); + + return vnfcFiles; + } + + private static void validateRequest(byte[] archive, String name) throws InvalidArchiveException { + if (archive == null || archive.length == 0) { + throw new InvalidArchiveException("An archive must be supplied for processing."); + } else if (StringUtils.isBlank(name)) { + throw new InvalidArchiveException("The name of the archive must be supplied for processing."); + } + } + + private static boolean fileShouldBeExtracted(ZipArchiveEntry entry) { + logger.debug(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Checking if " + entry.getName() + " should be extracted..."); + boolean extractFile = VNFCFILE_EXTENSION_REGEX.matcher(entry.getName()).matches(); + logger.debug(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Keeping file: " + entry.getName() + "? : " + extractFile); + return extractFile; + } +} + diff --git a/src/main/java/org/onap/aai/modelloader/notification/ArtifactDownloadManager.java b/src/main/java/org/onap/aai/modelloader/notification/ArtifactDownloadManager.java index febc99a..58bb074 100644 --- a/src/main/java/org/onap/aai/modelloader/notification/ArtifactDownloadManager.java +++ b/src/main/java/org/onap/aai/modelloader/notification/ArtifactDownloadManager.java @@ -1,5 +1,5 @@ /** - * ============LICENSE_START======================================================= + * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. @@ -38,6 +38,7 @@ import org.onap.aai.modelloader.entity.model.BabelArtifactParsingException; import org.onap.aai.modelloader.entity.model.IModelParser; import org.onap.aai.modelloader.entity.model.NamedQueryArtifactParser; import org.onap.aai.modelloader.extraction.InvalidArchiveException; +import org.onap.aai.modelloader.extraction.VnfCatalogExtractor; import org.onap.aai.modelloader.restclient.BabelServiceClient; import org.onap.aai.modelloader.restclient.BabelServiceClientException; import org.onap.aai.modelloader.service.BabelServiceClientFactory; @@ -68,6 +69,7 @@ public class ArtifactDownloadManager { private BabelArtifactConverter babelArtifactConverter; private ModelLoaderConfig config; private BabelServiceClientFactory clientFactory; + private VnfCatalogExtractor vnfCatalogExtractor; public ArtifactDownloadManager(IDistributionClient client, ModelLoaderConfig config, BabelServiceClientFactory clientFactory) { @@ -148,13 +150,33 @@ public class ArtifactDownloadManager { } public void processToscaArtifacts(List modelArtifacts, List catalogArtifacts, byte[] payload, + IArtifactInfo artifactInfo, String distributionId, String serviceVersion) + throws ProcessToscaArtifactsException, InvalidArchiveException { + // Get translated artifacts from Babel Service + invokeBabelService(modelArtifacts, catalogArtifacts, payload, artifactInfo, distributionId, serviceVersion); + + // Get VNF Catalog artifacts directly from CSAR + List csarCatalogArtifacts = getVnfCatalogExtractor().extract(payload, artifactInfo.getArtifactName()); + + // Throw an error if VNF Catalog data is present in the Babel payload and directly in the CSAR + if (!catalogArtifacts.isEmpty() && !csarCatalogArtifacts.isEmpty()) { + logger.error(ModelLoaderMsgs.DUPLICATE_VNFC_DATA_ERROR, artifactInfo.getArtifactName()); + throw new InvalidArchiveException("CSAR: " + artifactInfo.getArtifactName() + + " contains VNF Catalog data in the format of both TOSCA and XML files. Only one format can be used for each CSAR file."); + } else if (!csarCatalogArtifacts.isEmpty()) { + catalogArtifacts.addAll(csarCatalogArtifacts); + } + } + + public void invokeBabelService(List modelArtifacts, List catalogArtifacts, byte[] payload, IArtifactInfo artifactInfo, String distributionId, String serviceVersion) throws ProcessToscaArtifactsException { try { BabelServiceClient babelClient = createBabelServiceClient(artifactInfo, serviceVersion); - logger.debug(ModelLoaderMsgs.DISTRIBUTION_EVENT, - "Posting artifact: " + artifactInfo.getArtifactName() + ", version: " + serviceVersion); + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, + "Posting artifact: " + artifactInfo.getArtifactName() + ", service version: " + serviceVersion + + ", artifact version: " + artifactInfo.getArtifactVersion()); List babelArtifacts = babelClient.postArtifact(payload, artifactInfo.getArtifactName(), serviceVersion, distributionId); @@ -251,4 +273,12 @@ public class ArtifactDownloadManager { return babelArtifactConverter; } + + private VnfCatalogExtractor getVnfCatalogExtractor() { + if (vnfCatalogExtractor == null) { + vnfCatalogExtractor = new VnfCatalogExtractor(); + } + + return vnfCatalogExtractor; + } } diff --git a/src/main/java/org/onap/aai/modelloader/notification/NotificationPublisher.java b/src/main/java/org/onap/aai/modelloader/notification/NotificationPublisher.java index 626399e..4f552f7 100644 --- a/src/main/java/org/onap/aai/modelloader/notification/NotificationPublisher.java +++ b/src/main/java/org/onap/aai/modelloader/notification/NotificationPublisher.java @@ -52,7 +52,7 @@ public class NotificationPublisher { public NotificationPublisher() { Properties configProperties = new Properties(); try { - configProperties.load(Files.newInputStream(Paths.get(ModelLoaderConfig.propertiesFile()))); + configProperties.load(Files.newInputStream(ModelLoaderConfig.propertiesFile())); } catch (IOException e) { String errorMsg = "Failed to load configuration: " + e.getMessage(); logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, e, errorMsg); diff --git a/src/main/java/org/onap/aai/modelloader/service/ModelLoaderMsgs.java b/src/main/java/org/onap/aai/modelloader/service/ModelLoaderMsgs.java index fd39a9a..26a9efa 100644 --- a/src/main/java/org/onap/aai/modelloader/service/ModelLoaderMsgs.java +++ b/src/main/java/org/onap/aai/modelloader/service/ModelLoaderMsgs.java @@ -1,120 +1,125 @@ -/** - * ============LICENSE_START======================================================= - * org.onap.aai - * ================================================================================ - * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017-2018 European Software Marketing Ltd. - * ================================================================================ - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * ============LICENSE_END========================================================= - */ -package org.onap.aai.modelloader.service; - -import com.att.eelf.i18n.EELFResourceManager; -import org.onap.aai.cl.eelf.LogMessageEnum; - -public enum ModelLoaderMsgs implements LogMessageEnum { - - /** - * Arguments: None. - */ - LOADING_CONFIGURATION, - - /** - * Arguments: None. - */ - STOPPING_CLIENT, - - /** - * Arguments: {0} = message. - */ - INITIALIZING, - - /** - * Arguments: {0} = reason. - */ - ASDC_CONNECTION_ERROR, - - /** - * Arguments: {0} = message. - */ - DISTRIBUTION_EVENT, - - /** - * Arguments: {0} = error message. - */ - DISTRIBUTION_EVENT_ERROR, - - /** - * Arguments: {0} = request type. {1} = endpoint. {2} = result code. - */ - AAI_REST_REQUEST_SUCCESS, - - /** - * Arguments: {0} = request type. {1} = endpoint. {2} = result code. {3} = result. message - */ - AAI_REST_REQUEST_UNSUCCESSFUL, - - /** - * Arguments: {0} = request type. {1} = endpoint. {2} = error message. - */ - AAI_REST_REQUEST_ERROR, - - /** - * Arguments: {0} = request type. {1} = endpoint. {2} = error message. - */ - BABEL_REST_REQUEST_ERROR, - - /** - * Arguments: {0} = info request payload. - **/ - AAI_REST_REQUEST_PAYLOAD, - - /** - * Arguments: {0} = artifact name - */ - ARTIFACT_PARSE_ERROR, - - /** - * Arguments: {0} = info request payload. - **/ - BABEL_REST_REQUEST_PAYLOAD, - - /** - * Arguments: {0} = info Babel response payload. - **/ - BABEL_RESPONSE_PAYLOAD, - - /** - * Arguments: {0} = artifact name. {1} = payload. - */ - DOWNLOAD_COMPLETE, - - /** - * Arguments: {0} = event. {1} = artifact name. {2} = result. - */ - EVENT_PUBLISHED, - - /** - * Arguments: {0} = artifact name. {1} = artifact type. - */ - UNSUPPORTED_ARTIFACT_TYPE; - - /** - * Load message bundle (ModelLoaderMsgs.properties file) - */ - static { - EELFResourceManager.loadMessageBundle("org/onap/aai/modelloader/service/ModelLoaderMsgs"); - } - -} +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 European Software Marketing Ltd. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ +package org.onap.aai.modelloader.service; + +import com.att.eelf.i18n.EELFResourceManager; +import org.onap.aai.cl.eelf.LogMessageEnum; + +public enum ModelLoaderMsgs implements LogMessageEnum { + + /** + * Arguments: None. + */ + LOADING_CONFIGURATION, + + /** + * Arguments: None. + */ + STOPPING_CLIENT, + + /** + * Arguments: {0} = message. + */ + INITIALIZING, + + /** + * Arguments: {0} = reason. + */ + ASDC_CONNECTION_ERROR, + + /** + * Arguments: {0} = message. + */ + DISTRIBUTION_EVENT, + + /** + * Arguments: {0} = error message. + */ + DISTRIBUTION_EVENT_ERROR, + + /** + * Arguments: {0} = request type. {1} = endpoint. {2} = result code. + */ + AAI_REST_REQUEST_SUCCESS, + + /** + * Arguments: {0} = request type. {1} = endpoint. {2} = result code. {3} = result. message + */ + AAI_REST_REQUEST_UNSUCCESSFUL, + + /** + * Arguments: {0} = request type. {1} = endpoint. {2} = error message. + */ + AAI_REST_REQUEST_ERROR, + + /** + * Arguments: {0} = request type. {1} = endpoint. {2} = error message. + */ + BABEL_REST_REQUEST_ERROR, + + /** + * Arguments: {0} = info request payload. + **/ + AAI_REST_REQUEST_PAYLOAD, + + /** + * Arguments: {0} = artifact name + */ + ARTIFACT_PARSE_ERROR, + + /** + * Arguments: {0} = info request payload. + **/ + BABEL_REST_REQUEST_PAYLOAD, + + /** + * Arguments: {0} = info Babel response payload. + **/ + BABEL_RESPONSE_PAYLOAD, + + /** + * Arguments: {0} = artifact name. {1} = payload. + */ + DOWNLOAD_COMPLETE, + + /** + * Arguments: {0} = event. {1} = artifact name. {2} = result. + */ + EVENT_PUBLISHED, + + /** + * Arguments: {0} = artifact name. {1} = artifact type. + */ + UNSUPPORTED_ARTIFACT_TYPE, + + /** + * Arguments: {0} = artifact name. + */ + DUPLICATE_VNFC_DATA_ERROR; + + /** + * Load message bundle (ModelLoaderMsgs.properties file) + */ + static { + EELFResourceManager.loadMessageBundle("org/onap/aai/modelloader/service/ModelLoaderMsgs"); + } + +} diff --git a/src/main/java/org/onap/aai/modelloader/util/JsonXmlConverter.java b/src/main/java/org/onap/aai/modelloader/util/JsonXmlConverter.java index 87cfdcc..84218e5 100644 --- a/src/main/java/org/onap/aai/modelloader/util/JsonXmlConverter.java +++ b/src/main/java/org/onap/aai/modelloader/util/JsonXmlConverter.java @@ -42,11 +42,11 @@ public final class JsonXmlConverter { try { new JSONObject(text); isValid = true; - } catch (JSONException ex) { + } catch (JSONException ex) { // NOSONAR try { new JSONArray(text); isValid = true; - } catch (JSONException ex1) { + } catch (JSONException ex1) { // NOSONAR isValid = false; } } -- cgit 1.2.3-korg