X-Git-Url: https://gerrit.onap.org/r/gitweb?p=aai%2Fmodel-loader.git;a=blobdiff_plain;f=src%2Fmain%2Fjava%2Forg%2Fonap%2Faai%2Fmodelloader%2Fentity%2Fcatalog%2FVnfCatalogArtifactHandler.java;h=c54d7b2df5f7b079624679e3b0fd3123f0a689e9;hp=3480c68a142b29a1e5e3c3b9cb8c0a9aa5410647;hb=7e6fe8c29c5a5cfa5caf6ab47b30280e1fc20432;hpb=c5aea4a8bc398fc1c6220875e55b9520fd7f7524 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; } }