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=b224407ec827b537f1d0830dc33d781f918447ae;hp=9022516e0d4013ab9144b0d5b627466a716b85c1;hb=7b1f813441f94261f43ec4f5bb0944ad2570fbdf;hpb=4dd316529148d07059d844197cdb676806bdc0c6 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 9022516..b224407 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 @@ -20,171 +20,159 @@ */ 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.onap.aai.cl.api.Logger; -import org.onap.aai.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(); + } + + 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()); } - 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 + /* + * 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); + } + } } - } }