X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Forg%2Fonap%2Faai%2Fmodelloader%2Fentity%2Fmodel%2FModelArtifact.java;h=364fc78fb3520e131570ed308fd68b17c033559c;hb=refs%2Fheads%2Fmaster;hp=f0e848dad04e4355c4a20f6e9d4f4472eafd83c5;hpb=059f42e1a2289ecb2cb5835b8b14a0d098c9e1d3;p=aai%2Fmodel-loader.git diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java index f0e848d..364fc78 100644 --- a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java +++ b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java @@ -2,15 +2,14 @@ * ============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,194 +17,296 @@ * 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.model; -import java.io.StringWriter; import java.util.List; -import javax.ws.rs.core.Response; -import javax.xml.transform.OutputKeys; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - +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.ArtifactType; import org.onap.aai.modelloader.restclient.AaiRestClient; import org.onap.aai.modelloader.service.ModelLoaderMsgs; -import org.openecomp.cl.api.Logger; -import org.openecomp.cl.eelf.LoggerFactory; -import org.w3c.dom.Node; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.client.HttpClientErrorException; +import org.springframework.web.client.HttpServerErrorException; -import com.sun.jersey.api.client.ClientResponse; public class ModelArtifact extends AbstractModelArtifact { - private static final String AAI_MODEL_VER_SUB_URL = "/model-vers/model-ver"; - - private static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifact.class.getName()); - - private String modelVerId; - private String modelInvariantId; - private Node modelVer; - private boolean firstVersionOfModel = false; - - public ModelArtifact() { - super(ArtifactType.MODEL); - } - - public String getModelVerId() { - return modelVerId; - } - - public void setModelVerId(String modelVerId) { - this.modelVerId = modelVerId; - } - - public String getModelInvariantId() { - return modelInvariantId; - } - - public void setModelInvariantId(String modelInvariantId) { - this.modelInvariantId = modelInvariantId; - } - - public Node getModelVer() { - return modelVer; - } - - public void setModelVer(Node modelVer) { - this.modelVer = modelVer; - } - - @Override - public String getUniqueIdentifier() { - return getModelInvariantId() + "|" + getModelVerId(); - } - - @Override - public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List addedModels) { - ClientResponse getResponse = aaiClient.getResource(getModelUrl(config), distId, AaiRestClient.MimeType.XML); - if ( (getResponse == null) || (getResponse.getStatus() != Response.Status.OK.getStatusCode()) ) { - // Only attempt the PUT if the model doesn't already exist - ClientResponse putResponse = aaiClient.putResource(getModelUrl(config), getPayload(), distId, AaiRestClient.MimeType.XML); - if ( (putResponse != null) && (putResponse.getStatus() == Response.Status.CREATED.getStatusCode()) ) { - addedModels.add(this); - - // Flag this as the first version of the model that has been added. - firstVersionOfModel = true; - - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, getType().toString() + " " + getUniqueIdentifier() + " successfully ingested."); - } - else { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Ingestion failed for " + getType().toString() + " " + getUniqueIdentifier() + - ". Rolling back distribution."); - return false; - } - } - else { - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, getType().toString() + " " + getModelInvariantId() + " already exists. Skipping ingestion."); - getResponse = aaiClient.getResource(getModelVerUrl(config), distId, AaiRestClient.MimeType.XML); - if ( (getResponse == null) || (getResponse.getStatus() != Response.Status.OK.getStatusCode()) ) { - // Only attempt the PUT if the model-ver doesn't already exist - ClientResponse putResponse = null; + private static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifact.class); + + private static final String AAI_MODEL_VER_SUB_URL = "/model-vers/model-ver"; + + private static final String FAILURE_MSG_PREFIX = "Ingestion failed for "; + private static final String ROLLBACK_MSG_SUFFIX = ". Rolling back distribution."; + + + private String modelVerId; + private String modelInvariantId; + private String modelVer; + private boolean firstVersionOfModel = false; + + public ModelArtifact() { + super(ArtifactType.MODEL); + } + + public String getModelVerId() { + return modelVerId; + } + + public void setModelVerId(String modelVerId) { + this.modelVerId = modelVerId; + } + + public String getModelInvariantId() { + return modelInvariantId; + } + + public void setModelInvariantId(String modelInvariantId) { + this.modelInvariantId = modelInvariantId; + } + + public String getModelVer() { + return modelVer; + } + + public void setModelVer(String modelVer) { + this.modelVer = modelVer; + } + + @Override + public String getUniqueIdentifier() { + return getModelInvariantId() + "|" + getModelVerId(); + } + + + /** + * Test whether the specified resource (URL) can be requested successfully + * + * @param aaiClient + * @param distId + * @param xmlResourceUrl + * @return true if a request to GET this resource as XML media is successful (status OK) + */ + private boolean xmlResourceCanBeFetched(AaiRestClient aaiClient, String distId, String xmlResourceUrl) { + try { + ResponseEntity getResponse = getResourceModel(aaiClient, distId, xmlResourceUrl); + return getResponse.getStatusCode().equals(HttpStatus.OK); + } catch (HttpClientErrorException e) { + if(e.getStatusCode().equals(HttpStatus.NOT_FOUND)) { + return false; + } else { + throw e; + } + } + } + + /** + * Test whether the specified resource (URL) can be requested successfully + * + * @param aaiClient + * @param distId + * @param xmlResourceUrl + * @return OperationResult the result of the operation + */ + private ResponseEntity getResourceModel(AaiRestClient aaiClient, String distId, String xmlResourceUrl) { + return aaiClient.getResource(xmlResourceUrl, distId, MediaType.APPLICATION_XML, Model.class); + } + + /** + * PUT the specified XML resource + * + * @param aaiClient + * @param distId + * @param resourceUrl + * @param payload + * @return true if the resource PUT as XML media was successful (status OK) + */ + private boolean putXmlResource(AaiRestClient aaiClient, String distId, String resourceUrl, String payload) { + ResponseEntity putResponse = null; + try { + putResponse = + aaiClient.putResource(resourceUrl, payload, distId, MediaType.APPLICATION_XML, String.class); + } catch (HttpClientErrorException | HttpServerErrorException e) { + logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "Error putting resource: " + e.toString()); + } + return putResponse != null && putResponse.getStatusCode() == HttpStatus.CREATED; + } + + @Override + public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, + List completedArtifacts) { + if (config.useGizmo()) { + return pushToGizmo(aaiClient, config, distId); + } + + return pushToResources(aaiClient, config, distId, completedArtifacts); + } + + private boolean pushToResources(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, + List completedArtifacts) { + boolean success = false; + + // See whether the model is already present + String resourceUrl = getModelUrl(config); + // ResponseEntity result; + boolean modelExists = checkIfModelExists(aaiClient, distId, resourceUrl); + + if(modelExists) { + success = updateExistingModel(aaiClient, config, distId, completedArtifacts); + } else { + success = createNewModel(aaiClient, distId, completedArtifacts, resourceUrl); + } + + // if (result != null) { + // if (result.getStatusCode() == HttpStatus.OK) { + // success = updateExistingModel(aaiClient, config, distId, completedArtifacts); + // } else if (result.getStatusCode() == HttpStatus.NOT_FOUND) { + // success = createNewModel(aaiClient, distId, completedArtifacts, resourceUrl); + // } else { + // logModelUpdateFailure( + // "Response code " + result.getStatusCodeValue() + " invalid for getting resource model"); + // } + // } else { + // logModelUpdateFailure("Null response from RestClient"); + // } + + return success; + } + private boolean checkIfModelExists(AaiRestClient aaiClient, String distId, String resourceUrl) throws HttpClientErrorException { try { - putResponse = aaiClient.putResource(getModelVerUrl(config), nodeToString(getModelVer()), distId, AaiRestClient.MimeType.XML); - } catch (TransformerException e) { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Ingestion failed for " + getType().toString() + " " + getUniqueIdentifier() - + ": " + e.getMessage() + ". Rolling back distribution."); - return false; - } - if ( (putResponse != null) && (putResponse.getStatus() == Response.Status.CREATED.getStatusCode()) ) { - addedModels.add(this); - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, getType().toString() + " " + getUniqueIdentifier() + " successfully ingested."); - } - else { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Ingestion failed for " + getType().toString() + " " - + getUniqueIdentifier() + ". Rolling back distribution."); - return false; - } - } - else { - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, getType().toString() + " " + getUniqueIdentifier() + " already exists. Skipping ingestion."); - } - } - - return true; - } - - @Override - public void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) { - String url = getModelVerUrl(config); - if (firstVersionOfModel) { - // If this was the first version of the model which was added, we want to remove the entire - // model rather than just the version. - url = getModelUrl(config); - } - - // Best effort to delete. Nothing we can do in the event this fails. - aaiClient.getAndDeleteResource(url, distId); - } - - private String getModelUrl(ModelLoaderConfig config) { - String baseURL = config.getAaiBaseUrl().trim(); - String subURL = null; - String instance = null; - - subURL = config.getAaiModelUrl(getModelNamespaceVersion()).trim(); - instance = getModelInvariantId(); - - if ( (!baseURL.endsWith("/")) && (!subURL.startsWith("/")) ) { - baseURL = baseURL + "/"; - } - - if ( baseURL.endsWith("/") && subURL.startsWith("/") ) { - baseURL = baseURL.substring(0, baseURL.length()-1); - } - - if (!subURL.endsWith("/")) { - subURL = subURL + "/"; - } - - String url = baseURL + subURL + instance; - return url; - } - - private String getModelVerUrl(ModelLoaderConfig config) { - String baseURL = config.getAaiBaseUrl().trim(); - String subURL = null; - String instance = null; - - subURL = config.getAaiModelUrl(getModelNamespaceVersion()).trim() + getModelInvariantId() + AAI_MODEL_VER_SUB_URL; - instance = getModelVerId(); - - if ( (!baseURL.endsWith("/")) && (!subURL.startsWith("/")) ) { - baseURL = baseURL + "/"; - } - - if ( baseURL.endsWith("/") && subURL.startsWith("/") ) { - baseURL = baseURL.substring(0, baseURL.length()-1); - } - - if (!subURL.endsWith("/")) { - subURL = subURL + "/"; - } - - String url = baseURL + subURL + instance; - return url; - } - - private String nodeToString(Node node) throws TransformerException { - StringWriter sw = new StringWriter(); - Transformer t = TransformerFactory.newInstance().newTransformer(); - t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); - t.transform(new DOMSource(node), new StreamResult(sw)); - return sw.toString(); - } + ResponseEntity response = getResourceModel(aaiClient, distId, resourceUrl); + return response.getStatusCode().equals(HttpStatus.OK); + } catch (HttpClientErrorException e) { + if(e.getStatusCode().equals(HttpStatus.NOT_FOUND)) { + return false; + } else { + throw e; + } + } + } + + private boolean createNewModel(AaiRestClient aaiClient, String distId, List completedArtifacts, + String resourceUrl) { + boolean success; + // Assume that the model does not exist and attempt the PUT + success = putXmlResource(aaiClient, distId, resourceUrl, getPayload()); + if (success) { + completedArtifacts.add(this); + + // Record state to remember that this is the first version of the model (just added). + firstVersionOfModel = true; + + logInfoMsg(getType() + " " + getUniqueIdentifier() + " successfully ingested."); + } else { + logModelUpdateFailure("Error creating model. Skipping ingestion."); + } + return success; + } + + private void logModelUpdateFailure(String message) { + logErrorMsg(FAILURE_MSG_PREFIX + getType() + " " + getUniqueIdentifier() + " " + message + ROLLBACK_MSG_SUFFIX); + } + + private boolean updateExistingModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, + List completedArtifacts) { + boolean success; + logInfoMsg(getType() + " " + getModelInvariantId() + " already exists. Skipping ingestion."); + success = pushModelVersion(aaiClient, config, distId, completedArtifacts); + return success; + } + + /** + * @param aaiClient + * @param config + * @param distId + * @param completedArtifacts + * @return + */ + private boolean pushModelVersion(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, + List completedArtifacts) { + if (xmlResourceCanBeFetched(aaiClient, distId, getModelVerUrl(config))) { + logInfoMsg(getType() + " " + getUniqueIdentifier() + " already exists. Skipping ingestion."); + return true; + } + + // Load the model version + boolean success = true; + success = putXmlResource(aaiClient, distId, getModelVerUrl(config), getModelVer()); + if (success) { + completedArtifacts.add(this); + logInfoMsg(getType() + " " + getUniqueIdentifier() + " successfully ingested."); + } else { + logModelUpdateFailure("Error pushing model"); + } + + return success; + } + + + @Override + public void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) { + // Gizmo is resilient and doesn't require a rollback. A redistribution will work fine even if + // the model is partially loaded. + if (config.useGizmo()) { + return; + } + + String url = getModelVerUrl(config); + if (firstVersionOfModel) { + // If this was the first version of the model which was added, we want to remove the entire + // model rather than just the version. + url = getModelUrl(config); + } + + // Best effort to delete. Nothing we can do in the event this fails. + aaiClient.getAndDeleteResource(url, distId); + } + + private String getModelUrl(ModelLoaderConfig config) { + String baseURL = config.getAaiBaseUrl().trim(); + String subURL = config.getAaiModelUrl(getModelNamespaceVersion()).trim(); + String instance = getModelInvariantId(); + + if (!baseURL.endsWith("/") && !subURL.startsWith("/")) { + baseURL = baseURL + "/"; + } + + if (baseURL.endsWith("/") && subURL.startsWith("/")) { + baseURL = baseURL.substring(0, baseURL.length() - 1); + } + + if (!subURL.endsWith("/")) { + subURL = subURL + "/"; + } + + return baseURL + subURL + instance; + } + + private String getModelVerUrl(ModelLoaderConfig config) { + String baseURL = config.getAaiBaseUrl().trim(); + String subURL = config.getAaiModelUrl(getModelNamespaceVersion()).trim() + getModelInvariantId() + + AAI_MODEL_VER_SUB_URL; + String instance = getModelVerId(); + + if (!baseURL.endsWith("/") && !subURL.startsWith("/")) { + baseURL = baseURL + "/"; + } + + if (baseURL.endsWith("/") && subURL.startsWith("/")) { + baseURL = baseURL.substring(0, baseURL.length() - 1); + } + + if (!subURL.endsWith("/")) { + subURL = subURL + "/"; + } + + return baseURL + subURL + instance; + } }