diff options
author | 2017-05-03 13:47:43 -0400 | |
---|---|---|
committer | 2017-05-03 13:48:14 -0400 | |
commit | 578368fce559ad28eb3bc62064e4c39858fa3339 (patch) | |
tree | 3ab6b05b4e2738e0a2e9c3a4633ff2693652f5a4 /src/main/java/org/openecomp/modelloader/entity | |
parent | 3c76a64c4d8571c5a319af42fedc61b851106f6d (diff) |
Implement support for v10 model entities.
Change-Id: Id2b42b70d7fe0ada6695ac9632b314f21ace193f
Signed-off-by: Fraboni, Gino (gf403a) <gino.fraboni@amdocs.com>
Diffstat (limited to 'src/main/java/org/openecomp/modelloader/entity')
9 files changed, 1199 insertions, 944 deletions
diff --git a/src/main/java/org/openecomp/modelloader/entity/Artifact.java b/src/main/java/org/openecomp/modelloader/entity/Artifact.java index fb0ec9f..30709ae 100644 --- a/src/main/java/org/openecomp/modelloader/entity/Artifact.java +++ b/src/main/java/org/openecomp/modelloader/entity/Artifact.java @@ -1,44 +1,46 @@ -/*- - * ============LICENSE_START======================================================= - * MODEL LOADER SERVICE - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. 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========================================================= - */ - -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 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;
+ }
+
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/ArtifactHandler.java b/src/main/java/org/openecomp/modelloader/entity/ArtifactHandler.java index 16f2c87..bd6a861 100644 --- a/src/main/java/org/openecomp/modelloader/entity/ArtifactHandler.java +++ b/src/main/java/org/openecomp/modelloader/entity/ArtifactHandler.java @@ -1,37 +1,39 @@ -/*- - * ============LICENSE_START======================================================= - * MODEL LOADER SERVICE - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. 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========================================================= - */ - -package org.openecomp.modelloader.entity; - -import org.openecomp.modelloader.config.ModelLoaderConfig; - -import java.util.List; - -public abstract class ArtifactHandler { - - protected ModelLoaderConfig config; - - public ArtifactHandler(ModelLoaderConfig config) { - this.config = config; - } - - public abstract boolean pushArtifacts(List<Artifact> artifacts, String distributionId); - -} +/**
+ * ============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;
+
+import org.openecomp.modelloader.config.ModelLoaderConfig;
+
+import java.util.List;
+
+public abstract class ArtifactHandler {
+
+ protected ModelLoaderConfig config;
+
+ public ArtifactHandler(ModelLoaderConfig config) {
+ this.config = config;
+ }
+
+ public abstract boolean pushArtifacts(List<Artifact> artifacts, String distributionId);
+
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/ArtifactType.java b/src/main/java/org/openecomp/modelloader/entity/ArtifactType.java index 8977e3c..ae556bc 100644 --- a/src/main/java/org/openecomp/modelloader/entity/ArtifactType.java +++ b/src/main/java/org/openecomp/modelloader/entity/ArtifactType.java @@ -1,25 +1,27 @@ -/*- - * ============LICENSE_START======================================================= - * MODEL LOADER SERVICE - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. 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========================================================= - */ - -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, 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 b2e1fdb..a15ed3c 100644 --- a/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifact.java +++ b/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifact.java @@ -1,31 +1,33 @@ -/*- - * ============LICENSE_START======================================================= - * MODEL LOADER SERVICE - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. 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========================================================= - */ - -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) {
+ setPayload(payload);
+ setType(ArtifactType.VNF_CATALOG);
+ }
+}
diff --git a/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifactHandler.java b/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifactHandler.java index 189b069..5c526a6 100644 --- a/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifactHandler.java +++ b/src/main/java/org/openecomp/modelloader/entity/catalog/VnfCatalogArtifactHandler.java @@ -1,184 +1,192 @@ -/*- - * ============LICENSE_START======================================================= - * MODEL LOADER SERVICE - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. 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========================================================= - */ - -package org.openecomp.modelloader.entity.catalog; - -import com.sun.jersey.api.client.ClientResponse; - -import generated.VnfCatalog; -import generated.VnfCatalog.PartNumberList; - -import inventory.aai.openecomp.org.v8.VnfImage; - -import org.eclipse.persistence.jaxb.MarshallerProperties; -import 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.restclient.AaiRestClient; -import org.openecomp.modelloader.restclient.AaiRestClient.MimeType; -import org.openecomp.modelloader.service.ModelLoaderMsgs; - -import java.io.StringReader; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import javax.ws.rs.core.Response; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; - - -public class VnfCatalogArtifactHandler extends ArtifactHandler { - - private static Logger logger = LoggerFactory.getInstance() - .getLogger(VnfCatalogArtifactHandler.class.getName()); - - public VnfCatalogArtifactHandler(ModelLoaderConfig config) { - super(config); - } - - @Override - public boolean pushArtifacts(List<Artifact> artifacts, String distributionId) { - for (Artifact art : artifacts) { - VnfCatalogArtifact vnfCatalog = (VnfCatalogArtifact) art; - String artifactPayload = vnfCatalog.getPayload(); - - AaiRestClient restClient = new AaiRestClient(this.config); - List<VnfImage> putImages = new ArrayList<VnfImage>(); - - try { - JAXBContext inputContext = JAXBContext.newInstance(VnfCatalog.class); - Unmarshaller unmarshaller = inputContext.createUnmarshaller(); - StringReader reader = new StringReader(artifactPayload); - VnfCatalog cat = (VnfCatalog) unmarshaller.unmarshal(reader); - - int numParts = cat.getPartNumberList().size(); - - for (int i = 0; i < numParts; i++) { - - PartNumberList pnl = cat.getPartNumberList().get(i); - - String application = pnl.getVendorInfo().getVendorModel(); - String applicationVendor = pnl.getVendorInfo().getVendorName(); - - int numVersions = pnl.getSoftwareVersionList().size(); - - for (int j = 0; j < numVersions; j++) { - String applicationVersion = pnl.getSoftwareVersionList().get(j).getSoftwareVersion(); - - String imageId = "vnf image " + applicationVendor + " " + application + " " - + applicationVersion; - - String getUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() - + "?application-vendor=" + applicationVendor + "&application=" + application - + "&application-version=" + applicationVersion; - - ClientResponse tryGet = restClient.getResource(getUrl, distributionId, MimeType.JSON); - if (tryGet == null) { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, - "Ingestion failed on " + imageId + ". Rolling back distribution."); - failureCleanup(putImages, restClient, distributionId); - return false; - } - if (tryGet.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) { - // this vnf-image not already in the db, need to add - // only do this on 404 bc other error responses could mean there - // are problems that - // you might not want to try to PUT against - - VnfImage image = new VnfImage(); - image.setApplication(application); - image.setApplicationVendor(applicationVendor); - image.setApplicationVersion(applicationVersion); - String uuid = UUID.randomUUID().toString(); - image.setUuid(uuid); // need to create uuid - - System.setProperty("javax.xml.bind.context.factory", - "org.eclipse.persistence.jaxb.JAXBContextFactory"); - JAXBContext jaxbContext = JAXBContext.newInstance(VnfImage.class); - Marshaller marshaller = jaxbContext.createMarshaller(); - marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json"); - marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false); - marshaller.setProperty(MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true); - marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false); - StringWriter writer = new StringWriter(); - marshaller.marshal(image, writer); - String payload = writer.toString(); - - String putUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" - + uuid; - - ClientResponse putResp = restClient.putResource(putUrl, payload, distributionId, - MimeType.JSON); - if (putResp == null - || putResp.getStatus() != Response.Status.CREATED.getStatusCode()) { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, - "Ingestion failed on vnf-image " + imageId + ". Rolling back distribution."); - failureCleanup(putImages, restClient, distributionId); - return false; - } - putImages.add(image); - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, imageId + " successfully ingested."); - } else if (tryGet.getStatus() == Response.Status.OK.getStatusCode()) { - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, - imageId + " already exists. Skipping ingestion."); - } else { - // if other than 404 or 200, something went wrong - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, - "Ingestion failed on vnf-image " + imageId + " with status " + tryGet.getStatus() - + ". Rolling back distribution."); - failureCleanup(putImages, restClient, distributionId); - return false; - } - } - } - - } catch (JAXBException e) { - logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, - "Ingestion failed. " + e.getMessage() + ". Rolling back distribution."); - failureCleanup(putImages, restClient, distributionId); - return false; - } - } - - return true; - } - - /* - * if something fails in the middle of ingesting the catalog we want to - * rollback any changes to the db - */ - private void failureCleanup(List<VnfImage> putImages, AaiRestClient restClient, String transId) { - for (VnfImage image : putImages) { - String url = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/" - + image.getUuid(); - restClient.getAndDeleteResource(url, transId); // try to delete the image, - // if something goes wrong - // we can't really do - // anything here - } - } - -} +/**
+ * ============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 com.sun.jersey.api.client.ClientResponse;
+
+import generated.VnfCatalog;
+import generated.VnfCatalog.PartNumberList;
+
+import inventory.aai.openecomp.org.v8.VnfImage;
+
+import org.eclipse.persistence.jaxb.MarshallerProperties;
+import 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.restclient.AaiRestClient;
+import org.openecomp.modelloader.restclient.AaiRestClient.MimeType;
+import org.openecomp.modelloader.service.ModelLoaderMsgs;
+import org.springframework.web.util.UriUtils;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import javax.ws.rs.core.Response;
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.bind.Marshaller;
+import javax.xml.bind.Unmarshaller;
+
+
+public class VnfCatalogArtifactHandler extends ArtifactHandler {
+
+ private static Logger logger = LoggerFactory.getInstance()
+ .getLogger(VnfCatalogArtifactHandler.class.getName());
+
+ public VnfCatalogArtifactHandler(ModelLoaderConfig config) {
+ super(config);
+ }
+
+ @Override
+ public boolean pushArtifacts(List<Artifact> artifacts, String distributionId) {
+ for (Artifact art : artifacts) {
+ VnfCatalogArtifact vnfCatalog = (VnfCatalogArtifact) art;
+ String artifactPayload = vnfCatalog.getPayload();
+
+ AaiRestClient restClient = new AaiRestClient(this.config);
+ List<VnfImage> putImages = new ArrayList<VnfImage>();
+
+ try {
+ JAXBContext inputContext = JAXBContext.newInstance(VnfCatalog.class);
+ Unmarshaller unmarshaller = inputContext.createUnmarshaller();
+ StringReader reader = new StringReader(artifactPayload);
+ VnfCatalog cat = (VnfCatalog) unmarshaller.unmarshal(reader);
+
+ int numParts = cat.getPartNumberList().size();
+
+ for (int i = 0; i < numParts; i++) {
+
+ PartNumberList pnl = cat.getPartNumberList().get(i);
+
+ String application = pnl.getVendorInfo().getVendorModel();
+ String applicationVendor = pnl.getVendorInfo().getVendorName();
+
+ int numVersions = pnl.getSoftwareVersionList().size();
+
+ for (int j = 0; j < numVersions; j++) {
+ String applicationVersion = pnl.getSoftwareVersionList().get(j).getSoftwareVersion();
+
+ String imageId = "vnf image " + applicationVendor + " " + application + " "
+ + applicationVersion;
+
+ String queryURI = "application-vendor=" + applicationVendor + "&application=" + application + "&application-version=" + applicationVersion;
+
+ String getUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "?" + UriUtils.encodePath(queryURI, "UTF-8");
+
+ ClientResponse tryGet = restClient.getResource(getUrl, distributionId, MimeType.JSON);
+ if (tryGet == null) {
+ logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+ "Ingestion failed on " + imageId + ". Rolling back distribution.");
+ failureCleanup(putImages, restClient, distributionId);
+ return false;
+ }
+ if (tryGet.getStatus() == Response.Status.NOT_FOUND.getStatusCode()) {
+ // this vnf-image not already in the db, need to add
+ // only do this on 404 bc other error responses could mean there
+ // are problems that
+ // you might not want to try to PUT against
+
+ VnfImage image = new VnfImage();
+ image.setApplication(application);
+ image.setApplicationVendor(applicationVendor);
+ image.setApplicationVersion(applicationVersion);
+ String uuid = UUID.randomUUID().toString();
+ image.setUuid(uuid); // need to create uuid
+
+ System.setProperty("javax.xml.bind.context.factory",
+ "org.eclipse.persistence.jaxb.JAXBContextFactory");
+ JAXBContext jaxbContext = JAXBContext.newInstance(VnfImage.class);
+ Marshaller marshaller = jaxbContext.createMarshaller();
+ marshaller.setProperty(MarshallerProperties.MEDIA_TYPE, "application/json");
+ marshaller.setProperty(MarshallerProperties.JSON_INCLUDE_ROOT, false);
+ marshaller.setProperty(MarshallerProperties.JSON_WRAPPER_AS_ARRAY_NAME, true);
+ marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, false);
+ StringWriter writer = new StringWriter();
+ marshaller.marshal(image, writer);
+ String payload = writer.toString();
+
+ String putUrl = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/"
+ + uuid;
+
+ ClientResponse putResp = restClient.putResource(putUrl, payload, distributionId,
+ MimeType.JSON);
+ if (putResp == null
+ || putResp.getStatus() != Response.Status.CREATED.getStatusCode()) {
+ logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+ "Ingestion failed on vnf-image " + imageId + ". Rolling back distribution.");
+ failureCleanup(putImages, restClient, distributionId);
+ return false;
+ }
+ putImages.add(image);
+ logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, imageId + " successfully ingested.");
+ } else if (tryGet.getStatus() == Response.Status.OK.getStatusCode()) {
+ logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
+ imageId + " already exists. Skipping ingestion.");
+ } else {
+ // if other than 404 or 200, something went wrong
+ logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+ "Ingestion failed on vnf-image " + imageId + " with status " + tryGet.getStatus()
+ + ". Rolling back distribution.");
+ failureCleanup(putImages, restClient, distributionId);
+ return false;
+ }
+ }
+ }
+
+ } catch (JAXBException e) {
+ logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR,
+ "Ingestion failed. " + e.getMessage() + ". Rolling back distribution.");
+ failureCleanup(putImages, restClient, distributionId);
+ return false;
+ } catch (UnsupportedEncodingException e) {
+ logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Ingestion failed. " + e.getMessage() + ". Rolling back distribution.");
+ failureCleanup(putImages, restClient, distributionId);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /*
+ * if something fails in the middle of ingesting the catalog we want to
+ * rollback any changes to the db
+ */
+ private void failureCleanup(List<VnfImage> putImages, AaiRestClient restClient, String transId) {
+ for (VnfImage image : putImages) {
+ String url = config.getAaiBaseUrl() + config.getAaiVnfImageUrl() + "/vnf-image/"
+ + image.getUuid();
+ restClient.getAndDeleteResource(url, transId); // try to delete the image,
+ // if something goes wrong
+ // we can't really do
+ // anything here
+ }
+ }
+
+}
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 904dba9..14749e5 100644 --- a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifact.java +++ b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifact.java @@ -1,60 +1,134 @@ -/*- - * ============LICENSE_START======================================================= - * MODEL LOADER SERVICE - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. 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========================================================= - */ - -package org.openecomp.modelloader.entity.model; - -import org.openecomp.modelloader.entity.Artifact; - -import java.util.HashSet; -import java.util.Set; - -public class ModelArtifact extends Artifact { - - String nameVersionId; - Set<String> referencedModelIds = new HashSet<String>(); - - public String getNameVersionId() { - return nameVersionId; - } - - public void setNameVersionId(String nameVersionId) { - this.nameVersionId = nameVersionId; - } - - public Set<String> getDependentModelIds() { - return referencedModelIds; - } - - public void addDependentModelId(String dependentModelId) { - this.referencedModelIds.add(dependentModelId); - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append("NameVersId=" + nameVersionId + "(" + getType().toString() + ") ==> "); - for (String dep : referencedModelIds) { - sb.append(dep + " "); - } - - return sb.toString(); - } - -} +/**
+ * ============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.modelloader.entity.Artifact;
+import org.w3c.dom.Node;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class ModelArtifact extends Artifact {
+
+ String modelVerId;
+ String modelInvariantId;
+ String nameVersionId;
+ String modelModelVerCombinedKey;
+ String modelVerModelVersionId;
+ String modelModelInvariantId;
+ String modelNamespace;
+ Set<String> referencedModelIds = new HashSet<String>();
+ Node modelVer;
+ boolean isV9Artifact = true;
+
+ public boolean isV9Artifact() {
+ return isV9Artifact;
+ }
+
+ public void setV9Artifact(boolean isV9Artifact) {
+ this.isV9Artifact = isV9Artifact;
+ }
+
+ 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;
+ }
+
+ public Set<String> getDependentModelIds() {
+ return referencedModelIds;
+ }
+
+ public void addDependentModelId(String dependentModelId) {
+ this.referencedModelIds.add(dependentModelId);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("ModelInvariantId=" + modelInvariantId + "(" + getType().toString() + ") ==> ");
+ for (String dep : referencedModelIds) {
+ sb.append(dep + " ");
+ }
+
+ return sb.toString();
+ }
+
+ public String getModelVerId() {
+ return modelVerId;
+ }
+
+ public void setModelVerId(String modelVerId) {
+ this.modelVerId = modelVerId;
+ }
+
+ public String getModelInvariantId() {
+ return modelInvariantId;
+ }
+
+ public void setModelInvariantId(String modelInvariantId) {
+ this.modelInvariantId = modelInvariantId;
+ }
+
+ public Node getModelVer() {
+ return modelVer;
+ }
+
+ public void setModelVer(Node modelVer) {
+ this.modelVer = modelVer;
+ }
+
+ public String getModelModelVerCombinedKey() {
+ return getModelInvariantId() + "|" + getModelVerId();
+ }
+
+ public void setModelModelVerCombinedKey(String modelModelVerCombinedKey) {
+ this.modelModelVerCombinedKey = getModelInvariantId() + "|" + getModelVerId();
+ }
+}
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 fb269b1..ce6d986 100644 --- a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactHandler.java +++ b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactHandler.java @@ -1,133 +1,228 @@ -/*- - * ============LICENSE_START======================================================= - * MODEL LOADER SERVICE - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. 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========================================================= - */ - -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 java.util.ArrayList; -import java.util.List; - -import javax.ws.rs.core.Response; - -public class ModelArtifactHandler extends ArtifactHandler { - - private static Logger logger = LoggerFactory.getInstance() - .getLogger(ArtifactHandler.class.getName()); - - public ModelArtifactHandler(ModelLoaderConfig config) { - super(config); - } - - @Override - public boolean pushArtifacts(List<Artifact> artifacts, String distributionId) { - ModelSorter modelSorter = new ModelSorter(); - List<Artifact> sortedModelArtifacts = modelSorter.sort(artifacts); - - // 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>(); - AaiRestClient aaiClient = new AaiRestClient(config); - - for (Artifact art : sortedModelArtifacts) { - ModelArtifact model = (ModelArtifact) art; - 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.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(getUrl(modelToDelete), distributionId); - } - - return false; - } - } else { - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, model.getType().toString() + " " - + model.getNameVersionId() + " already exists. Skipping ingestion."); - } - } - - return true; - } - - private String getUrl(ModelArtifact model) { - String baseUrl = config.getAaiBaseUrl().trim(); - String subUrl = null; - if (model.getType().equals(ArtifactType.MODEL)) { - subUrl = config.getAaiModelUrl().trim(); - } else { - subUrl = config.getAaiNamedQueryUrl().trim(); - } - - 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 + model.getNameVersionId(); - return url; - } - - /** - * This method is used for the test REST interface to load models without an - * ASDC. - * - * @param payload content of the request - */ - public void loadModelTest(byte[] payload) { - List<Artifact> modelArtifacts = new ArrayList<Artifact>(); - ModelArtifactParser parser = new ModelArtifactParser(); - modelArtifacts.addAll(parser.parse(payload, "Test-Artifact")); - ModelSorter modelSorter = new ModelSorter(); - List<Artifact> sortedModelArtifacts = modelSorter.sort(modelArtifacts); - pushArtifacts(sortedModelArtifacts, "Test-Distribution"); - } -} +/**
+ * ============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 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());
+
+
+ public ModelArtifactHandler(ModelLoaderConfig config) {
+ super(config);
+ }
+
+ @Override
+ public boolean pushArtifacts(List<Artifact> artifacts, String distributionID) {
+ ModelSorter modelSorter = new ModelSorter();
+ List<Artifact> sortedModelArtifacts = modelSorter.sort(artifacts);
+
+ // 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>();
+ 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;
+ }
+ 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 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;
+ if (model.getType().equals(ArtifactType.MODEL)) {
+ subURL = config.getAaiModelUrl().trim();
+ }
+ else {
+ subURL = config.getAaiNamedQueryUrl().trim();
+ }
+
+ 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 + model.getModelInvariantId();
+ return url;
+ }
+
+ private String getModelVerURL(ModelArtifact model) {
+ String baseURL = config.getAaiBaseUrl().trim();
+ String subURL = null;
+ if (model.getType().equals(ArtifactType.MODEL)) {
+ subURL = config.getAaiModelUrl().trim() + model.getModelInvariantId() + AAI_MODEL_VER;
+ }
+ else {
+ subURL = config.getAaiNamedQueryUrl().trim();
+ }
+
+ 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 + model.getModelVerId();
+ System.out.println(url);
+ 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>();
+ ModelArtifactParser parser = new ModelArtifactParser();
+ modelArtifacts.addAll(parser.parse(payload, "Test-Artifact"));
+ ModelSorter modelSorter = new ModelSorter();
+ List<Artifact> sortedModelArtifacts = modelSorter.sort(modelArtifacts);
+ pushArtifacts(sortedModelArtifacts, "Test-Distribution");
+ }
+}
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 625145f..de27924 100644 --- a/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactParser.java +++ b/src/main/java/org/openecomp/modelloader/entity/model/ModelArtifactParser.java @@ -1,197 +1,265 @@ -/*- - * ============LICENSE_START======================================================= - * MODEL LOADER SERVICE - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. 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========================================================= - */ - -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.Node; -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.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 { - - 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 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-name-version-id"; - - private static Logger logger = LoggerFactory.getInstance() - .getLogger(ModelArtifactParser.class.getName()); - - /** - * This method parses the given artifact payload in byte array format and - * generates a list of model artifacts according to the content. - * - * @param artifactPayload - * artifact content to be parsed - * @param artifactName - * name of the artifact - * @return a list of model artifacts - */ - public List<Artifact> parse(byte[] artifactPayload, String artifactName) { - String payload = new String(artifactPayload); - 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); - if (model != null) { - modelList.add(model); - } else { - // TODO: A WARN message? - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, - "Unable to parse artifact " + artifactName); - } - } 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 { - // TODO: A WARN message? - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, - "Unable to parse artifact " + artifactName); - modelList.clear(); - break; - } - } - } - } - } catch (Exception ex) { - // This may not be an error. We may be receiving an artifact that is - // unrelated - // to models. In this case, we just ignore it. - // TODO: A WARN message? - logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, - "Unable to parse artifact " + artifactName + ": " + ex.getLocalizedMessage()); - } - - return modelList; - } - - private ModelArtifact parseModel(Node modelNode, String payload) { - ModelArtifact model = new ModelArtifact(); - model.setPayload(payload); - - if (modelNode.getNodeName().equalsIgnoreCase(MODEL_ELEMENT)) { - model.setType(ArtifactType.MODEL); - } else { - model.setType(ArtifactType.NAMED_QUERY); - } - - parseNode(modelNode, model); - - if (model.getNameVersionId() == null) { - return null; - } - - return model; - } - - private void parseNode(Node node, ModelArtifact model) { - if (node.getNodeName().equalsIgnoreCase(MODEL_NAME_VERSION_ID)) { - model.setNameVersionId(node.getTextContent().trim()); - } else if (node.getNodeName().equalsIgnoreCase(NAMED_QUERY_VERSION_ID)) { - model.setNameVersionId(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, ModelArtifact 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); - } - } - } - - private String nodeToString(Node node) throws TransformerException { - StringWriter sw = new StringWriter(); - Transformer transfomer = TransformerFactory.newInstance().newTransformer(); - transfomer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); - transfomer.transform(new DOMSource(node), new StreamResult(sw)); - return sw.toString(); - } -} +/**
+ * ============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.entity.ArtifactType;
+import org.openecomp.modelloader.service.ModelLoaderMsgs;
+import org.openecomp.modelloader.util.JsonXmlConverter;
+
+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.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 {
+
+ 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_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 String MODEL_VER_ELEMENT_RELATIONSHIP_KEY = "model-ver.model-version-id";
+
+ private static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifactParser.class.getName());
+
+ public List<Artifact> parse(byte[] artifactPayload, String artifactName) {
+ String payload = new String(artifactPayload);
+ 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);
+
+ 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;
+ }
+ }
+ 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;
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex) {
+ logger.error(ModelLoaderMsgs.ARTIFACT_PARSE_ERROR, "Unable to parse artifact " + artifactName + ": " + ex.getLocalizedMessage());
+ }
+
+ 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) {
+ return null;
+ }
+
+ return model;
+ }
+
+ 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)) {
+ 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(MODEL_VER)) {
+ model.setModelVer(node);
+ if ( (model.getModelNamespace() != null) && (!model.getModelNamespace().isEmpty()) ) {
+ Element e = (Element) node;
+ e.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, "xmlns", model.getModelNamespace());
+ System.out.println("Setting NS: " + e.getAttribute("xmlns"));
+ }
+ }
+
+ 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, 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;
+
+ 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);
+ }
+ 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);
+ }
+ }
+ }
+
+ 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/ModelSorter.java b/src/main/java/org/openecomp/modelloader/entity/model/ModelSorter.java index 4dcda71..79f1c29 100644 --- a/src/main/java/org/openecomp/modelloader/entity/model/ModelSorter.java +++ b/src/main/java/org/openecomp/modelloader/entity/model/ModelSorter.java @@ -1,233 +1,235 @@ -/*- - * ============LICENSE_START======================================================= - * MODEL LOADER SERVICE - * ================================================================================ - * Copyright (C) 2017 AT&T Intellectual Property. 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========================================================= - */ - -package org.openecomp.modelloader.entity.model; - -import jline.internal.Log; - -import org.openecomp.modelloader.entity.Artifact; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; - -/** - * Utility class to sort the given Models according to their dependencies. - * Example: Given a list of Models [A, B, C] where B depends on A, and A depends - * on C, the sorted result will be [C, A, B] - */ -public class ModelSorter { - - /** - * Wraps a Model object to form dependencies other Models using Edges. - */ - static class Node { - private final ModelArtifact model; - private final HashSet<Edge> inEdges; - private final HashSet<Edge> outEdges; - - public Node(ModelArtifact model) { - this.model = model; - inEdges = new HashSet<Edge>(); - outEdges = new HashSet<Edge>(); - } - - public Node addEdge(Node node) { - Edge edge = new Edge(this, node); - outEdges.add(edge); - node.inEdges.add(edge); - return this; - } - - @Override - public String toString() { - return model.getNameVersionId(); - } - - @Override - public boolean equals(Object other) { - ModelArtifact otherModel = ((Node) other).model; - return this.model.getNameVersionId().equals(otherModel.getNameVersionId()); - } - - @Override - public int hashCode() { - return this.model.getNameVersionId().hashCode(); - - } - } - - /** - * Represents a dependency between two Nodes. - */ - static class Edge { - public final Node from; - public final Node to; - - public Edge(Node from, Node to) { - this.from = from; - this.to = to; - } - - @Override - public boolean equals(Object obj) { - Edge edge = (Edge) obj; - return edge.from == from && edge.to == to; - } - } - - /** - * Returns the list of models sorted by order of dependency. - * - * @param originalList - * the list that needs to be sorted - * @return a list of sorted models - */ - public List<Artifact> sort(List<Artifact> originalList) { - - if (originalList.size() <= 1) { - return originalList; - } - - Collection<Node> nodes = createNodes(originalList); - Collection<Node> sortedNodes = sortNodes(nodes); - - List<Artifact> sortedModelsList = new ArrayList<Artifact>(sortedNodes.size()); - for (Node node : sortedNodes) { - sortedModelsList.add(node.model); - } - - return sortedModelsList; - } - - /** - * Create nodes from the list of models and their dependencies. - * - * @param models - * what the nodes creation is based upon - * @return Collection of Node objects - */ - private Collection<Node> createNodes(Collection<Artifact> models) { - - // load list of models into a map, so we can later replace referenceIds with - // real Models - HashMap<String, ModelArtifact> versionIdToModelMap = new HashMap<String, ModelArtifact>(); - for (Artifact art : models) { - ModelArtifact ma = (ModelArtifact) art; - versionIdToModelMap.put(ma.getNameVersionId(), 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; - - // node might have been created by another model referencing it - Node node = nodes.get(model.getNameVersionId()); - - if (null == node) { - node = new Node(model); - nodes.put(model.getNameVersionId(), node); - } - - for (String referencedModelId : model.getDependentModelIds()) { - // node might have been created by another model referencing it - Node referencedNode = nodes.get(referencedModelId); - - if (null == referencedNode) { - // create node - ModelArtifact referencedModel = versionIdToModelMap.get(referencedModelId); - if (referencedModel == null) { - Log.debug("ignoring " + referencedModelId); - continue; // referenced model not supplied, no need to sort it - } - referencedNode = new Node(referencedModel); - nodes.put(referencedModelId, referencedNode); - } - referencedNode.addEdge(node); - } - } - - return nodes.values(); - } - - /** - * Sorts the given Nodes by order of dependency. - * - * @param originalList - * the collection of nodes to be sorted - * @return a sorted collection of the given nodes - */ - private Collection<Node> sortNodes(Collection<Node> unsortedNodes) { - - // L <- Empty list that will contain the sorted elements - ArrayList<Node> nodeList = new ArrayList<Node>(); - - // S <- Set of all nodes with no incoming edges - HashSet<Node> nodeSet = new HashSet<Node>(); - for (Node unsortedNode : unsortedNodes) { - if (unsortedNode.inEdges.size() == 0) { - nodeSet.add(unsortedNode); - } - } - - // while S is non-empty do - while (!nodeSet.isEmpty()) { - // remove a node n from S - Node node = nodeSet.iterator().next(); - nodeSet.remove(node); - - // insert n into L - nodeList.add(node); - - // for each node m with an edge e from n to m do - for (Iterator<Edge> it = node.outEdges.iterator(); it.hasNext();) { - // remove edge e from the graph - Edge edge = it.next(); - Node to = edge.to; - it.remove();// Remove edge from n - to.inEdges.remove(edge);// Remove edge from m - - // if m has no other incoming edges then insert m into S - if (to.inEdges.isEmpty()) { - nodeSet.add(to); - } - } - } - // Check to see if all edges are removed - boolean cycle = false; - for (Node node : unsortedNodes) { - if (!node.inEdges.isEmpty()) { - cycle = true; - break; - } - } - if (cycle) { - throw new RuntimeException( - "Circular dependency present between models, topological sort not possible"); - } - - return nodeList; - } - -} +/**
+ * ============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 jline.internal.Log;
+
+import org.openecomp.modelloader.entity.Artifact;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Utility class to sort the given Models according to their dependencies.
+ * Example: Given a list of Models [A, B, C] where B depends on A, and A depends
+ * on C, the sorted result will be [C, A, B]
+ */
+public class ModelSorter {
+
+ /**
+ * Wraps a Model object to form dependencies other Models using Edges.
+ */
+ static class Node {
+ private final ModelArtifact model;
+ private final HashSet<Edge> inEdges;
+ private final HashSet<Edge> outEdges;
+
+ public Node(ModelArtifact model) {
+ this.model = model;
+ inEdges = new HashSet<Edge>();
+ outEdges = new HashSet<Edge>();
+ }
+
+ public Node addEdge(Node node) {
+ Edge edge = new Edge(this, node);
+ outEdges.add(edge);
+ node.inEdges.add(edge);
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return model.getModelInvariantId();
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ ModelArtifact otherModel = ((Node) other).model;
+ return this.model.getModelInvariantId().equals(otherModel.getModelInvariantId());
+ }
+
+ @Override
+ public int hashCode() {
+ return this.model.getModelInvariantId().hashCode();
+
+ }
+ }
+
+ /**
+ * Represents a dependency between two Nodes.
+ */
+ static class Edge {
+ public final Node from;
+ public final Node to;
+
+ public Edge(Node from, Node to) {
+ this.from = from;
+ this.to = to;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ Edge edge = (Edge) obj;
+ return edge.from == from && edge.to == to;
+ }
+ }
+
+ /**
+ * Returns the list of models sorted by order of dependency.
+ *
+ * @param originalList
+ * the list that needs to be sorted
+ * @return a list of sorted models
+ */
+ public List<Artifact> sort(List<Artifact> originalList) {
+
+ if (originalList.size() <= 1) {
+ return originalList;
+ }
+
+ Collection<Node> nodes = createNodes(originalList);
+ Collection<Node> sortedNodes = sortNodes(nodes);
+
+ List<Artifact> sortedModelsList = new ArrayList<Artifact>(sortedNodes.size());
+ for (Node node : sortedNodes) {
+ sortedModelsList.add(node.model);
+ }
+
+ return sortedModelsList;
+ }
+
+ /**
+ * Create nodes from the list of models and their dependencies.
+ *
+ * @param models
+ * what the nodes creation is based upon
+ * @return Collection of Node objects
+ */
+ private Collection<Node> createNodes(Collection<Artifact> models) {
+
+ // load list of models into a map, so we can later replace referenceIds with
+ // real Models
+ HashMap<String, ModelArtifact> versionIdToModelMap = new HashMap<String, ModelArtifact>();
+ for (Artifact art : models) {
+ ModelArtifact ma = (ModelArtifact) art;
+ versionIdToModelMap.put(ma.getModelModelVerCombinedKey(), 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;
+
+ // node might have been created by another model referencing it
+ Node node = nodes.get(model.getModelModelVerCombinedKey());
+
+ if (null == node) {
+ node = new Node(model);
+ nodes.put(model.getModelModelVerCombinedKey(), node);
+ }
+
+ for (String referencedModelId : model.getDependentModelIds()) {
+ // node might have been created by another model referencing it
+ Node referencedNode = nodes.get(referencedModelId);
+
+ if (null == referencedNode) {
+ // create node
+ ModelArtifact referencedModel = versionIdToModelMap.get(referencedModelId);
+ if (referencedModel == null) {
+ Log.debug("ignoring " + referencedModelId);
+ continue; // referenced model not supplied, no need to sort it
+ }
+ referencedNode = new Node(referencedModel);
+ nodes.put(referencedModelId, referencedNode);
+ }
+ referencedNode.addEdge(node);
+ }
+ }
+
+ return nodes.values();
+ }
+
+ /**
+ * Sorts the given Nodes by order of dependency.
+ *
+ * @param originalList
+ * the collection of nodes to be sorted
+ * @return a sorted collection of the given nodes
+ */
+ private Collection<Node> sortNodes(Collection<Node> unsortedNodes) {
+
+ // L <- Empty list that will contain the sorted elements
+ ArrayList<Node> nodeList = new ArrayList<Node>();
+
+ // S <- Set of all nodes with no incoming edges
+ HashSet<Node> nodeSet = new HashSet<Node>();
+ for (Node unsortedNode : unsortedNodes) {
+ if (unsortedNode.inEdges.size() == 0) {
+ nodeSet.add(unsortedNode);
+ }
+ }
+
+ // while S is non-empty do
+ while (!nodeSet.isEmpty()) {
+ // remove a node n from S
+ Node node = nodeSet.iterator().next();
+ nodeSet.remove(node);
+
+ // insert n into L
+ nodeList.add(node);
+
+ // for each node m with an edge e from n to m do
+ for (Iterator<Edge> it = node.outEdges.iterator(); it.hasNext();) {
+ // remove edge e from the graph
+ Edge edge = it.next();
+ Node to = edge.to;
+ it.remove();// Remove edge from n
+ to.inEdges.remove(edge);// Remove edge from m
+
+ // if m has no other incoming edges then insert m into S
+ if (to.inEdges.isEmpty()) {
+ nodeSet.add(to);
+ }
+ }
+ }
+ // Check to see if all edges are removed
+ boolean cycle = false;
+ for (Node node : unsortedNodes) {
+ if (!node.inEdges.isEmpty()) {
+ cycle = true;
+ break;
+ }
+ }
+ if (cycle) {
+ throw new RuntimeException(
+ "Circular dependency present between models, topological sort not possible");
+ }
+
+ return nodeList;
+ }
+
+}
|