diff options
author | 2017-06-27 21:08:37 +0300 | |
---|---|---|
committer | 2017-06-27 21:10:57 +0300 | |
commit | fe17f093d5c61207949eebef95b83baf5139be50 (patch) | |
tree | 776be9df8cd4cf8e5a69bde1f0ed741e78ab08fb /src/main/java/org/openecomp | |
parent | faa407b9cd0430c1e6b8b668392fe5e33f792432 (diff) |
Allow handling of legact model artifacts
Change-Id: I3d4c5e51140d4d05b3fd871d58c2590421c0e9db
Signed-off-by: Blimkie, Steven (sb787e) <steven.blimkie@amdocs.com>
Diffstat (limited to 'src/main/java/org/openecomp')
16 files changed, 1842 insertions, 1219 deletions
diff --git a/src/main/java/org/openecomp/modelloader/entity/Artifact.java b/src/main/java/org/openecomp/modelloader/entity/Artifact.java index 30709ae..88c75eb 100644 --- a/src/main/java/org/openecomp/modelloader/entity/Artifact.java +++ b/src/main/java/org/openecomp/modelloader/entity/Artifact.java @@ -1,46 +1,46 @@ -/**
- * ============LICENSE_START=======================================================
- * Model Loader
- * ================================================================================
- * Copyright © 2017 AT&T Intellectual Property.
- * Copyright © 2017 Amdocs
- * All rights reserved.
- * ================================================================================
- * 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=========================================================
- *
- * ECOMP and OpenECOMP are trademarks
- * and service marks of AT&T Intellectual Property.
- */
-package org.openecomp.modelloader.entity;
-
-public abstract class Artifact {
-
- private String payload;
- private ArtifactType type;
-
- public ArtifactType getType() {
- return type;
- }
-
- public void setType(ArtifactType type) {
- this.type = type;
- }
-
- public String getPayload() {
- return payload;
- }
-
- public void setPayload(String payload) {
- this.payload = payload;
- }
-
-}
+/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.entity; + +public abstract class Artifact { + + private String payload; + private ArtifactType type; + + public Artifact(ArtifactType type) { + this.type = type; + } + + public ArtifactType getType() { + return type; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + +} diff --git a/src/main/java/org/openecomp/modelloader/entity/ArtifactType.java b/src/main/java/org/openecomp/modelloader/entity/ArtifactType.java index ae556bc..381733b 100644 --- a/src/main/java/org/openecomp/modelloader/entity/ArtifactType.java +++ b/src/main/java/org/openecomp/modelloader/entity/ArtifactType.java @@ -1,27 +1,30 @@ -/**
- * ============LICENSE_START=======================================================
- * Model Loader
- * ================================================================================
- * Copyright © 2017 AT&T Intellectual Property.
- * Copyright © 2017 Amdocs
- * All rights reserved.
- * ================================================================================
- * 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=========================================================
- *
- * ECOMP and OpenECOMP are trademarks
- * and service marks of AT&T Intellectual Property.
- */
-package org.openecomp.modelloader.entity;
-
-public enum ArtifactType {
- MODEL, NAMED_QUERY, VNF_CATALOG;
-}
+/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.entity; + +public enum ArtifactType { + MODEL, + MODEL_V8, + NAMED_QUERY, + VNF_CATALOG; +} diff --git a/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifact.java b/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifact.java index a15ed3c..9b4c587 100644 --- a/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifact.java +++ b/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifact.java @@ -1,33 +1,33 @@ -/**
- * ============LICENSE_START=======================================================
- * Model Loader
- * ================================================================================
- * Copyright © 2017 AT&T Intellectual Property.
- * Copyright © 2017 Amdocs
- * All rights reserved.
- * ================================================================================
- * 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=========================================================
- *
- * ECOMP and OpenECOMP are trademarks
- * and service marks of AT&T Intellectual Property.
- */
-package org.openecomp.modelloader.entity.catalog;
-
-import org.openecomp.modelloader.entity.Artifact;
-import org.openecomp.modelloader.entity.ArtifactType;
-
-public class VnfCatalogArtifact extends Artifact {
- public VnfCatalogArtifact(String payload) {
- setPayload(payload);
- setType(ArtifactType.VNF_CATALOG);
- }
-}
+/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.entity.catalog; + +import org.openecomp.modelloader.entity.Artifact; +import org.openecomp.modelloader.entity.ArtifactType; + +public class VnfCatalogArtifact extends Artifact { + public VnfCatalogArtifact(String payload) { + super(ArtifactType.VNF_CATALOG); + setPayload(payload); + } +} diff --git a/src/main/java/org/openecomp/modelloader/entity/model/AbstractModelArtifact.java b/src/main/java/org/openecomp/modelloader/entity/model/AbstractModelArtifact.java new file mode 100644 index 0000000..2add53e --- /dev/null +++ b/src/main/java/org/openecomp/modelloader/entity/model/AbstractModelArtifact.java @@ -0,0 +1,85 @@ +/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.entity.model; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.openecomp.modelloader.config.ModelLoaderConfig; +import org.openecomp.modelloader.entity.Artifact; +import org.openecomp.modelloader.entity.ArtifactType; +import org.openecomp.modelloader.restclient.AaiRestClient; + +public abstract class AbstractModelArtifact extends Artifact { + + private String modelNamespace; + private String modelNamespaceVersion; + private Set<String> referencedModelIds = new HashSet<String>(); + + public AbstractModelArtifact(ArtifactType type) { + super(type); + } + + public Set<String> getDependentModelIds() { + return referencedModelIds; + } + + public void addDependentModelId(String dependentModelId) { + this.referencedModelIds.add(dependentModelId); + } + + public String getModelNamespace() { + return modelNamespace; + } + + public void setModelNamespace(String modelNamespace) { + this.modelNamespace = modelNamespace; + + // Get the version from the namespace (in format 'http://org.openecomp.aai.inventory/v9') + String[] parts = modelNamespace.split("/"); + modelNamespaceVersion = parts[parts.length-1].trim(); + } + + public String getModelNamespaceVersion() { + return modelNamespaceVersion; + } + + public abstract String getUniqueIdentifier(); + + public abstract boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List<AbstractModelArtifact> addedModels); + + public abstract void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId); + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("\nType=" + getType().toString() +"\nId=" + getUniqueIdentifier() +"\nVersion=" + getModelNamespaceVersion() + "\nDependant models: "); + for (String dep : referencedModelIds) { + sb.append(dep + " "); + } + + return sb.toString(); + } + + +} diff --git a/src/main/java/org/openecomp/modelloader/entity/model/IModelParser.java b/src/main/java/org/openecomp/modelloader/entity/model/IModelParser.java new file mode 100644 index 0000000..3a31756 --- /dev/null +++ b/src/main/java/org/openecomp/modelloader/entity/model/IModelParser.java @@ -0,0 +1,31 @@ +/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.entity.model; + +import java.util.List; + +import org.openecomp.modelloader.entity.Artifact; + +public interface IModelParser { + public List<Artifact> parse(byte[] artifactPayload, String artifactName); +} diff --git a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifact.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifact.java index 432e442..f316e28 100644 --- a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifact.java +++ b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifact.java @@ -22,94 +22,44 @@ */ package org.openecomp.modelloader.entity.model; -import org.openecomp.modelloader.entity.Artifact; -import org.w3c.dom.Node; +import java.io.StringWriter; +import java.util.List; -import java.util.HashSet; -import java.util.Set; - -public class ModelArtifact extends Artifact { - - String modelVerId; - String modelInvariantId; - String nameVersionId; - String modelVerModelVersionId; - String modelModelInvariantId; - String modelNamespace; - String modelNamespaceVersion; - Set<String> referencedModelIds = new HashSet<String>(); - Node modelVer; - boolean isV9Artifact = true; - - public boolean isV9Artifact() { - return isV9Artifact; - } - - public void setV9Artifact(boolean isV9Artifact) { - this.isV9Artifact = isV9Artifact; - } +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; - public String getModelVerModelVersionId() { - return modelVerModelVersionId; - } - - public void setModelVerModelVersionId(String modelVerModelVersionId) { - this.modelVerModelVersionId = modelVerModelVersionId; - } - - public String getModelModelInvariantId() { - return modelModelInvariantId; - } - - public void setModelModelInvariantId(String modelModelInvariantId) { - this.modelModelInvariantId = modelModelInvariantId; - } - - public String getNameVersionId() { - return nameVersionId; - } - - public void setNameVersionId(String nameVersionId) { - this.nameVersionId = nameVersionId; - } - - public String getModelNamespace() { - return modelNamespace; - } - - public void setModelNamespace(String modelNamespace) { - this.modelNamespace = modelNamespace; - - // Get the version from the namespace (in format 'http://org.openecomp.aai.inventory/v9') - String[] parts = modelNamespace.split("/"); - modelNamespaceVersion = parts[parts.length-1].trim(); - } - - public String getModelNamespaceVersion() { - return modelNamespaceVersion; - } +import org.openecomp.cl.api.Logger; +import org.openecomp.cl.eelf.LoggerFactory; +import org.openecomp.modelloader.config.ModelLoaderConfig; +import org.openecomp.modelloader.entity.ArtifactType; +import org.openecomp.modelloader.restclient.AaiRestClient; +import org.openecomp.modelloader.service.ModelLoaderMsgs; +import org.w3c.dom.Node; - public Set<String> getDependentModelIds() { - return referencedModelIds; - } +import com.sun.jersey.api.client.ClientResponse; - public void addDependentModelId(String dependentModelId) { - this.referencedModelIds.add(dependentModelId); - } +public class ModelArtifact extends AbstractModelArtifact { - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("ModelInvariantId=" + modelInvariantId + "(" + getType().toString() + ") ==> "); - for (String dep : referencedModelIds) { - sb.append(dep + " "); - } + 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; - return sb.toString(); + public ModelArtifact() { + super(ArtifactType.MODEL); } public String getModelVerId() { - return modelVerId; + return modelVerId; } public void setModelVerId(String modelVerId) { @@ -131,11 +81,130 @@ public class ModelArtifact extends Artifact { public void setModelVer(Node modelVer) { this.modelVer = modelVer; } - - public String getModelModelVerCombinedKey() { - if ( (getModelInvariantId() == null) && (getModelVerId() == null) ) { - return getNameVersionId(); - } - return getModelInvariantId() + "|" + getModelVerId(); - } + + @Override + public String getUniqueIdentifier() { + return getModelInvariantId() + "|" + getModelVerId(); + } + + @Override + public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List<AbstractModelArtifact> 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; + + 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(); + } } diff --git a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactHandler.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactHandler.java index 19b69cf..13ef1b1 100644 --- a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactHandler.java +++ b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactHandler.java @@ -22,38 +22,22 @@ */ package org.openecomp.modelloader.entity.model; -import com.sun.jersey.api.client.ClientResponse; - import org.openecomp.cl.api.Logger; import org.openecomp.cl.eelf.LoggerFactory; import org.openecomp.modelloader.config.ModelLoaderConfig; import org.openecomp.modelloader.entity.Artifact; import org.openecomp.modelloader.entity.ArtifactHandler; -import org.openecomp.modelloader.entity.ArtifactType; import org.openecomp.modelloader.restclient.AaiRestClient; import org.openecomp.modelloader.service.ModelLoaderMsgs; -import org.w3c.dom.Node; - -import java.io.StringWriter; import java.util.ArrayList; 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; - public class ModelArtifactHandler extends ArtifactHandler { - private static final String AAI_MODEL_VER = "/model-vers/model-ver"; - private static Logger logger = LoggerFactory.getInstance().getLogger(ArtifactHandler.class.getName()); - - + private static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifactHandler.class.getName()); + public ModelArtifactHandler(ModelLoaderConfig config) { super(config); } @@ -61,166 +45,34 @@ public class ModelArtifactHandler extends ArtifactHandler { @Override public boolean pushArtifacts(List<Artifact> artifacts, String distributionID) { ModelSorter modelSorter = new ModelSorter(); - List<Artifact> sortedModelArtifacts = modelSorter.sort(artifacts); - + List<Artifact> sortedModelArtifacts; + try { + sortedModelArtifacts = modelSorter.sort(artifacts); + } + catch (RuntimeException ex) { + logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Unable to resolve models: " + ex.getMessage()); + return false; + } + // Push the ordered list of model artifacts to A&AI. If one fails, we need to roll back // the changes. - List<ModelArtifact> completedModels = new ArrayList<ModelArtifact>(); + List<AbstractModelArtifact> completedModels = new ArrayList<AbstractModelArtifact>(); AaiRestClient aaiClient = new AaiRestClient(config); for (Artifact art : sortedModelArtifacts) { - ModelArtifact model = (ModelArtifact)art; - - boolean version = model.isV9Artifact(); - //Non - V9 version for models - if(version == false){ - ClientResponse getResponse = aaiClient.getResource(getModelVerURL(model), distributionID, AaiRestClient.MimeType.XML); - if ( (getResponse == null) || (getResponse.getStatus() != Response.Status.OK.getStatusCode()) ) { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, " Artifact format not valid for " + - model.getType().toString() + "- model-invariant-id[model-id]: " + - model.getModelInvariantId() + " and model-version-id[model-name-version-id]: "+ - model.getModelVerId()+ " . Rolling back distribution."); - return false; + AbstractModelArtifact model = (AbstractModelArtifact)art; + if (model.push(aaiClient, config, distributionID, completedModels) != true) { + for (AbstractModelArtifact modelToDelete : completedModels) { + modelToDelete.rollbackModel(aaiClient, config, distributionID); } - else{ - completedModels.add(model); - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, model.getType().toString() + - " " + model.getModelInvariantId() + " successfully ingested."); - } - } - else - { - ClientResponse getResponse = aaiClient.getResource(getURL(model), distributionID, 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(getURL(model), model.getPayload(), distributionID, AaiRestClient.MimeType.XML); - if ( (putResponse != null) && (putResponse.getStatus() == Response.Status.CREATED.getStatusCode()) ) { - completedModels.add(model); - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, model.getType().toString() + - " " + model.getModelInvariantId() + " successfully ingested."); - } - else { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Ingestion failed for " + - model.getType().toString() + " " + model.getModelInvariantId() + ". Rolling back distribution."); - for (ModelArtifact modelToDelete : completedModels) { - // Best effort to delete. Nothing we can do in the event this fails. - aaiClient.getAndDeleteResource(getURL(modelToDelete), distributionID); - } - - return false; - } - } - else { - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, model.getType().toString() + " " + model.getModelInvariantId() + - " already exists. Skipping ingestion."); - getResponse = aaiClient.getResource(getModelVerURL(model), distributionID, 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; - - try { - putResponse = aaiClient.putResource(getModelVerURL(model), nodeToString(model.getModelVer()), distributionID, AaiRestClient.MimeType.XML); - } catch (TransformerException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - if ( (putResponse != null) && (putResponse.getStatus() == Response.Status.CREATED.getStatusCode()) ) { - completedModels.add(model); - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, model.getType().toString() + " " + - model.getNameVersionId() + " successfully ingested."); - } - else { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Ingestion failed for " + - model.getType().toString() + " " + model.getNameVersionId() + ". Rolling back distribution."); - - for (ModelArtifact modelToDelete : completedModels) { - // Best effort to delete. Nothing we can do in the event this fails. - aaiClient.getAndDeleteResource(getModelVerURL(modelToDelete), distributionID); - } - - return false; - } - } - else { - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, model.getType().toString() + " " + - model.getModelInvariantId() + " already exists. Skipping ingestion."); - } - } + return false; } } return true; } - - 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)); - System.out.println(sw.toString()); - return sw.toString(); - } - - private String getURL(ModelArtifact model) { - String baseURL = config.getAaiBaseUrl().trim(); - String subURL = null; - String instance = null; - if (model.getType().equals(ArtifactType.MODEL)) { - subURL = config.getAaiModelUrl(model.getModelNamespaceVersion()).trim(); - instance = model.getModelInvariantId(); - } - else { - subURL = config.getAaiNamedQueryUrl(model.getModelNamespaceVersion()).trim(); - instance = model.getNameVersionId(); - } - - 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(ModelArtifact model) { - String baseURL = config.getAaiBaseUrl().trim(); - String subURL = null; - String instance = null; - if (model.getType().equals(ArtifactType.MODEL)) { - subURL = config.getAaiModelUrl(model.getModelNamespaceVersion()).trim() + model.getModelInvariantId() + AAI_MODEL_VER; - instance = model.getModelVerId(); - } - else { - subURL = config.getAaiNamedQueryUrl(model.getModelNamespaceVersion()).trim(); - instance = model.getNameVersionId(); - } - - 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; - } - // This method is used for the test REST interface to load models without an ASDC public void loadModelTest(byte[] payload) { List<Artifact> modelArtifacts = new ArrayList<Artifact>(); diff --git a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactParser.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactParser.java index 1bd77c8..d81539c 100644 --- a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactParser.java +++ b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactParser.java @@ -25,9 +25,7 @@ package org.openecomp.modelloader.entity.model; import org.openecomp.cl.api.Logger; import org.openecomp.cl.eelf.LoggerFactory; import org.openecomp.modelloader.entity.Artifact; -import org.openecomp.modelloader.entity.ArtifactType; import org.openecomp.modelloader.service.ModelLoaderMsgs; -import org.openecomp.modelloader.util.JsonXmlConverter; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -36,32 +34,20 @@ import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import java.io.StringReader; -import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; -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; -public class ModelArtifactParser { +public class ModelArtifactParser implements IModelParser { - private static String MODELS_ELEMENT = "models"; - private static String MODEL_ELEMENT = "model"; - private static String NAMED_QUERIES_ELEMENT = "named-queries"; - private static String NAMED_QUERY_ELEMENT = "named-query"; - private static String MODEL_NAME_VERSION_ID = "model-name-version-id"; private static String MODEL_VER = "model-ver"; private static String MODEL_VERSION_ID = "model-version-id"; private static String MODEL_INVARIANT_ID = "model-invariant-id"; - private static String NAMED_QUERY_VERSION_ID = "named-query-uuid"; + private static String RELATIONSHIP = "relationship"; private static String RELATIONSHIP_DATA = "relationship-data"; private static String RELATIONSHIP_KEY = "relationship-key"; private static String RELATIONSHIP_VALUE = "relationship-value"; @@ -75,54 +61,22 @@ public class ModelArtifactParser { List<Artifact> modelList = new ArrayList<Artifact>(); try { - // Artifact could be JSON or XML - if (JsonXmlConverter.isValidJson(payload)) { - payload = JsonXmlConverter.convertJsonToXml(payload); - } - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); InputSource is = new InputSource(new StringReader(payload)); Document doc = builder.parse(is); - if ( (doc.getDocumentElement().getNodeName().equalsIgnoreCase(MODEL_ELEMENT)) || - (doc.getDocumentElement().getNodeName().equalsIgnoreCase(NAMED_QUERY_ELEMENT)) ) { - - ModelArtifact model = parseModel(doc.getDocumentElement(), payload); + ModelArtifact model = parseModel(doc.getDocumentElement(), payload); - if (model != null) { - if ( ArtifactType.MODEL.equals(model.getType())) { - logger.info( ModelLoaderMsgs.DISTRIBUTION_EVENT, "Model parsed =====>>>> " - + "Model-invariant-Id: "+ model.getModelInvariantId() - + " Model-Version-Id: "+ model.getModelVerId()); - } - modelList.add(model); - } - else { - logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse artifact " + artifactName); - return null; - } + if (model != null) { + logger.info( ModelLoaderMsgs.DISTRIBUTION_EVENT, "Model parsed =====>>>> " + + "Model-invariant-Id: "+ model.getModelInvariantId() + + " Model-Version-Id: "+ model.getModelVerId()); + modelList.add(model); } - else if ( (doc.getDocumentElement().getNodeName().equalsIgnoreCase(MODELS_ELEMENT)) || - (doc.getDocumentElement().getNodeName().equalsIgnoreCase(NAMED_QUERIES_ELEMENT)) ) { - // The complete set of models/named-queries were contained in this artifact - NodeList nodeList = doc.getDocumentElement().getChildNodes(); - for (int i = 0; i < nodeList.getLength(); i++) { - Node childNode = nodeList.item(i); - if ( (childNode.getNodeName().equalsIgnoreCase(MODEL_ELEMENT)) || - (childNode.getNodeName().equalsIgnoreCase(NAMED_QUERY_ELEMENT)) ) { - String modelPayload = nodeToString(childNode); - ModelArtifact model = parseModel(childNode, modelPayload); - if (model != null) { - modelList.add(model); - } - else { - logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse artifact " + artifactName); - modelList.clear(); - break; - } - } - } + else { + logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse artifact " + artifactName); + return null; } } catch (Exception ex) { @@ -132,28 +86,16 @@ public class ModelArtifactParser { return modelList; } - private void printDetails(Node modelVer) throws TransformerException { - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, nodeToString(modelVer)); - } - private ModelArtifact parseModel(Node modelNode, String payload) { ModelArtifact model = new ModelArtifact(); model.setPayload(payload); - if (modelNode.getNodeName().equalsIgnoreCase(MODEL_ELEMENT)) { - //compare with Model-ver - model.setType(ArtifactType.MODEL); - } - else { - model.setType(ArtifactType.NAMED_QUERY); - } - Element e = (Element)modelNode; model.setModelNamespace(e.getAttribute("xmlns")); parseNode(modelNode, model); - if (model.getModelInvariantId() == null && model.getNameVersionId() == null) { + if ( (model.getModelInvariantId() == null) || (model.getModelVerId() == null) ){ return null; } @@ -161,36 +103,19 @@ public class ModelArtifactParser { } private void parseNode(Node node, ModelArtifact model) { - - if(node.getNodeName().equalsIgnoreCase(MODEL_NAME_VERSION_ID)){ - model.setModelVerId(node.getTextContent().trim()); - model.setV9Artifact(false); - } - else if(node.getNodeName().equalsIgnoreCase("model-id")){ - model.setModelInvariantId(node.getTextContent().trim()); - model.setV9Artifact(false); - } - - else if (node.getNodeName().equalsIgnoreCase(MODEL_INVARIANT_ID)) { + if (node.getNodeName().equalsIgnoreCase(MODEL_INVARIANT_ID)) { model.setModelInvariantId(node.getTextContent().trim()); } else if (node.getNodeName().equalsIgnoreCase(MODEL_VERSION_ID)) { model.setModelVerId(node.getTextContent().trim()); - //Change to Model Invariant Id - } - else if (node.getNodeName().equalsIgnoreCase(NAMED_QUERY_VERSION_ID)) { - model.setNameVersionId(node.getTextContent().trim()); } - else if (node.getNodeName().equalsIgnoreCase(RELATIONSHIP_DATA)) { - parseRelationshipNode(node, model); - if(model.getModelModelInvariantId()!=null && model.getModelVerModelVersionId()!=null && !model.getModelModelInvariantId().isEmpty() && !model.getModelVerModelVersionId().isEmpty()){ - model.addDependentModelId(model.getModelModelInvariantId() + "|" + model.getModelVerModelVersionId()); - model.setModelModelInvariantId(""); - model.setModelVerModelVersionId(""); + else if (node.getNodeName().equalsIgnoreCase(RELATIONSHIP)) { + String dependentModelKey = parseRelationshipNode(node, model); + if (dependentModelKey != null) { + model.addDependentModelId(dependentModelKey); } } else { - if (node.getNodeName().equalsIgnoreCase(MODEL_VER)) { model.setModelVer(node); if ( (model.getModelNamespace() != null) && (!model.getModelNamespace().isEmpty()) ) { @@ -208,57 +133,62 @@ public class ModelArtifactParser { } } - private void parseRelationshipNode(Node node, ModelArtifact model) { - - //invariant-id comes before model-version-id .. create a list of values - String key = null; - String value = null; - String modelVersionIdKey=null; - String modelInvariantIdIdKey=null; - String modelVersionIdValue=null; - String modelInvariantIdIdValue=null; + private String parseRelationshipNode(Node node, ModelArtifact model) { + String currentKey = null; + String currentValue = null; + String modelVersionIdValue = null; + String modelInvariantIdValue = null; NodeList nodeList = node.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { Node childNode = nodeList.item(i); - - - if (childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_KEY)) { - key = childNode.getTextContent().trim(); - if(key.equalsIgnoreCase(MODEL_VER_ELEMENT_RELATIONSHIP_KEY)){ - modelVersionIdKey = key; - } - else if(key.equalsIgnoreCase(MODEL_ELEMENT_RELATIONSHIP_KEY)){ - modelInvariantIdIdKey = key; - } - } - else if (childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_VALUE)) { - value = childNode.getTextContent().trim(); - if(modelVersionIdKey!=null){ - modelVersionIdValue = value; - model.setModelVerModelVersionId(modelVersionIdValue); + + if (childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_DATA)) { + NodeList relDataChildList = childNode.getChildNodes(); + + for (int j = 0; j < relDataChildList.getLength(); j++) { + Node relDataChildNode = relDataChildList.item(j); + + if (relDataChildNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_KEY)) { + currentKey = relDataChildNode.getTextContent().trim(); + + if (currentValue != null) { + if (currentKey.equalsIgnoreCase(MODEL_VER_ELEMENT_RELATIONSHIP_KEY)) { + modelVersionIdValue = currentValue; + } + else if (currentKey.equalsIgnoreCase(MODEL_ELEMENT_RELATIONSHIP_KEY)) { + modelInvariantIdValue = currentValue; + } + + currentKey = null; + currentValue = null; + } + } + else if (relDataChildNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_VALUE)) { + currentValue = relDataChildNode.getTextContent().trim(); + + if (currentKey != null) { + if (currentKey.equalsIgnoreCase(MODEL_VER_ELEMENT_RELATIONSHIP_KEY)) { + modelVersionIdValue = currentValue; + } + else if (currentKey.equalsIgnoreCase(MODEL_ELEMENT_RELATIONSHIP_KEY)) { + modelInvariantIdValue = currentValue; + } + + currentKey = null; + currentValue = null; + } + } } - else if(modelInvariantIdIdKey!=null){ - modelInvariantIdIdValue = value; - model.setModelModelInvariantId(modelInvariantIdIdValue); - } - } } - - if ( (key != null) && (key.equalsIgnoreCase(MODEL_ELEMENT_RELATIONSHIP_KEY )) && - (model.isV9Artifact == false ||ArtifactType.NAMED_QUERY.equals(model.getType())) ) { - if (value != null) { - model.addDependentModelId(value); - } + + if ( (modelVersionIdValue != null) && (modelInvariantIdValue != null) ) { + return modelInvariantIdValue + "|" + modelVersionIdValue; } - } + + return null; - 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(); } + } diff --git a/src/main/java/org/openecomp/modelloader/entity/model/ModelParserFactory.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelParserFactory.java new file mode 100644 index 0000000..aa3283f --- /dev/null +++ b/src/main/java/org/openecomp/modelloader/entity/model/ModelParserFactory.java @@ -0,0 +1,87 @@ +/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.entity.model; + +import java.io.StringReader; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.openecomp.cl.api.Logger; +import org.openecomp.cl.eelf.LoggerFactory; +import org.openecomp.modelloader.service.ModelLoaderMsgs; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.InputSource; + +public class ModelParserFactory { + private static Logger logger = LoggerFactory.getInstance().getLogger(ModelParserFactory.class.getName()); + + private static String MODEL_ELEMENT = "model"; + private static String NAMED_QUERY_ELEMENT = "named-query"; + + public static IModelParser createModelParser(byte[] artifactPayload, String artifactName) { + Document doc = null; + + try { + String payload = new String(artifactPayload); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder; + builder = factory.newDocumentBuilder(); + InputSource is = new InputSource(new StringReader(payload)); + doc = builder.parse(is); + } catch (Exception e) { + logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse artifact " + artifactName); + return null; + } + + if (doc.getDocumentElement().getNodeName().equalsIgnoreCase(NAMED_QUERY_ELEMENT)) { + return new NamedQueryArtifactParser(); + } + + if (!doc.getDocumentElement().getNodeName().equalsIgnoreCase(MODEL_ELEMENT)) { + logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse artifact " + artifactName + + ": Invalid root element: " + doc.getDocumentElement().getNodeName()); + return null; + } + + Element e = doc.getDocumentElement(); + String ns = e.getAttribute("xmlns"); + String[] parts = ns.split("/"); + + if (parts.length < 1) { + logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse artifact " + artifactName + + ": Could not parse namespace version"); + return null; + } + + String modelNamespaceVersion = parts[parts.length-1].trim().replace("v", ""); + int version = Integer.parseInt(modelNamespaceVersion); + + if (version > 8) { + return new ModelArtifactParser(); + } + + return new ModelV8ArtifactParser(); + } +} diff --git a/src/main/java/org/openecomp/modelloader/entity/model/ModelSorter.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelSorter.java index 7f99414..274b18f 100644 --- a/src/main/java/org/openecomp/modelloader/entity/model/ModelSorter.java +++ b/src/main/java/org/openecomp/modelloader/entity/model/ModelSorter.java @@ -44,11 +44,11 @@ public class ModelSorter { * Wraps a Model object to form dependencies other Models using Edges. */ static class Node { - private final ModelArtifact model; + private final AbstractModelArtifact model; private final HashSet<Edge> inEdges; private final HashSet<Edge> outEdges; - public Node(ModelArtifact model) { + public Node(AbstractModelArtifact model) { this.model = model; inEdges = new HashSet<Edge>(); outEdges = new HashSet<Edge>(); @@ -63,36 +63,18 @@ public class ModelSorter { @Override public String toString() { - if (model.getModelInvariantId() == null) { - return model.getNameVersionId(); - } - - return model.getModelInvariantId(); + return model.getUniqueIdentifier(); } @Override public boolean equals(Object other) { - ModelArtifact otherModel = ((Node) other).model; - String modelId1 = this.model.getModelInvariantId(); - if (modelId1 == null) { - modelId1 = this.model.getNameVersionId(); - } - - String modelId2 = otherModel.getModelInvariantId(); - if (modelId2 == null) { - modelId2 = otherModel.getNameVersionId(); - } - - return modelId1.equals(modelId2); + AbstractModelArtifact otherModel = ((Node) other).model; + return this.model.getUniqueIdentifier().equals(otherModel.getUniqueIdentifier()); } @Override public int hashCode() { - if (this.model.getModelInvariantId() == null) { - return this.model.getNameVersionId().hashCode(); - } - - return this.model.getModelInvariantId().hashCode(); + return this.model.getUniqueIdentifier().hashCode(); } } @@ -150,24 +132,24 @@ public class ModelSorter { // load list of models into a map, so we can later replace referenceIds with // real Models - HashMap<String, ModelArtifact> versionIdToModelMap = new HashMap<String, ModelArtifact>(); + HashMap<String, AbstractModelArtifact> versionIdToModelMap = new HashMap<String, AbstractModelArtifact>(); for (Artifact art : models) { - ModelArtifact ma = (ModelArtifact) art; - versionIdToModelMap.put(ma.getModelModelVerCombinedKey(), ma); + AbstractModelArtifact ma = (AbstractModelArtifact) art; + versionIdToModelMap.put(ma.getUniqueIdentifier(), ma); } HashMap<String, Node> nodes = new HashMap<String, Node>(); // create a node for each model and its referenced models for (Artifact art : models) { - ModelArtifact model = (ModelArtifact) art; + AbstractModelArtifact model = (AbstractModelArtifact) art; // node might have been created by another model referencing it - Node node = nodes.get(model.getModelModelVerCombinedKey()); + Node node = nodes.get(model.getUniqueIdentifier()); if (null == node) { node = new Node(model); - nodes.put(model.getModelModelVerCombinedKey(), node); + nodes.put(model.getUniqueIdentifier(), node); } for (String referencedModelId : model.getDependentModelIds()) { @@ -176,7 +158,7 @@ public class ModelSorter { if (null == referencedNode) { // create node - ModelArtifact referencedModel = versionIdToModelMap.get(referencedModelId); + AbstractModelArtifact referencedModel = versionIdToModelMap.get(referencedModelId); if (referencedModel == null) { Log.debug("ignoring " + referencedModelId); continue; // referenced model not supplied, no need to sort it diff --git a/src/main/java/org/openecomp/modelloader/entity/model/ModelV8Artifact.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelV8Artifact.java new file mode 100644 index 0000000..847f880 --- /dev/null +++ b/src/main/java/org/openecomp/modelloader/entity/model/ModelV8Artifact.java @@ -0,0 +1,122 @@ +/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.entity.model; + +import java.util.List; + +import javax.ws.rs.core.Response; + +import org.openecomp.cl.api.Logger; +import org.openecomp.cl.eelf.LoggerFactory; +import org.openecomp.modelloader.config.ModelLoaderConfig; +import org.openecomp.modelloader.entity.Artifact; +import org.openecomp.modelloader.entity.ArtifactType; +import org.openecomp.modelloader.restclient.AaiRestClient; +import org.openecomp.modelloader.service.ModelLoaderMsgs; + +import com.sun.jersey.api.client.ClientResponse; + +public class ModelV8Artifact extends AbstractModelArtifact { + private static String AAI_CONVERSION_URL = "/aai/tools/modeltransform"; + + private static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifact.class.getName()); + + private String modelNameVersionId; + private ModelArtifact translatedModel; + + public ModelV8Artifact() { + super(ArtifactType.MODEL_V8); + } + + public String getModelNameVersionId() { + return modelNameVersionId; + } + + public void setModelNameVersionId(String modelNameVersionId) { + this.modelNameVersionId = modelNameVersionId; + } + + @Override + public String getUniqueIdentifier() { + return getModelNameVersionId(); + } + + @Override + public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List<AbstractModelArtifact> addedModels) { + // For a legacy model (version <= v8), we need to call out to an A&AI endpoint to convert to the proper format + ClientResponse response = aaiClient.postResource(getConversionUrl(config), constructTransformPayload(), distId, AaiRestClient.MimeType.XML); + if ( (response == null) || (response.getStatus() != Response.Status.OK.getStatusCode()) ) { + logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Ingestion failed for " + + getType().toString() + " " + getModelNameVersionId() + ". Unable to convert model. Rolling back distribution."); + return false; + } + + String translatedPayload = response.getEntity(String.class); + + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Translated artifact payload:\n" + translatedPayload); + + ModelArtifactParser parser = new ModelArtifactParser(); + + List<Artifact> parsedArtifacts = parser.parse(translatedPayload.getBytes(), "translated-payload"); + if (parsedArtifacts == null || parsedArtifacts.isEmpty()) { + return false; + } + + translatedModel = (ModelArtifact)parsedArtifacts.get(0); + return translatedModel.push(aaiClient, config, distId, addedModels); + } + + @Override + public void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) { + if (translatedModel != null) { + translatedModel.rollbackModel(aaiClient, config, distId); + } + } + + + private String constructTransformPayload() { + // A&AI requires that to transform a legacy model, we need to use the v8 namespace (even + // if the version < 8) + return getPayload().replaceFirst("aai.inventory/v.", "aai.inventory/v8"); + } + + private String getConversionUrl(ModelLoaderConfig config) { + String baseUrl = config.getAaiBaseUrl().trim(); + String subUrl = AAI_CONVERSION_URL; + + 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; + return url; + } +} diff --git a/src/main/java/org/openecomp/modelloader/entity/model/ModelV8ArtifactParser.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelV8ArtifactParser.java new file mode 100644 index 0000000..f5ecb2b --- /dev/null +++ b/src/main/java/org/openecomp/modelloader/entity/model/ModelV8ArtifactParser.java @@ -0,0 +1,136 @@ +/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.entity.model; + +import org.openecomp.cl.api.Logger; +import org.openecomp.cl.eelf.LoggerFactory; +import org.openecomp.modelloader.entity.Artifact; +import org.openecomp.modelloader.service.ModelLoaderMsgs; + +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; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + + +public class ModelV8ArtifactParser implements IModelParser { + + private static String MODEL_NAME_VERSION_ID = "model-name-version-id"; + private static String RELATIONSHIP_DATA = "relationship-data"; + private static String RELATIONSHIP_KEY = "relationship-key"; + private static String RELATIONSHIP_VALUE = "relationship-value"; + private static String MODEL_ELEMENT_RELATIONSHIP_KEY = "model.model-name-version-id"; + + + private static Logger logger = LoggerFactory.getInstance().getLogger(ModelV8ArtifactParser.class.getName()); + + public List<Artifact> parse(byte[] artifactPayload, String artifactName) { + String payload = new String(artifactPayload); + List<Artifact> modelList = new ArrayList<Artifact>(); + + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + InputSource is = new InputSource(new StringReader(payload)); + Document doc = builder.parse(is); + + ModelV8Artifact model = parseModel(doc.getDocumentElement(), payload); + + if (model != null) { + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Model parsed =====>>>> " + "Model-Named-Version-Id: "+ model.getModelNameVersionId()); + modelList.add(model); + } + else { + logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse legacy model artifact " + artifactName); + return null; + } + } + catch (Exception ex) { + logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse legacy model artifact " + artifactName + ": " + ex.getLocalizedMessage()); + } + + return modelList; + } + + private ModelV8Artifact parseModel(Node modelNode, String payload) { + ModelV8Artifact model = new ModelV8Artifact(); + model.setPayload(payload); + + Element e = (Element)modelNode; + model.setModelNamespace(e.getAttribute("xmlns")); + + parseNode(modelNode, model); + + if (model.getModelNameVersionId() == null) { + return null; + } + + return model; + } + + private void parseNode(Node node, ModelV8Artifact model) { + if (node.getNodeName().equalsIgnoreCase(MODEL_NAME_VERSION_ID)) { + model.setModelNameVersionId(node.getTextContent().trim()); + } + else if (node.getNodeName().equalsIgnoreCase(RELATIONSHIP_DATA)) { + parseRelationshipNode(node, model); + } + else { + NodeList nodeList = node.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node childNode = nodeList.item(i); + parseNode(childNode, model); + } + } + } + + private void parseRelationshipNode(Node node, ModelV8Artifact model) { + String key = null; + String value = null; + + NodeList nodeList = node.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node childNode = nodeList.item(i); + if (childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_KEY)) { + key = childNode.getTextContent().trim(); + } + else if (childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_VALUE)) { + value = childNode.getTextContent().trim(); + } + } + + if ( (key != null) && (key.equalsIgnoreCase(MODEL_ELEMENT_RELATIONSHIP_KEY )) ) { + if (value != null) { + model.addDependentModelId(value); + } + } + } +} diff --git a/src/main/java/org/openecomp/modelloader/entity/model/NamedQueryArtifact.java b/src/main/java/org/openecomp/modelloader/entity/model/NamedQueryArtifact.java new file mode 100644 index 0000000..1a4ceaa --- /dev/null +++ b/src/main/java/org/openecomp/modelloader/entity/model/NamedQueryArtifact.java @@ -0,0 +1,113 @@ +/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.entity.model; + +import java.util.List; + +import javax.ws.rs.core.Response; + +import org.openecomp.cl.api.Logger; +import org.openecomp.cl.eelf.LoggerFactory; +import org.openecomp.modelloader.config.ModelLoaderConfig; +import org.openecomp.modelloader.entity.ArtifactType; +import org.openecomp.modelloader.restclient.AaiRestClient; +import org.openecomp.modelloader.service.ModelLoaderMsgs; + +import com.sun.jersey.api.client.ClientResponse; + +public class NamedQueryArtifact extends AbstractModelArtifact { + + private Logger logger = LoggerFactory.getInstance().getLogger(NamedQueryArtifact.class.getName()); + + private String namedQueryUuid; + + public NamedQueryArtifact() { + super(ArtifactType.NAMED_QUERY); + } + + public String getNamedQueryUuid() { + return namedQueryUuid; + } + + public void setNamedQueryUuid(String namedQueryUuid) { + this.namedQueryUuid = namedQueryUuid; + } + + @Override + public String getUniqueIdentifier() { + return getNamedQueryUuid(); + } + + @Override + public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List<AbstractModelArtifact> addedModels) { + ClientResponse getResponse = aaiClient.getResource(getNamedQueryUrl(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(getNamedQueryUrl(config), getPayload(), distId, AaiRestClient.MimeType.XML); + 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) { + // Best effort to delete. Nothing we can do in the event this fails. + aaiClient.getAndDeleteResource(getNamedQueryUrl(config), distId); + } + + private String getNamedQueryUrl(ModelLoaderConfig config) { + String baseURL = config.getAaiBaseUrl().trim(); + String subURL = null; + String instance = null; + + subURL = config.getAaiNamedQueryUrl(getModelNamespaceVersion()).trim(); + instance = this.getNamedQueryUuid(); + + 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; + } +} diff --git a/src/main/java/org/openecomp/modelloader/entity/model/NamedQueryArtifactParser.java b/src/main/java/org/openecomp/modelloader/entity/model/NamedQueryArtifactParser.java new file mode 100644 index 0000000..3643f18 --- /dev/null +++ b/src/main/java/org/openecomp/modelloader/entity/model/NamedQueryArtifactParser.java @@ -0,0 +1,136 @@ +/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.entity.model; + +import org.openecomp.cl.api.Logger; +import org.openecomp.cl.eelf.LoggerFactory; +import org.openecomp.modelloader.entity.Artifact; +import org.openecomp.modelloader.service.ModelLoaderMsgs; + +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; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.List; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + + +public class NamedQueryArtifactParser implements IModelParser { + + private static String NAMED_QUERY_VERSION_ID = "named-query-uuid"; + private static String RELATIONSHIP_DATA = "relationship-data"; + private static String RELATIONSHIP_KEY = "relationship-key"; + private static String RELATIONSHIP_VALUE = "relationship-value"; + private static String MODEL_ELEMENT_RELATIONSHIP_KEY = "model.model-invariant-id"; + + + private static Logger logger = LoggerFactory.getInstance().getLogger(NamedQueryArtifactParser.class.getName()); + + public List<Artifact> parse(byte[] artifactPayload, String artifactName) { + String payload = new String(artifactPayload); + List<Artifact> modelList = new ArrayList<Artifact>(); + + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + InputSource is = new InputSource(new StringReader(payload)); + Document doc = builder.parse(is); + + NamedQueryArtifact model = parseModel(doc.getDocumentElement(), payload); + + if (model != null) { + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, "Named-Query parsed =====>>>> " + "Named-Query-UUID: "+ model.getNamedQueryUuid()); + modelList.add(model); + } + else { + logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse named-query artifact " + artifactName); + return null; + } + } + catch (Exception ex) { + logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse named-query artifact " + artifactName + ": " + ex.getLocalizedMessage()); + } + + return modelList; + } + + private NamedQueryArtifact parseModel(Node modelNode, String payload) { + NamedQueryArtifact model = new NamedQueryArtifact(); + model.setPayload(payload); + + Element e = (Element)modelNode; + model.setModelNamespace(e.getAttribute("xmlns")); + + parseNode(modelNode, model); + + if (model.getNamedQueryUuid() == null) { + return null; + } + + return model; + } + + private void parseNode(Node node, NamedQueryArtifact model) { + if (node.getNodeName().equalsIgnoreCase(NAMED_QUERY_VERSION_ID)) { + model.setNamedQueryUuid(node.getTextContent().trim()); + } + else if (node.getNodeName().equalsIgnoreCase(RELATIONSHIP_DATA)) { + parseRelationshipNode(node, model); + } + else { + NodeList nodeList = node.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node childNode = nodeList.item(i); + parseNode(childNode, model); + } + } + } + + private void parseRelationshipNode(Node node, NamedQueryArtifact model) { + String key = null; + String value = null; + + NodeList nodeList = node.getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node childNode = nodeList.item(i); + if (childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_KEY)) { + key = childNode.getTextContent().trim(); + } + else if (childNode.getNodeName().equalsIgnoreCase(RELATIONSHIP_VALUE)) { + value = childNode.getTextContent().trim(); + } + } + + if ( (key != null) && (key.equalsIgnoreCase(MODEL_ELEMENT_RELATIONSHIP_KEY )) ) { + if (value != null) { + model.addDependentModelId(value); + } + } + } +} diff --git a/src/main/java/org/openecomp/modelloader/notification/EventCallback.java b/src/main/java/org/openecomp/modelloader/notification/EventCallback.java index 8634741..059964e 100644 --- a/src/main/java/org/openecomp/modelloader/notification/EventCallback.java +++ b/src/main/java/org/openecomp/modelloader/notification/EventCallback.java @@ -1,294 +1,293 @@ -/**
- * ============LICENSE_START=======================================================
- * Model Loader
- * ================================================================================
- * Copyright © 2017 AT&T Intellectual Property.
- * Copyright © 2017 Amdocs
- * All rights reserved.
- * ================================================================================
- * 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=========================================================
- *
- * ECOMP and OpenECOMP are trademarks
- * and service marks of AT&T Intellectual Property.
- */
-package org.openecomp.modelloader.notification;
-
-import org.openecomp.sdc.api.IDistributionClient;
-import org.openecomp.sdc.api.consumer.IDistributionStatusMessage;
-import org.openecomp.sdc.api.consumer.INotificationCallback;
-import org.openecomp.sdc.api.notification.IArtifactInfo;
-import org.openecomp.sdc.api.notification.INotificationData;
-import org.openecomp.sdc.api.notification.IResourceInstance;
-import org.openecomp.sdc.api.results.IDistributionClientDownloadResult;
-import org.openecomp.sdc.api.results.IDistributionClientResult;
-import org.openecomp.sdc.utils.ArtifactTypeEnum;
-import org.openecomp.sdc.utils.DistributionActionResultEnum;
-import org.openecomp.sdc.utils.DistributionStatusEnum;
-
-import org.openecomp.cl.api.Logger;
-import org.openecomp.cl.eelf.LoggerFactory;
-import org.openecomp.cl.mdc.MdcContext;
-import org.openecomp.cl.mdc.MdcOverride;
-import org.openecomp.modelloader.config.ModelLoaderConfig;
-import org.openecomp.modelloader.entity.Artifact;
-import org.openecomp.modelloader.entity.catalog.VnfCatalogArtifact;
-import org.openecomp.modelloader.entity.catalog.VnfCatalogArtifactHandler;
-import org.openecomp.modelloader.entity.model.ModelArtifactHandler;
-import org.openecomp.modelloader.entity.model.ModelArtifactParser;
-import org.openecomp.modelloader.service.ModelLoaderMsgs;
-import org.slf4j.MDC;
-
-import java.text.SimpleDateFormat;
-import java.util.ArrayList;
-import java.util.List;
-
-public class EventCallback implements INotificationCallback {
-
- private IDistributionClient client;
- private ModelLoaderConfig config;
- private static Logger logger = LoggerFactory.getInstance()
- .getLogger(EventCallback.class.getName());
- private static Logger auditLogger = LoggerFactory.getInstance()
- .getAuditLogger(EventCallback.class.getName());
- private static Logger metricsLogger = LoggerFactory.getInstance()
- .getMetricsLogger(EventCallback.class.getName());
-
- private static SimpleDateFormat dateFormatter = new SimpleDateFormat(
- "yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
-
- public EventCallback(IDistributionClient client, ModelLoaderConfig config) {
- this.client = client;
- this.config = config;
- }
-
- @Override
- public void activateCallback(INotificationData data) {
- // Init MDC
- MdcContext.initialize(data.getDistributionID(), "ModelLoader", "", "Event-Bus", "");
-
- logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
- "Received distribution " + data.getDistributionID());
-
- boolean success = true;
- List<IArtifactInfo> artifacts = getArtifacts(data);
- List<Artifact> modelArtifacts = new ArrayList<Artifact>();
- List<Artifact> catalogArtifacts = new ArrayList<Artifact>();
- ModelArtifactParser modelArtParser = new ModelArtifactParser();
-
- for (IArtifactInfo artifact : artifacts) {
- // Grab the current time so we can measure the download time for the
- // metrics log
- long startTimeInMs = System.currentTimeMillis();
- MdcOverride override = new MdcOverride();
- override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
-
- // Download Artifact
- IDistributionClientDownloadResult downloadResult = client.download(artifact);
-
- // Generate metrics log
- metricsLogger.info(ModelLoaderMsgs.DOWNLOAD_COMPLETE, null, override,
- artifact.getArtifactName(), downloadResult.getDistributionActionResult().toString());
-
- if (downloadResult.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
- publishDownloadFailure(data, artifact, downloadResult.getDistributionMessageResult());
- success = false;
- break;
- }
-
- logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
- "Downloaded artifact: " + artifact.getArtifactName() + " Payload:\n" + new String(downloadResult.getArtifactPayload()));
-
- publishDownloadSuccess(data, artifact, downloadResult);
-
- if ((artifact.getArtifactType()
- .compareToIgnoreCase(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE.toString()) == 0)
- || (artifact.getArtifactType()
- .compareToIgnoreCase(ArtifactTypeEnum.MODEL_QUERY_SPEC.toString()) == 0)) {
- List<Artifact> parsedArtifacts = modelArtParser.parse(downloadResult.getArtifactPayload(), downloadResult.getArtifactName());
- if (parsedArtifacts != null && !parsedArtifacts.isEmpty()) {
- modelArtifacts.addAll(parsedArtifacts);
- } else {
- success = false;
- publishDeployFailure(data, artifact);
- break;
- }
- } else if (artifact.getArtifactType()
- .compareToIgnoreCase(ArtifactTypeEnum.VNF_CATALOG.toString()) == 0) {
- catalogArtifacts
- .add(new VnfCatalogArtifact(new String(downloadResult.getArtifactPayload())));
- }
- }
-
- String statusString = "SUCCESS";
- if (success) {
- ModelArtifactHandler modelHandler = new ModelArtifactHandler(config);
- boolean modelDeploySuccess = modelHandler.pushArtifacts(modelArtifacts,
- data.getDistributionID());
-
- VnfCatalogArtifactHandler catalogHandler = new VnfCatalogArtifactHandler(config);
- boolean catalogDeploySuccess = catalogHandler.pushArtifacts(catalogArtifacts,
- data.getDistributionID());
-
- for (IArtifactInfo artifact : artifacts) {
- if ((artifact.getArtifactType()
- .compareToIgnoreCase(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE.toString()) == 0)
- || (artifact.getArtifactType()
- .compareToIgnoreCase(ArtifactTypeEnum.MODEL_QUERY_SPEC.toString()) == 0)) {
- if (modelDeploySuccess) {
- publishDeploySuccess(data, artifact);
- } else {
- publishDeployFailure(data, artifact);
- statusString = "FAILURE";
- }
- } else if (artifact.getArtifactType()
- .compareToIgnoreCase(ArtifactTypeEnum.VNF_CATALOG.toString()) == 0) {
- if (catalogDeploySuccess) {
- publishDeploySuccess(data, artifact);
- } else {
- publishDeployFailure(data, artifact);
- statusString = "FAILURE";
- }
- }
- }
- } else {
- statusString = "FAILURE";
- }
-
- auditLogger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
- "Processed distribution " + data.getDistributionID() + " (" + statusString + ")");
- MDC.clear();
- }
-
- private List<IArtifactInfo> getArtifacts(INotificationData data) {
- List<IArtifactInfo> artifacts = new ArrayList<IArtifactInfo>();
- List<IResourceInstance> resources = data.getResources();
-
- if (data.getServiceArtifacts() != null) {
- artifacts.addAll(data.getServiceArtifacts());
- }
-
- if (resources != null) {
- for (IResourceInstance resource : resources) {
- if (resource.getArtifacts() != null) {
- artifacts.addAll(resource.getArtifacts());
- }
- }
- }
-
- return artifacts;
- }
-
- private void publishDownloadFailure(INotificationData data, IArtifactInfo artifact,
- String errorMessage) {
- // Grab the current time so we can measure the download time for the metrics
- // log
- long startTimeInMs = System.currentTimeMillis();
- MdcOverride override = new MdcOverride();
- override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
-
- IDistributionClientResult sendDownloadStatus = client.sendDownloadStatus(
- buildStatusMessage(client, data, artifact, DistributionStatusEnum.DOWNLOAD_ERROR));
- metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "download failure",
- artifact.getArtifactName(), sendDownloadStatus.getDistributionActionResult().toString());
-
- if (sendDownloadStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
- logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
- "Failed to publish download failure status: "
- + sendDownloadStatus.getDistributionMessageResult());
- }
-
- logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
- "Failed to download artifact " + artifact.getArtifactName() + ": " + errorMessage);
- }
-
- private void publishDownloadSuccess(INotificationData data, IArtifactInfo artifact,
- IDistributionClientDownloadResult downloadResult) {
- // Grab the current time so we can measure the download time for the metrics
- // log
- long startTimeInMs = System.currentTimeMillis();
- MdcOverride override = new MdcOverride();
- override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
-
- IDistributionClientResult sendDownloadStatus = client.sendDownloadStatus(
- buildStatusMessage(client, data, artifact, DistributionStatusEnum.DOWNLOAD_OK));
- metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "download success",
- artifact.getArtifactName(), sendDownloadStatus.getDistributionActionResult().toString());
-
- if (sendDownloadStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
- logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
- "Failed to publish download success status: "
- + sendDownloadStatus.getDistributionMessageResult());
- }
-
- if (logger.isDebugEnabled()) {
- StringBuilder sb = new StringBuilder();
- sb.append("Downloaded artifact:\n");
- sb.append("ArtInfo_Art_Name: " + artifact.getArtifactName());
- sb.append("\nArtInfo_Art_description: " + artifact.getArtifactDescription());
- sb.append("\nArtInfo_Art_CheckSum: " + artifact.getArtifactChecksum());
- sb.append("\nArtInfo_Art_Url: " + artifact.getArtifactURL());
- sb.append("\nArtInfo_Art_Type: " + artifact.getArtifactType());
- sb.append("\nArtInfo_Serv_description: " + data.getServiceDescription());
- sb.append("\nArtInfo_Serv_Name: " + data.getServiceName());
- sb.append("\nGet_serviceVersion: " + data.getServiceVersion());
- sb.append("\nGet_Service_UUID: " + data.getServiceUUID());
- sb.append("\nArtInfo_DistributionId: " + data.getDistributionID());
- logger.debug(sb.toString());
- }
- }
-
- private void publishDeployFailure(INotificationData data, IArtifactInfo artifact) {
- // Grab the current time so we can measure the download time for the metrics
- // log
- long startTimeInMs = System.currentTimeMillis();
- MdcOverride override = new MdcOverride();
- override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
-
- IDistributionClientResult sendStatus = client.sendDeploymentStatus(
- buildStatusMessage(client, data, artifact, DistributionStatusEnum.DEPLOY_ERROR));
- metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "deploy failure",
- artifact.getArtifactName(), sendStatus.getDistributionActionResult().toString());
-
- if (sendStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
- logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
- "Failed to publish deploy failure status: " + sendStatus.getDistributionMessageResult());
- }
- }
-
- private void publishDeploySuccess(INotificationData data, IArtifactInfo artifact) {
- // Grab the current time so we can measure the download time for the metrics
- // log
- long startTimeInMs = System.currentTimeMillis();
- MdcOverride override = new MdcOverride();
- override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
-
- IDistributionClientResult sendStatus = client.sendDownloadStatus(
- buildStatusMessage(client, data, artifact, DistributionStatusEnum.DEPLOY_OK));
- metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "deploy success",
- artifact.getArtifactName(), sendStatus.getDistributionActionResult().toString());
-
- if (sendStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) {
- logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
- "Failed to publish deploy success status: " + sendStatus.getDistributionMessageResult());
- }
- }
-
- private IDistributionStatusMessage buildStatusMessage(IDistributionClient client,
- INotificationData data, IArtifactInfo artifact, DistributionStatusEnum status) {
- IDistributionStatusMessage statusMessage = new DistributionStatusMsg(status,
- data.getDistributionID(), client.getConfiguration().getConsumerID(),
- artifact.getArtifactURL());
-
- return statusMessage;
- }
-
-}
+/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.notification; + +import org.openecomp.sdc.api.IDistributionClient; +import org.openecomp.sdc.api.consumer.IDistributionStatusMessage; +import org.openecomp.sdc.api.consumer.INotificationCallback; +import org.openecomp.sdc.api.notification.IArtifactInfo; +import org.openecomp.sdc.api.notification.INotificationData; +import org.openecomp.sdc.api.notification.IResourceInstance; +import org.openecomp.sdc.api.results.IDistributionClientDownloadResult; +import org.openecomp.sdc.api.results.IDistributionClientResult; +import org.openecomp.sdc.utils.ArtifactTypeEnum; +import org.openecomp.sdc.utils.DistributionActionResultEnum; +import org.openecomp.sdc.utils.DistributionStatusEnum; + +import org.openecomp.cl.api.Logger; +import org.openecomp.cl.eelf.LoggerFactory; +import org.openecomp.cl.mdc.MdcContext; +import org.openecomp.cl.mdc.MdcOverride; +import org.openecomp.modelloader.config.ModelLoaderConfig; +import org.openecomp.modelloader.entity.Artifact; +import org.openecomp.modelloader.entity.catalog.VnfCatalogArtifact; +import org.openecomp.modelloader.entity.catalog.VnfCatalogArtifactHandler; +import org.openecomp.modelloader.entity.model.IModelParser; +import org.openecomp.modelloader.entity.model.ModelArtifactHandler; +import org.openecomp.modelloader.entity.model.ModelParserFactory; +import org.openecomp.modelloader.service.ModelLoaderMsgs; +import org.slf4j.MDC; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.List; + +public class EventCallback implements INotificationCallback { + + private IDistributionClient client; + private ModelLoaderConfig config; + private static Logger logger = LoggerFactory.getInstance() + .getLogger(EventCallback.class.getName()); + private static Logger auditLogger = LoggerFactory.getInstance() + .getAuditLogger(EventCallback.class.getName()); + private static Logger metricsLogger = LoggerFactory.getInstance() + .getMetricsLogger(EventCallback.class.getName()); + + private static SimpleDateFormat dateFormatter = new SimpleDateFormat( + "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); + + public EventCallback(IDistributionClient client, ModelLoaderConfig config) { + this.client = client; + this.config = config; + } + + @Override + public void activateCallback(INotificationData data) { + // Init MDC + MdcContext.initialize(data.getDistributionID(), "ModelLoader", "", "Event-Bus", ""); + + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, + "Received distribution " + data.getDistributionID()); + + boolean success = true; + List<IArtifactInfo> artifacts = getArtifacts(data); + List<Artifact> modelArtifacts = new ArrayList<Artifact>(); + List<Artifact> catalogArtifacts = new ArrayList<Artifact>(); + + for (IArtifactInfo artifact : artifacts) { + // Grab the current time so we can measure the download time for the + // metrics log + long startTimeInMs = System.currentTimeMillis(); + MdcOverride override = new MdcOverride(); + override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs)); + + // Download Artifact + IDistributionClientDownloadResult downloadResult = client.download(artifact); + + // Generate metrics log + metricsLogger.info(ModelLoaderMsgs.DOWNLOAD_COMPLETE, null, override, + artifact.getArtifactName(), downloadResult.getDistributionActionResult().toString()); + + if (downloadResult.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) { + publishDownloadFailure(data, artifact, downloadResult.getDistributionMessageResult()); + success = false; + break; + } + + logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, + "Downloaded artifact: " + artifact.getArtifactName() + " Payload:\n" + new String(downloadResult.getArtifactPayload())); + + publishDownloadSuccess(data, artifact, downloadResult); + + if ((artifact.getArtifactType().compareToIgnoreCase(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE.toString()) == 0) + || (artifact.getArtifactType().compareToIgnoreCase(ArtifactTypeEnum.MODEL_QUERY_SPEC.toString()) == 0)) { + IModelParser parser = ModelParserFactory.createModelParser(downloadResult.getArtifactPayload(), downloadResult.getArtifactName()); + List<Artifact> parsedArtifacts = parser.parse(downloadResult.getArtifactPayload(), downloadResult.getArtifactName()); + if (parsedArtifacts != null && !parsedArtifacts.isEmpty()) { + modelArtifacts.addAll(parsedArtifacts); + } else { + success = false; + publishDeployFailure(data, artifact); + break; + } + } else if (artifact.getArtifactType() + .compareToIgnoreCase(ArtifactTypeEnum.VNF_CATALOG.toString()) == 0) { + catalogArtifacts + .add(new VnfCatalogArtifact(new String(downloadResult.getArtifactPayload()))); + } + } + + String statusString = "SUCCESS"; + if (success) { + ModelArtifactHandler modelHandler = new ModelArtifactHandler(config); + boolean modelDeploySuccess = modelHandler.pushArtifacts(modelArtifacts, + data.getDistributionID()); + + VnfCatalogArtifactHandler catalogHandler = new VnfCatalogArtifactHandler(config); + boolean catalogDeploySuccess = catalogHandler.pushArtifacts(catalogArtifacts, + data.getDistributionID()); + + for (IArtifactInfo artifact : artifacts) { + if ((artifact.getArtifactType() + .compareToIgnoreCase(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE.toString()) == 0) + || (artifact.getArtifactType() + .compareToIgnoreCase(ArtifactTypeEnum.MODEL_QUERY_SPEC.toString()) == 0)) { + if (modelDeploySuccess) { + publishDeploySuccess(data, artifact); + } else { + publishDeployFailure(data, artifact); + statusString = "FAILURE"; + } + } else if (artifact.getArtifactType() + .compareToIgnoreCase(ArtifactTypeEnum.VNF_CATALOG.toString()) == 0) { + if (catalogDeploySuccess) { + publishDeploySuccess(data, artifact); + } else { + publishDeployFailure(data, artifact); + statusString = "FAILURE"; + } + } + } + } else { + statusString = "FAILURE"; + } + + auditLogger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, + "Processed distribution " + data.getDistributionID() + " (" + statusString + ")"); + MDC.clear(); + } + + private List<IArtifactInfo> getArtifacts(INotificationData data) { + List<IArtifactInfo> artifacts = new ArrayList<IArtifactInfo>(); + List<IResourceInstance> resources = data.getResources(); + + if (data.getServiceArtifacts() != null) { + artifacts.addAll(data.getServiceArtifacts()); + } + + if (resources != null) { + for (IResourceInstance resource : resources) { + if (resource.getArtifacts() != null) { + artifacts.addAll(resource.getArtifacts()); + } + } + } + + return artifacts; + } + + private void publishDownloadFailure(INotificationData data, IArtifactInfo artifact, + String errorMessage) { + // Grab the current time so we can measure the download time for the metrics + // log + long startTimeInMs = System.currentTimeMillis(); + MdcOverride override = new MdcOverride(); + override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs)); + + IDistributionClientResult sendDownloadStatus = client.sendDownloadStatus( + buildStatusMessage(client, data, artifact, DistributionStatusEnum.DOWNLOAD_ERROR)); + metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "download failure", + artifact.getArtifactName(), sendDownloadStatus.getDistributionActionResult().toString()); + + if (sendDownloadStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) { + logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, + "Failed to publish download failure status: " + + sendDownloadStatus.getDistributionMessageResult()); + } + + logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, + "Failed to download artifact " + artifact.getArtifactName() + ": " + errorMessage); + } + + private void publishDownloadSuccess(INotificationData data, IArtifactInfo artifact, + IDistributionClientDownloadResult downloadResult) { + // Grab the current time so we can measure the download time for the metrics + // log + long startTimeInMs = System.currentTimeMillis(); + MdcOverride override = new MdcOverride(); + override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs)); + + IDistributionClientResult sendDownloadStatus = client.sendDownloadStatus( + buildStatusMessage(client, data, artifact, DistributionStatusEnum.DOWNLOAD_OK)); + metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "download success", + artifact.getArtifactName(), sendDownloadStatus.getDistributionActionResult().toString()); + + if (sendDownloadStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) { + logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, + "Failed to publish download success status: " + + sendDownloadStatus.getDistributionMessageResult()); + } + + if (logger.isDebugEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append("Downloaded artifact:\n"); + sb.append("ArtInfo_Art_Name: " + artifact.getArtifactName()); + sb.append("\nArtInfo_Art_description: " + artifact.getArtifactDescription()); + sb.append("\nArtInfo_Art_CheckSum: " + artifact.getArtifactChecksum()); + sb.append("\nArtInfo_Art_Url: " + artifact.getArtifactURL()); + sb.append("\nArtInfo_Art_Type: " + artifact.getArtifactType()); + sb.append("\nArtInfo_Serv_description: " + data.getServiceDescription()); + sb.append("\nArtInfo_Serv_Name: " + data.getServiceName()); + sb.append("\nGet_serviceVersion: " + data.getServiceVersion()); + sb.append("\nGet_Service_UUID: " + data.getServiceUUID()); + sb.append("\nArtInfo_DistributionId: " + data.getDistributionID()); + logger.debug(sb.toString()); + } + } + + private void publishDeployFailure(INotificationData data, IArtifactInfo artifact) { + // Grab the current time so we can measure the download time for the metrics + // log + long startTimeInMs = System.currentTimeMillis(); + MdcOverride override = new MdcOverride(); + override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs)); + + IDistributionClientResult sendStatus = client.sendDeploymentStatus( + buildStatusMessage(client, data, artifact, DistributionStatusEnum.DEPLOY_ERROR)); + metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "deploy failure", + artifact.getArtifactName(), sendStatus.getDistributionActionResult().toString()); + + if (sendStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) { + logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, + "Failed to publish deploy failure status: " + sendStatus.getDistributionMessageResult()); + } + } + + private void publishDeploySuccess(INotificationData data, IArtifactInfo artifact) { + // Grab the current time so we can measure the download time for the metrics + // log + long startTimeInMs = System.currentTimeMillis(); + MdcOverride override = new MdcOverride(); + override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs)); + + IDistributionClientResult sendStatus = client.sendDownloadStatus( + buildStatusMessage(client, data, artifact, DistributionStatusEnum.DEPLOY_OK)); + metricsLogger.info(ModelLoaderMsgs.EVENT_PUBLISHED, null, override, "deploy success", + artifact.getArtifactName(), sendStatus.getDistributionActionResult().toString()); + + if (sendStatus.getDistributionActionResult() != DistributionActionResultEnum.SUCCESS) { + logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, + "Failed to publish deploy success status: " + sendStatus.getDistributionMessageResult()); + } + } + + private IDistributionStatusMessage buildStatusMessage(IDistributionClient client, + INotificationData data, IArtifactInfo artifact, DistributionStatusEnum status) { + IDistributionStatusMessage statusMessage = new DistributionStatusMsg(status, + data.getDistributionID(), client.getConfiguration().getConsumerID(), + artifact.getArtifactURL()); + + return statusMessage; + } + +} diff --git a/src/main/java/org/openecomp/modelloader/restclient/AaiRestClient.java b/src/main/java/org/openecomp/modelloader/restclient/AaiRestClient.java index d4ee738..4d5e487 100644 --- a/src/main/java/org/openecomp/modelloader/restclient/AaiRestClient.java +++ b/src/main/java/org/openecomp/modelloader/restclient/AaiRestClient.java @@ -1,402 +1,480 @@ -/**
- * ============LICENSE_START=======================================================
- * Model Loader
- * ================================================================================
- * Copyright © 2017 AT&T Intellectual Property.
- * Copyright © 2017 Amdocs
- * All rights reserved.
- * ================================================================================
- * 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=========================================================
- *
- * ECOMP and OpenECOMP are trademarks
- * and service marks of AT&T Intellectual Property.
- */
-package org.openecomp.modelloader.restclient;
-
-import com.sun.jersey.api.client.Client;
-import com.sun.jersey.api.client.ClientResponse;
-import com.sun.jersey.api.client.config.ClientConfig;
-import com.sun.jersey.api.client.config.DefaultClientConfig;
-import com.sun.jersey.api.client.filter.LoggingFilter;
-import com.sun.jersey.client.urlconnection.HTTPSProperties;
-import org.openecomp.cl.api.LogFields;
-import org.openecomp.cl.api.LogLine;
-import org.openecomp.cl.api.Logger;
-import org.openecomp.cl.eelf.LoggerFactory;
-import org.openecomp.cl.mdc.MdcContext;
-import org.openecomp.cl.mdc.MdcOverride;
-import org.openecomp.modelloader.config.ModelLoaderConfig;
-import org.openecomp.modelloader.service.ModelLoaderMsgs;
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-
-import java.io.ByteArrayOutputStream;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.io.StringReader;
-import java.security.GeneralSecurityException;
-import java.security.KeyStore;
-import java.security.cert.X509Certificate;
-import java.text.SimpleDateFormat;
-
-import javax.net.ssl.HostnameVerifier;
-import javax.net.ssl.HttpsURLConnection;
-import javax.net.ssl.KeyManagerFactory;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.TrustManager;
-import javax.net.ssl.X509TrustManager;
-import javax.ws.rs.core.Response;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-
-public class AaiRestClient {
- public enum MimeType {
- XML("application/xml"), JSON("application/json");
-
- private String httpType;
-
- MimeType(String httpType) {
- this.httpType = httpType;
- }
-
- String getHttpHeaderType() {
- return httpType;
- }
- }
-
- private static String HEADER_TRANS_ID = "X-TransactionId";
- private static String HEADER_FROM_APP_ID = "X-FromAppId";
- private static String HEADER_AUTHORIZATION = "Authorization";
- private static String ML_APP_NAME = "ModelLoader";
- private static String RESOURCE_VERSION_PARAM = "resource-version";
-
- private static SimpleDateFormat dateFormatter = new SimpleDateFormat(
- "yyyy-MM-dd'T'HH:mm:ss.SSSXXX");
-
- private static Logger logger = LoggerFactory.getInstance()
- .getLogger(AaiRestClient.class.getName());
- private static Logger metricsLogger = LoggerFactory.getInstance()
- .getMetricsLogger(AaiRestClient.class.getName());
-
- private ModelLoaderConfig config = null;
-
- public AaiRestClient(ModelLoaderConfig config) {
- this.config = config;
- }
-
- /**
- * Send a PUT request to the A&AI.
- *
- * @param url
- * - the url
- * @param transId
- * - transaction ID
- * @param payload
- * - the XML or JSON payload for the request
- * @param mimeType
- * - the content type (XML or JSON)
- * @return ClientResponse
- */
- public ClientResponse putResource(String url, String payload, String transId, MimeType mimeType) {
- ClientResponse result = null;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- long startTimeInMs = 0;
- MdcOverride override = new MdcOverride();
-
- try {
- Client client = setupClient();
-
- baos = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(baos);
- if (logger.isDebugEnabled()) {
- client.addFilter(new LoggingFilter(ps));
- }
-
- // Grab the current time so that we can use it for metrics purposes later.
- startTimeInMs = System.currentTimeMillis();
- override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
-
- if (useBasicAuth()) {
- result = client.resource(url).header(HEADER_TRANS_ID, transId)
- .header(HEADER_FROM_APP_ID, ML_APP_NAME)
- .header(HEADER_AUTHORIZATION, getAuthenticationCredentials())
- .type(mimeType.getHttpHeaderType()).put(ClientResponse.class, payload);
- } else {
- result = client.resource(url).header(HEADER_TRANS_ID, transId)
- .header(HEADER_FROM_APP_ID, ML_APP_NAME).type(mimeType.getHttpHeaderType())
- .put(ClientResponse.class, payload);
- }
- } catch (Exception ex) {
- logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "PUT", url, ex.getLocalizedMessage());
- return null;
- } finally {
- if (logger.isDebugEnabled()) {
- logger.debug(baos.toString());
- }
- }
-
- if ((result != null) && ((result.getStatus() == Response.Status.CREATED.getStatusCode())
- || (result.getStatus() == Response.Status.OK.getStatusCode()))) {
- logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, "PUT", url,
- Integer.toString(result.getStatus()));
- metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS,
- new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus())
- .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION,
- result.getResponseStatus().toString()),
- override, "PUT", url, Integer.toString(result.getStatus()));
- } else {
- // If response is not 200 OK, then additionally log the reason
- String respMsg = result.getEntity(String.class);
- if (respMsg == null) {
- respMsg = result.getStatusInfo().getReasonPhrase();
- }
- logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_UNSUCCESSFUL, "PUT", url,
- Integer.toString(result.getStatus()), respMsg);
- metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_UNSUCCESSFUL,
- new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus())
- .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION,
- result.getResponseStatus().toString()),
- override, "PUT", url, Integer.toString(result.getStatus()), respMsg);
- }
-
- return result;
- }
-
- /**
- * Send a DELETE request to the A&AI.
- *
- * @param url
- * - the url
- * @param resourceVersion
- * - the resource-version of the model to delete
- * @param transId
- * - transaction ID
- * @return ClientResponse
- */
- public ClientResponse deleteResource(String url, String resourceVersion, String transId) {
- ClientResponse result = null;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- long startTimeInMs = 0;
- MdcOverride override = new MdcOverride();
-
- try {
- Client client = setupClient();
-
- baos = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(baos);
- if (logger.isDebugEnabled()) {
- client.addFilter(new LoggingFilter(ps));
- }
-
- // Grab the current time so that we can use it for metrics purposes later.
- startTimeInMs = System.currentTimeMillis();
- override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
-
- if (useBasicAuth()) {
- result = client.resource(url).queryParam(RESOURCE_VERSION_PARAM, resourceVersion)
- .header(HEADER_TRANS_ID, transId).header(HEADER_FROM_APP_ID, ML_APP_NAME)
- .header(HEADER_AUTHORIZATION, getAuthenticationCredentials())
- .delete(ClientResponse.class);
- } else {
- result = client.resource(url).queryParam(RESOURCE_VERSION_PARAM, resourceVersion)
- .header(HEADER_TRANS_ID, transId).header(HEADER_FROM_APP_ID, ML_APP_NAME)
- .delete(ClientResponse.class);
- }
- } catch (Exception ex) {
- logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "DELETE", url, ex.getLocalizedMessage());
- return null;
- } finally {
- if (logger.isDebugEnabled()) {
- logger.debug(baos.toString());
- }
- }
-
- logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, "DELETE", url,
- Integer.toString(result.getStatus()));
- metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS,
- new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus()).setField(
- LogLine.DefinedFields.RESPONSE_DESCRIPTION, result.getResponseStatus().toString()),
- override, "DELETE", url, Integer.toString(result.getStatus()));
-
- return result;
- }
-
- /**
- * Send a GET request to the A&AI for a resource.
- *
- * @param url
- * - the url to use
- * @param transId
- * - transaction ID
- * @return ClientResponse
- */
- public ClientResponse getResource(String url, String transId, MimeType mimeType) {
- ClientResponse result = null;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- long startTimeInMs = 0;
- MdcOverride override = new MdcOverride();
-
- try {
- Client client = setupClient();
-
- baos = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(baos);
- if (logger.isDebugEnabled()) {
- client.addFilter(new LoggingFilter(ps));
- }
-
- // Grab the current time so that we can use it for metrics purposes later.
- startTimeInMs = System.currentTimeMillis();
- override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs));
-
- if (useBasicAuth()) {
- result = client.resource(url).header(HEADER_TRANS_ID, transId)
- .header(HEADER_FROM_APP_ID, ML_APP_NAME).accept(mimeType.getHttpHeaderType())
- .header(HEADER_AUTHORIZATION, getAuthenticationCredentials()).get(ClientResponse.class);
- } else {
- result = client.resource(url).header(HEADER_TRANS_ID, transId)
- .header(HEADER_FROM_APP_ID, ML_APP_NAME).accept(mimeType.getHttpHeaderType())
- .get(ClientResponse.class);
-
- }
- } catch (Exception ex) {
- logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "GET", url, ex.getLocalizedMessage());
- return null;
- } finally {
- if (logger.isDebugEnabled()) {
- logger.debug(baos.toString());
- }
- }
-
- logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, "GET", url,
- Integer.toString(result.getStatus()));
- metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS,
- new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus()).setField(
- LogLine.DefinedFields.RESPONSE_DESCRIPTION, result.getResponseStatus().toString()),
- override, "GET", url, Integer.toString(result.getStatus()));
-
- return result;
- }
-
- /**
- * Does a GET on a resource to retrieve the resource version, and then DELETE
- * that version.
- *
- * @param url
- * - the url
- * @param transId
- * - transaction ID
- * @return ClientResponse
- */
- public ClientResponse getAndDeleteResource(String url, String transId) {
- // First, GET the model
- ClientResponse getResponse = getResource(url, transId, MimeType.XML);
- if ((getResponse == null) || (getResponse.getStatus() != Response.Status.OK.getStatusCode())) {
- return getResponse;
- }
-
- // Delete the model using the resource version in the response
- String resVersion = null;
- try {
- resVersion = getResourceVersion(getResponse);
- } catch (Exception e) {
- logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "GET", url, e.getLocalizedMessage());
- return null;
- }
-
- return deleteResource(url, resVersion, transId);
- }
-
- private Client setupClient() throws IOException, GeneralSecurityException {
- ClientConfig clientConfig = new DefaultClientConfig();
-
- HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
- @Override
- public boolean verify(String string, SSLSession ssls) {
- return true;
- }
- });
-
- // Create a trust manager that does not validate certificate chains
- TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- return null;
- }
-
- @Override
- public void checkClientTrusted(X509Certificate[] certs, String authType) {}
-
- @Override
- public void checkServerTrusted(X509Certificate[] certs, String authType) {}
- } };
-
- SSLContext ctx = SSLContext.getInstance("TLS");
- KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
- FileInputStream fin = new FileInputStream(config.getAaiKeyStorePath());
- KeyStore ks = KeyStore.getInstance("PKCS12");
- char[] pwd = config.getAaiKeyStorePassword().toCharArray();
- ks.load(fin, pwd);
- kmf.init(ks, pwd);
-
- ctx.init(kmf.getKeyManagers(), trustAllCerts, null);
- clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
- new HTTPSProperties(new HostnameVerifier() {
- @Override
- public boolean verify(String theString, SSLSession sslSession) {
- return true;
- }
- }, ctx));
-
- Client client = Client.create(clientConfig);
-
- return client;
- }
-
- private String getResourceVersion(ClientResponse response)
- throws ParserConfigurationException, SAXException, IOException {
- String respData = response.getEntity(String.class);
-
- DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- DocumentBuilder builder = factory.newDocumentBuilder();
- InputSource is = new InputSource(new StringReader(respData));
- Document doc = builder.parse(is);
-
- NodeList nodeList = doc.getDocumentElement().getChildNodes();
- for (int i = 0; i < nodeList.getLength(); i++) {
- Node currentNode = nodeList.item(i);
- if (currentNode.getNodeName().equals(RESOURCE_VERSION_PARAM)) {
- return currentNode.getTextContent();
- }
- }
-
- return null;
- }
-
- private String getAuthenticationCredentials() {
-
- String usernameAndPassword = config.getAaiAuthenticationUser() + ":"
- + config.getAaiAuthenticationPassword();
- return "Basic " + java.util.Base64.getEncoder().encodeToString(usernameAndPassword.getBytes());
- }
-
- public boolean useBasicAuth() {
- return (config.getAaiAuthenticationUser() != null)
- && (config.getAaiAuthenticationPassword() != null);
- }
-}
+/** + * ============LICENSE_START======================================================= + * Model Loader + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.modelloader.restclient; + +import com.sun.jersey.api.client.Client; +import com.sun.jersey.api.client.ClientResponse; +import com.sun.jersey.api.client.config.ClientConfig; +import com.sun.jersey.api.client.config.DefaultClientConfig; +import com.sun.jersey.api.client.filter.LoggingFilter; +import com.sun.jersey.client.urlconnection.HTTPSProperties; +import org.openecomp.cl.api.LogFields; +import org.openecomp.cl.api.LogLine; +import org.openecomp.cl.api.Logger; +import org.openecomp.cl.eelf.LoggerFactory; +import org.openecomp.cl.mdc.MdcContext; +import org.openecomp.cl.mdc.MdcOverride; +import org.openecomp.modelloader.config.ModelLoaderConfig; +import org.openecomp.modelloader.service.ModelLoaderMsgs; +import org.w3c.dom.Document; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.io.StringReader; +import java.security.GeneralSecurityException; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.text.SimpleDateFormat; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import javax.ws.rs.core.Response; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; + +public class AaiRestClient { + public enum MimeType { + XML("application/xml"), JSON("application/json"); + + private String httpType; + + MimeType(String httpType) { + this.httpType = httpType; + } + + String getHttpHeaderType() { + return httpType; + } + } + + private static String HEADER_TRANS_ID = "X-TransactionId"; + private static String HEADER_FROM_APP_ID = "X-FromAppId"; + private static String HEADER_AUTHORIZATION = "Authorization"; + private static String ML_APP_NAME = "ModelLoader"; + private static String RESOURCE_VERSION_PARAM = "resource-version"; + + private static SimpleDateFormat dateFormatter = new SimpleDateFormat( + "yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); + + private static Logger logger = LoggerFactory.getInstance() + .getLogger(AaiRestClient.class.getName()); + private static Logger metricsLogger = LoggerFactory.getInstance() + .getMetricsLogger(AaiRestClient.class.getName()); + + private ModelLoaderConfig config = null; + + public AaiRestClient(ModelLoaderConfig config) { + this.config = config; + } + + /** + * Send a PUT request to the A&AI. + * + * @param url + * - the url + * @param transId + * - transaction ID + * @param payload + * - the XML or JSON payload for the request + * @param mimeType + * - the content type (XML or JSON) + * @return ClientResponse + */ + public ClientResponse putResource(String url, String payload, String transId, MimeType mimeType) { + ClientResponse result = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + long startTimeInMs = 0; + MdcOverride override = new MdcOverride(); + + try { + Client client = setupClient(); + + baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + if (logger.isDebugEnabled()) { + client.addFilter(new LoggingFilter(ps)); + } + + // Grab the current time so that we can use it for metrics purposes later. + startTimeInMs = System.currentTimeMillis(); + override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs)); + + if (useBasicAuth()) { + result = client.resource(url).header(HEADER_TRANS_ID, transId) + .header(HEADER_FROM_APP_ID, ML_APP_NAME) + .header(HEADER_AUTHORIZATION, getAuthenticationCredentials()) + .type(mimeType.getHttpHeaderType()).put(ClientResponse.class, payload); + } else { + result = client.resource(url).header(HEADER_TRANS_ID, transId) + .header(HEADER_FROM_APP_ID, ML_APP_NAME).type(mimeType.getHttpHeaderType()) + .put(ClientResponse.class, payload); + } + } catch (Exception ex) { + logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "PUT", url, ex.getLocalizedMessage()); + return null; + } finally { + if (logger.isDebugEnabled()) { + logger.debug(baos.toString()); + } + } + + if ((result != null) && ((result.getStatus() == Response.Status.CREATED.getStatusCode()) + || (result.getStatus() == Response.Status.OK.getStatusCode()))) { + logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, "PUT", url, + Integer.toString(result.getStatus())); + metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, + new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus()) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, + result.getResponseStatus().toString()), + override, "PUT", url, Integer.toString(result.getStatus())); + } else { + // If response is not 200 OK, then additionally log the reason + String respMsg = result.getEntity(String.class); + if (respMsg == null) { + respMsg = result.getStatusInfo().getReasonPhrase(); + } + logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_UNSUCCESSFUL, "PUT", url, + Integer.toString(result.getStatus()), respMsg); + metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_UNSUCCESSFUL, + new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus()) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, + result.getResponseStatus().toString()), + override, "PUT", url, Integer.toString(result.getStatus()), respMsg); + } + + return result; + } + + /** + * Send a DELETE request to the A&AI. + * + * @param url + * - the url + * @param resourceVersion + * - the resource-version of the model to delete + * @param transId + * - transaction ID + * @return ClientResponse + */ + public ClientResponse deleteResource(String url, String resourceVersion, String transId) { + ClientResponse result = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + long startTimeInMs = 0; + MdcOverride override = new MdcOverride(); + + try { + Client client = setupClient(); + + baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + if (logger.isDebugEnabled()) { + client.addFilter(new LoggingFilter(ps)); + } + + // Grab the current time so that we can use it for metrics purposes later. + startTimeInMs = System.currentTimeMillis(); + override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs)); + + if (useBasicAuth()) { + result = client.resource(url).queryParam(RESOURCE_VERSION_PARAM, resourceVersion) + .header(HEADER_TRANS_ID, transId).header(HEADER_FROM_APP_ID, ML_APP_NAME) + .header(HEADER_AUTHORIZATION, getAuthenticationCredentials()) + .delete(ClientResponse.class); + } else { + result = client.resource(url).queryParam(RESOURCE_VERSION_PARAM, resourceVersion) + .header(HEADER_TRANS_ID, transId).header(HEADER_FROM_APP_ID, ML_APP_NAME) + .delete(ClientResponse.class); + } + } catch (Exception ex) { + logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "DELETE", url, ex.getLocalizedMessage()); + return null; + } finally { + if (logger.isDebugEnabled()) { + logger.debug(baos.toString()); + } + } + + logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, "DELETE", url, + Integer.toString(result.getStatus())); + metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, + new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus()).setField( + LogLine.DefinedFields.RESPONSE_DESCRIPTION, result.getResponseStatus().toString()), + override, "DELETE", url, Integer.toString(result.getStatus())); + + return result; + } + + /** + * Send a GET request to the A&AI for a resource. + * + * @param url + * - the url to use + * @param transId + * - transaction ID + * @return ClientResponse + */ + public ClientResponse getResource(String url, String transId, MimeType mimeType) { + ClientResponse result = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + long startTimeInMs = 0; + MdcOverride override = new MdcOverride(); + + try { + Client client = setupClient(); + + baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + if (logger.isDebugEnabled()) { + client.addFilter(new LoggingFilter(ps)); + } + + // Grab the current time so that we can use it for metrics purposes later. + startTimeInMs = System.currentTimeMillis(); + override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs)); + + if (useBasicAuth()) { + result = client.resource(url).header(HEADER_TRANS_ID, transId) + .header(HEADER_FROM_APP_ID, ML_APP_NAME).accept(mimeType.getHttpHeaderType()) + .header(HEADER_AUTHORIZATION, getAuthenticationCredentials()).get(ClientResponse.class); + } else { + result = client.resource(url).header(HEADER_TRANS_ID, transId) + .header(HEADER_FROM_APP_ID, ML_APP_NAME).accept(mimeType.getHttpHeaderType()) + .get(ClientResponse.class); + + } + } catch (Exception ex) { + logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "GET", url, ex.getLocalizedMessage()); + return null; + } finally { + if (logger.isDebugEnabled()) { + logger.debug(baos.toString()); + } + } + + logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, "GET", url, + Integer.toString(result.getStatus())); + metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, + new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus()).setField( + LogLine.DefinedFields.RESPONSE_DESCRIPTION, result.getResponseStatus().toString()), + override, "GET", url, Integer.toString(result.getStatus())); + + return result; + } + + /** + * Send a POST request to the A&AI. + * + * @param url + * - the url + * @param transId + * - transaction ID + * @param payload + * - the XML or JSON payload for the request + * @param mimeType + * - the content type (XML or JSON) + * @return ClientResponse + */ + public ClientResponse postResource(String url, String payload, String transId, MimeType mimeType) { + ClientResponse result = null; + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + long startTimeInMs = 0; + MdcOverride override = new MdcOverride(); + + try { + Client client = setupClient(); + + baos = new ByteArrayOutputStream(); + PrintStream ps = new PrintStream(baos); + if (logger.isDebugEnabled()) { + client.addFilter(new LoggingFilter(ps)); + } + + // Grab the current time so that we can use it for metrics purposes later. + startTimeInMs = System.currentTimeMillis(); + override.addAttribute(MdcContext.MDC_START_TIME, dateFormatter.format(startTimeInMs)); + + if (useBasicAuth()) { + result = client.resource(url).header(HEADER_TRANS_ID, transId) + .header(HEADER_FROM_APP_ID, ML_APP_NAME) + .header(HEADER_AUTHORIZATION, getAuthenticationCredentials()) + .type(mimeType.getHttpHeaderType()).post(ClientResponse.class, payload); + } else { + result = client.resource(url).header(HEADER_TRANS_ID, transId) + .header(HEADER_FROM_APP_ID, ML_APP_NAME).type(mimeType.getHttpHeaderType()) + .post(ClientResponse.class, payload); + } + } catch (Exception ex) { + logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "POST", url, ex.getLocalizedMessage()); + return null; + } finally { + if (logger.isDebugEnabled()) { + logger.debug(baos.toString()); + } + } + + if ((result != null) && ((result.getStatus() == Response.Status.CREATED.getStatusCode()) + || (result.getStatus() == Response.Status.OK.getStatusCode()))) { + logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, "POST", url, + Integer.toString(result.getStatus())); + metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_SUCCESS, + new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus()) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, + result.getResponseStatus().toString()), + override, "POST", url, Integer.toString(result.getStatus())); + } else { + // If response is not 200 OK, then additionally log the reason + String respMsg = result.getEntity(String.class); + if (respMsg == null) { + respMsg = result.getStatusInfo().getReasonPhrase(); + } + logger.info(ModelLoaderMsgs.AAI_REST_REQUEST_UNSUCCESSFUL, "POST", url, + Integer.toString(result.getStatus()), respMsg); + metricsLogger.info(ModelLoaderMsgs.AAI_REST_REQUEST_UNSUCCESSFUL, + new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getStatus()) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, + result.getResponseStatus().toString()), + override, "POST", url, Integer.toString(result.getStatus()), respMsg); + } + + return result; + } + + /** + * Does a GET on a resource to retrieve the resource version, and then DELETE + * that version. + * + * @param url + * - the url + * @param transId + * - transaction ID + * @return ClientResponse + */ + public ClientResponse getAndDeleteResource(String url, String transId) { + // First, GET the model + ClientResponse getResponse = getResource(url, transId, MimeType.XML); + if ((getResponse == null) || (getResponse.getStatus() != Response.Status.OK.getStatusCode())) { + return getResponse; + } + + // Delete the model using the resource version in the response + String resVersion = null; + try { + resVersion = getResourceVersion(getResponse); + } catch (Exception e) { + logger.error(ModelLoaderMsgs.AAI_REST_REQUEST_ERROR, "GET", url, e.getLocalizedMessage()); + return null; + } + + return deleteResource(url, resVersion, transId); + } + + private Client setupClient() throws IOException, GeneralSecurityException { + ClientConfig clientConfig = new DefaultClientConfig(); + + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String string, SSLSession ssls) { + return true; + } + }); + + // Create a trust manager that does not validate certificate chains + TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { + @Override + public X509Certificate[] getAcceptedIssuers() { + return null; + } + + @Override + public void checkClientTrusted(X509Certificate[] certs, String authType) {} + + @Override + public void checkServerTrusted(X509Certificate[] certs, String authType) {} + } }; + + SSLContext ctx = SSLContext.getInstance("TLS"); + KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509"); + FileInputStream fin = new FileInputStream(config.getAaiKeyStorePath()); + KeyStore ks = KeyStore.getInstance("PKCS12"); + char[] pwd = config.getAaiKeyStorePassword().toCharArray(); + ks.load(fin, pwd); + kmf.init(ks, pwd); + + ctx.init(kmf.getKeyManagers(), trustAllCerts, null); + clientConfig.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, + new HTTPSProperties(new HostnameVerifier() { + @Override + public boolean verify(String theString, SSLSession sslSession) { + return true; + } + }, ctx)); + + Client client = Client.create(clientConfig); + + return client; + } + + private String getResourceVersion(ClientResponse response) + throws ParserConfigurationException, SAXException, IOException { + String respData = response.getEntity(String.class); + + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + InputSource is = new InputSource(new StringReader(respData)); + Document doc = builder.parse(is); + + NodeList nodeList = doc.getDocumentElement().getChildNodes(); + for (int i = 0; i < nodeList.getLength(); i++) { + Node currentNode = nodeList.item(i); + if (currentNode.getNodeName().equals(RESOURCE_VERSION_PARAM)) { + return currentNode.getTextContent(); + } + } + + return null; + } + + private String getAuthenticationCredentials() { + + String usernameAndPassword = config.getAaiAuthenticationUser() + ":" + + config.getAaiAuthenticationPassword(); + return "Basic " + java.util.Base64.getEncoder().encodeToString(usernameAndPassword.getBytes()); + } + + public boolean useBasicAuth() { + return (config.getAaiAuthenticationUser() != null) + && (config.getAaiAuthenticationPassword() != null); + } +} |