X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;ds=sidebyside;f=src%2Fmain%2Fjava%2Forg%2Fonap%2Faai%2Fmodelloader%2Fentity%2Fcatalog%2FVnfCatalogArtifactHandler.java;h=85be50be7bf6afcdc683aa91574b79711171f5ba;hb=6e4f04afea4c2d07fdd9c15eda38438c7baeb308;hp=9ef3f6f39b0b21ee900b082b99d2c0e5a0c1986f;hpb=059f42e1a2289ecb2cb5835b8b14a0d098c9e1d3;p=aai%2Fmodel-loader.git 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 9ef3f6f..85be50b 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,16 +1,15 @@ /** - * ============LICENSE_START======================================================= + * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. - * Copyright © 2017 Amdocs - * All rights reserved. + * 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 + * 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, @@ -18,176 +17,162 @@ * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ package org.onap.aai.modelloader.entity.catalog; -import com.sun.jersey.api.client.ClientResponse; - -import generated.VnfCatalog; -import generated.VnfCatalog.PartNumberList; - -import inventory.aai.openecomp.org.v8.VnfImage; - -import org.eclipse.persistence.jaxb.MarshallerProperties; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import java.io.UnsupportedEncodingException; +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 org.apache.commons.text.StringEscapeUtils; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.modelloader.config.ModelLoaderConfig; import org.onap.aai.modelloader.entity.Artifact; import org.onap.aai.modelloader.entity.ArtifactHandler; import org.onap.aai.modelloader.restclient.AaiRestClient; -import org.onap.aai.modelloader.restclient.AaiRestClient.MimeType; import org.onap.aai.modelloader.service.ModelLoaderMsgs; -import org.openecomp.cl.api.Logger; -import org.openecomp.cl.eelf.LoggerFactory; +import org.onap.aai.restclient.client.OperationResult; import org.springframework.web.util.UriUtils; -import java.io.StringReader; -import java.io.StringWriter; -import java.io.UnsupportedEncodingException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import javax.ws.rs.core.Response; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; - - +/** + * VNF Catalog specific handling + */ public class VnfCatalogArtifactHandler extends ArtifactHandler { - private static Logger logger = LoggerFactory.getInstance() - .getLogger(VnfCatalogArtifactHandler.class.getName()); - - public VnfCatalogArtifactHandler(ModelLoaderConfig config) { - super(config); - } + private static Logger logger = LoggerFactory.getInstance().getLogger(VnfCatalogArtifactHandler.class.getName()); - @Override - public boolean pushArtifacts(List artifacts, String distributionId) { - for (Artifact art : artifacts) { - VnfCatalogArtifact vnfCatalog = (VnfCatalogArtifact) art; - String artifactPayload = vnfCatalog.getPayload(); + public static final String ATTR_UUID = "uuid"; - AaiRestClient restClient = new AaiRestClient(this.config); - List putImages = new ArrayList(); - - try { - JAXBContext inputContext = JAXBContext.newInstance(VnfCatalog.class); - Unmarshaller unmarshaller = inputContext.createUnmarshaller(); - StringReader reader = new StringReader(artifactPayload); - VnfCatalog cat = (VnfCatalog) unmarshaller.unmarshal(reader); + public VnfCatalogArtifactHandler(ModelLoaderConfig config) { + super(config); + } - int numParts = cat.getPartNumberList().size(); + /* + * (non-Javadoc) + * + * @see org.openecomp.modelloader.entity.ArtifactHandler#pushArtifacts(java.util.List, java.lang.String) + */ + @Override + public boolean pushArtifacts(List artifacts, String distributionId, List completedArtifacts, + AaiRestClient aaiClient) { + for (Artifact artifact : artifacts) { + try { + distributeVnfcData(aaiClient, distributionId, artifact, completedArtifacts); + } catch (VnfImageException e) { + if (e.getResultCode().isPresent()) { + logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, + "Ingestion failed on vnf-image " + e.getImageId() + " with status " + + e.getResultCode().orElse(0) + ". Rolling back distribution."); + } else { + logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, + "Ingestion failed on " + e.getImageId() + ". Rolling back distribution."); + } + return false; + } + } - for (int i = 0; i < numParts; i++) { + return true; + } - PartNumberList pnl = cat.getPartNumberList().get(i); + private void distributeVnfcData(AaiRestClient restClient, String distributionId, Artifact vnfcArtifact, + List completedArtifacts) throws VnfImageException { - String application = pnl.getVendorInfo().getVendorModel(); - String applicationVendor = pnl.getVendorInfo().getVendorName(); + List> vnfcData = unmarshallVnfcData(vnfcArtifact); - int numVersions = pnl.getSoftwareVersionList().size(); + for (Map dataItem : vnfcData) { + // If an empty dataItem is supplied, do nothing. + if (dataItem.isEmpty()) { + logger.warn(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Empty image data supplied, skipping ingestion."); + return; + } - for (int j = 0; j < numVersions; j++) { - String applicationVersion = pnl.getSoftwareVersionList().get(j).getSoftwareVersion(); + String urlParams; + StringBuilder imageId = new StringBuilder("vnf image"); - String imageId = "vnf image " + applicationVendor + " " + application + " " - + applicationVersion; + try { + urlParams = buildUrlImgIdStrings(imageId, dataItem); + } catch (UnsupportedEncodingException e) { + throw new VnfImageException(e); + } - String queryURI = "application-vendor=" + applicationVendor + "&application=" + application + "&application-version=" + applicationVersion; - - String getUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "?" + UriUtils.encodePath(queryURI, "UTF-8"); + OperationResult tryGet = + restClient.getResource(config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "?" + urlParams, + distributionId, MediaType.APPLICATION_JSON_TYPE); - ClientResponse tryGet = restClient.getResource(getUrl, distributionId, MimeType.JSON); if (tryGet == null) { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, - "Ingestion failed on " + imageId + ". Rolling back distribution."); - failureCleanup(putImages, restClient, distributionId); - return false; + throw new VnfImageException(imageId.toString()); } - if (tryGet.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) { - // this vnf-image not already in the db, need to add - // only do this on 404 bc other error responses could mean there - // are problems that - // you might not want to try to PUT against - - VnfImage image = new VnfImage(); - image.setApplication(application); - image.setApplicationVendor(applicationVendor); - image.setApplicationVersion(applicationVersion); - String uuid = UUID.randomUUID().toString(); - image.setUuid(uuid); // need to create uuid - - System.setProperty("javax.xml.bind.context.factory", - "org.eclipse.persistence.jaxb.JAXBContextFactory"); - JAXBContext jaxbContext = JAXBContext.newInstance(VnfImage.class); - Marshaller marshaller = jaxbContext.createMarshaller(); - marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json"); - marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false); - marshaller.setProperty(MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true); - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); - StringWriter writer = new StringWriter(); - marshaller.marshal(image, writer); - String payload = writer.toString(); - - String putUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" - + uuid; - - ClientResponse putResp = restClient.putResource(putUrl, payload, distributionId, - MimeType.JSON); - if (putResp == null - || putResp.getStatus() != Response.Status.CREATED.getStatusCode()) { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, - "Ingestion failed on vnf-image " + imageId + ". Rolling back distribution."); - failureCleanup(putImages, restClient, distributionId); - return false; - } - putImages.add(image); - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, imageId + " successfully ingested."); - } else if (tryGet.getStatus() == Response.Status.OK.getStatusCode()) { - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, - imageId + " already exists. Skipping ingestion."); + + 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()); + } + 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 - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, - "Ingestion failed on vnf-image " + imageId + " with status " + tryGet.getStatus() - + ". Rolling back distribution."); - failureCleanup(putImages, restClient, distributionId); - return false; + // if other than 404 or 200, something went wrong + throw new VnfImageException(imageId.toString(), resultCode); } - } } + } - } catch (JAXBException e) { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, - "Ingestion failed. " + e.getMessage() + ". Rolling back distribution."); - failureCleanup(putImages, restClient, distributionId); - return false; - } catch (UnsupportedEncodingException e) { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Ingestion failed. " + e.getMessage() + ". Rolling back distribution."); - failureCleanup(putImages, restClient, distributionId); - return false; - } + 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()); + } + return urlParams.deleteCharAt(urlParams.length() - 1).toString(); } - return true; - } - - /* - * if something fails in the middle of ingesting the catalog we want to - * rollback any changes to the db - */ - private void failureCleanup(List putImages, AaiRestClient restClient, String transId) { - for (VnfImage image : putImages) { - String url = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" - + image.getUuid(); - restClient.getAndDeleteResource(url, transId); // try to delete the image, - // if something goes wrong - // we can't really do - // anything here + private boolean putVnfImage(AaiRestClient restClient, Map dataItem, String distributionId) { + // Generate a new UUID for the image data item + String uuid = UUID.randomUUID().toString(); + dataItem.put(ATTR_UUID, uuid); + + String payload = createVnfImagePayload(dataItem); + String putUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" + uuid; + OperationResult putResp = + restClient.putResource(putUrl, payload, distributionId, MediaType.APPLICATION_JSON_TYPE); + return putResp != null && putResp.getResultCode() == Response.Status.CREATED.getStatusCode(); + } + + private String createVnfImagePayload(Map dataItem) { + dataItem.put(ATTR_UUID, UUID.randomUUID().toString()); + return new Gson().toJson(dataItem); + } + + private List> unmarshallVnfcData(Artifact vnfcArtifact) { + // Unmarshall Babel JSON payload into a List of Maps of JSON attribute name/values. + return new Gson().fromJson(StringEscapeUtils.unescapeJson(vnfcArtifact.getPayload()), + new TypeToken>>() {}.getType()); + } + + /* + * 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) { + 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); + } + } } - } }