summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsblimkie <sb787e@att.com>2018-11-26 16:56:06 -0500
committersblimkie <steven.blimkie@amdocs.com>2018-11-27 11:33:38 -0500
commit270656abb1ed24930b2f9e57f5bef659494f5e8e (patch)
tree0e9d53cd0eabf5c6aa7d3beac36474a861761a73
parent5209f42102348d19a389017c1717f0edc3733b36 (diff)
Configurable option to load models via Gizmo
Change-Id: I792e1a0db166ccab84f42a2d1beb92d7a630165b Issue-ID: AAI-1957 Signed-off-by: sblimkie <steven.blimkie@amdocs.com>
-rw-r--r--src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java11
-rw-r--r--src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifact.java40
-rw-r--r--src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java37
-rw-r--r--src/main/java/org/onap/aai/modelloader/entity/model/NamedQueryArtifact.java36
-rw-r--r--src/main/java/org/onap/aai/modelloader/gizmo/GizmoBulkPayload.java112
-rw-r--r--src/main/java/org/onap/aai/modelloader/gizmo/GizmoEdge.java68
-rw-r--r--src/main/java/org/onap/aai/modelloader/gizmo/GizmoEdgeOperation.java90
-rw-r--r--src/main/java/org/onap/aai/modelloader/gizmo/GizmoVertex.java71
-rw-r--r--src/main/java/org/onap/aai/modelloader/gizmo/GizmoVertexOperation.java94
-rw-r--r--src/main/java/org/onap/aai/modelloader/restclient/AaiRestClient.java4
-rw-r--r--src/main/java/org/onap/aai/modelloader/util/GizmoTranslator.java288
-rw-r--r--src/test/java/org/onap/aai/modelloader/util/GizmoTranslatorTest.java116
12 files changed, 936 insertions, 31 deletions
diff --git a/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java b/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java
index 01505ba..6a45f28 100644
--- a/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java
+++ b/src/main/java/org/onap/aai/modelloader/config/ModelLoaderConfig.java
@@ -81,6 +81,7 @@ public class ModelLoaderConfig implements IConfiguration {
protected static final String PROP_AAI_VNF_IMAGE_RESOURCE_URL = PREFIX_AAI + "VNF_IMAGE_URL";
protected static final String PROP_AAI_AUTHENTICATION_USER = PREFIX_AAI + "AUTH_USER";
protected static final String PROP_AAI_AUTHENTICATION_PASSWORD = PREFIX_AAI + "AUTH_PASSWORD";
+ protected static final String PROP_AAI_USE_GIZMO = PREFIX_AAI + "USE_GIZMO";
protected static final String PROP_BABEL_BASE_URL = PREFIX_BABEL + "BASE_URL";
protected static final String PROP_BABEL_KEYSTORE_FILE = PREFIX_BABEL + SUFFIX_KEYSTORE_FILE;
@@ -289,6 +290,16 @@ public class ModelLoaderConfig implements IConfiguration {
this.modelVersion = modelVersion;
}
+ public boolean useGizmo() {
+ String useGizmo = modelLoaderProperties.getProperty(PROP_AAI_USE_GIZMO);
+
+ if ( (useGizmo == null) || (!useGizmo.equalsIgnoreCase("true")) ) {
+ return false;
+ }
+
+ return true;
+ }
+
/**
* @return password for AAI authentication that has been reverse-engineered from its obfuscated form.
*/
diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifact.java b/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifact.java
index 35c672a..f310ae3 100644
--- a/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifact.java
+++ b/src/main/java/org/onap/aai/modelloader/entity/model/AbstractModelArtifact.java
@@ -1,5 +1,5 @@
/**
- * ============LICENSE_START=======================================================
+ * ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
* Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
@@ -23,13 +23,25 @@ package org.onap.aai.modelloader.entity.model;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
+
+import javax.ws.rs.core.MediaType;
+
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
import org.onap.aai.modelloader.config.ModelLoaderConfig;
import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.restclient.AaiRestClient;
+import org.onap.aai.modelloader.service.ModelLoaderMsgs;
+import org.onap.aai.modelloader.util.GizmoTranslator;
+import org.onap.aai.restclient.client.OperationResult;
+import org.springframework.http.HttpStatus;
+
public abstract class AbstractModelArtifact extends Artifact implements IModelArtifact {
+ private static Logger logger = LoggerFactory.getInstance().getLogger(AbstractModelArtifact.class.getName());
+
private String modelNamespace;
private String modelNamespaceVersion;
private Set<String> referencedModelIds = new HashSet<>();
@@ -71,6 +83,32 @@ public abstract class AbstractModelArtifact extends Artifact implements IModelAr
public abstract void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId);
+ protected boolean pushToGizmo(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List<Artifact> completedArtifacts) {
+ try {
+ String gizmoPayload = GizmoTranslator.translate(getPayload());
+ OperationResult postResponse =
+ aaiClient.postResource(config.getAaiBaseUrl().trim(), gizmoPayload, distId, MediaType.APPLICATION_JSON_TYPE);
+
+ if (postResponse.getResultCode() != HttpStatus.OK.value()) {
+ return false;
+ }
+
+ } catch (Exception e) {
+ logErrorMsg("Ingest failed for " + getType().toString() + " " + getUniqueIdentifier() + ": " + e.getMessage());
+ return false;
+ }
+
+ return true;
+ }
+
+ protected void logInfoMsg(String infoMsg) {
+ logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, infoMsg);
+ }
+
+ protected void logErrorMsg(String errorMsg) {
+ logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, errorMsg);
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java
index 705ceb5..175f858 100644
--- a/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java
+++ b/src/main/java/org/onap/aai/modelloader/entity/model/ModelArtifact.java
@@ -1,5 +1,5 @@
/**
- * ============LICENSE_START=======================================================
+ * ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
* Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
@@ -31,16 +31,16 @@ import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
-import org.onap.aai.cl.api.Logger;
-import org.onap.aai.cl.eelf.LoggerFactory;
+
import org.onap.aai.modelloader.config.ModelLoaderConfig;
-import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.restclient.AaiRestClient;
-import org.onap.aai.modelloader.service.ModelLoaderMsgs;
+import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.restclient.client.OperationResult;
+
import org.w3c.dom.Node;
+
public class ModelArtifact extends AbstractModelArtifact {
private static final String AAI_MODEL_VER_SUB_URL = "/model-vers/model-ver";
@@ -48,7 +48,6 @@ public class ModelArtifact extends AbstractModelArtifact {
private static final String FAILURE_MSG_PREFIX = "Ingestion failed for ";
private static final String ROLLBACK_MSG_SUFFIX = ". Rolling back distribution.";
- private static Logger logger = LoggerFactory.getInstance().getLogger(ModelArtifact.class.getName());
private String modelVerId;
private String modelInvariantId;
@@ -119,6 +118,15 @@ public class ModelArtifact extends AbstractModelArtifact {
@Override
public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ List<Artifact> completedArtifacts) {
+ if (config.useGizmo()) {
+ return pushToGizmo(aaiClient, config, distId, completedArtifacts);
+ }
+
+ return pushToResources(aaiClient, config, distId, completedArtifacts);
+ }
+
+ private boolean pushToResources(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
List<Artifact> completedArtifacts) {
boolean success;
@@ -145,7 +153,7 @@ public class ModelArtifact extends AbstractModelArtifact {
}
return success;
- }
+ }
/**
* @param aaiClient
@@ -184,6 +192,12 @@ public class ModelArtifact extends AbstractModelArtifact {
@Override
public void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) {
+ // Gizmo is resilient and doesn't require a rollback. A redistribution will work fine even if
+ // the model is partially loaded.
+ if (config.useGizmo()) {
+ return;
+ }
+
String url = getModelVerUrl(config);
if (firstVersionOfModel) {
// If this was the first version of the model which was added, we want to remove the entire
@@ -195,15 +209,6 @@ public class ModelArtifact extends AbstractModelArtifact {
aaiClient.getAndDeleteResource(url, distId);
}
-
- private void logInfoMsg(String infoMsg) {
- logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT, infoMsg);
- }
-
- private void logErrorMsg(String errorMsg) {
- logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, errorMsg);
- }
-
private String getModelUrl(ModelLoaderConfig config) {
String baseURL = config.getAaiBaseUrl().trim();
String subURL = config.getAaiModelUrl(getModelNamespaceVersion()).trim();
diff --git a/src/main/java/org/onap/aai/modelloader/entity/model/NamedQueryArtifact.java b/src/main/java/org/onap/aai/modelloader/entity/model/NamedQueryArtifact.java
index a8fdc8e..ba5d12b 100644
--- a/src/main/java/org/onap/aai/modelloader/entity/model/NamedQueryArtifact.java
+++ b/src/main/java/org/onap/aai/modelloader/entity/model/NamedQueryArtifact.java
@@ -1,5 +1,5 @@
/**
- * ============LICENSE_START=======================================================
+ * ============LICENSE_START=======================================================
* org.onap.aai
* ================================================================================
* Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
@@ -23,18 +23,16 @@ package org.onap.aai.modelloader.entity.model;
import java.util.List;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
-import org.onap.aai.cl.api.Logger;
-import org.onap.aai.cl.eelf.LoggerFactory;
+
import org.onap.aai.modelloader.config.ModelLoaderConfig;
-import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.modelloader.entity.ArtifactType;
import org.onap.aai.modelloader.restclient.AaiRestClient;
-import org.onap.aai.modelloader.service.ModelLoaderMsgs;
+
+import org.onap.aai.modelloader.entity.Artifact;
import org.onap.aai.restclient.client.OperationResult;
-public class NamedQueryArtifact extends AbstractModelArtifact {
- private Logger logger = LoggerFactory.getInstance().getLogger(NamedQueryArtifact.class.getName());
+public class NamedQueryArtifact extends AbstractModelArtifact {
private String namedQueryUuid;
@@ -56,7 +54,15 @@ public class NamedQueryArtifact extends AbstractModelArtifact {
}
@Override
- public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
+ public boolean push(AaiRestClient aaiClient, ModelLoaderConfig config, String distId, List<Artifact> completedArtifacts) {
+ if (config.useGizmo()) {
+ return pushToGizmo(aaiClient, config, distId, completedArtifacts);
+ }
+
+ return pushToResources(aaiClient, config, distId, completedArtifacts);
+ }
+
+ private boolean pushToResources(AaiRestClient aaiClient, ModelLoaderConfig config, String distId,
List<Artifact> completedArtifacts) {
OperationResult getResponse =
aaiClient.getResource(getNamedQueryUrl(config), distId, MediaType.APPLICATION_XML_TYPE);
@@ -66,16 +72,14 @@ public class NamedQueryArtifact extends AbstractModelArtifact {
MediaType.APPLICATION_XML_TYPE);
if (putResponse != null && putResponse.getResultCode() == Response.Status.CREATED.getStatusCode()) {
completedArtifacts.add(this);
- logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
- getType().toString() + " " + getUniqueIdentifier() + " successfully ingested.");
+ logInfoMsg(getType().toString() + " " + getUniqueIdentifier() + " successfully ingested.");
} else {
- logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Ingestion failed for " + getType().toString()
+ logErrorMsg("Ingestion failed for " + getType().toString()
+ " " + getUniqueIdentifier() + ". Rolling back distribution.");
return false;
}
} else {
- logger.info(ModelLoaderMsgs.DISTRIBUTION_EVENT,
- getType().toString() + " " + getUniqueIdentifier() + " already exists. Skipping ingestion.");
+ logInfoMsg(getType().toString() + " " + getUniqueIdentifier() + " already exists. Skipping ingestion.");
}
return true;
@@ -83,6 +87,12 @@ public class NamedQueryArtifact extends AbstractModelArtifact {
@Override
public void rollbackModel(AaiRestClient aaiClient, ModelLoaderConfig config, String distId) {
+ // Gizmo is resilient and doesn't require a rollback. A redistribution will work fine even if
+ // the model is partially loaded.
+ if (config.useGizmo()) {
+ return;
+ }
+
// Best effort to delete. Nothing we can do in the event this fails.
aaiClient.getAndDeleteResource(getNamedQueryUrl(config), distId);
}
diff --git a/src/main/java/org/onap/aai/modelloader/gizmo/GizmoBulkPayload.java b/src/main/java/org/onap/aai/modelloader/gizmo/GizmoBulkPayload.java
new file mode 100644
index 0000000..11aa35d
--- /dev/null
+++ b/src/main/java/org/onap/aai/modelloader/gizmo/GizmoBulkPayload.java
@@ -0,0 +1,112 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.onap.aai.modelloader.gizmo;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonElement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GizmoBulkPayload {
+
+ public static final String ADD_OP = "add";
+ public static final String UPDATE_OP = "modify";
+ public static final String DELETE_OP = "delete";
+ public static final String PATCH_OP = "patch";
+ public static final String EXISTS_OP = "exists";
+ public static final String ALL_OPS = "all";
+ public static final String OP_KEY = "operation";
+
+
+ private List<JsonElement> objects = new ArrayList<JsonElement>();
+ private List<JsonElement> relationships = new ArrayList<JsonElement>();
+
+ private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create();
+
+ public String toJson() {
+ return gson.toJson(this);
+ }
+
+ public static GizmoBulkPayload fromJson(String payload) {
+ return gson.fromJson(payload, GizmoBulkPayload.class);
+ }
+
+ public List<JsonElement> getObjects() {
+ return objects;
+ }
+
+ public void setObjects(List<JsonElement> objects) {
+ this.objects = objects;
+ }
+
+ public List<JsonElement> getRelationships() {
+ return relationships;
+ }
+
+ public void setRelationships(List<JsonElement> relationships) {
+ this.relationships = relationships;
+ }
+
+ public List<GizmoVertexOperation> getVertexOperations() {
+ return getVertexOperations(ALL_OPS);
+ }
+
+ public List<GizmoVertexOperation> getVertexOperations(String opType) {
+ List<GizmoVertexOperation> ops = new ArrayList<GizmoVertexOperation>();
+ for (JsonElement v : getObjects()) {
+ GizmoVertexOperation op = GizmoVertexOperation.fromJsonElement(v);
+
+ if ( (opType.equalsIgnoreCase(ALL_OPS)) || (op.getOperation().equalsIgnoreCase(opType)) ) {
+ ops.add(op);
+ }
+ }
+
+ return ops;
+ }
+
+ public void addVertexOperation(GizmoVertexOperation newOp) {
+ objects.add(newOp.toJsonElement());
+ }
+
+ public List<GizmoEdgeOperation> getEdgeOperations() {
+ return getEdgeOperations(ALL_OPS);
+ }
+
+ public List<GizmoEdgeOperation> getEdgeOperations(String opType) {
+ List<GizmoEdgeOperation> ops = new ArrayList<GizmoEdgeOperation>();
+
+ for (JsonElement v : getRelationships()) {
+ GizmoEdgeOperation op = GizmoEdgeOperation.fromJsonElement(v);
+
+ if ( (opType.equalsIgnoreCase(ALL_OPS)) || (op.getOperation().equalsIgnoreCase(opType)) ) {
+ ops.add(op);
+ }
+ }
+
+ return ops;
+ }
+
+ public void addEdgeOperation(GizmoEdgeOperation newOp) {
+ relationships.add(newOp.toJsonElement());
+ }
+}
diff --git a/src/main/java/org/onap/aai/modelloader/gizmo/GizmoEdge.java b/src/main/java/org/onap/aai/modelloader/gizmo/GizmoEdge.java
new file mode 100644
index 0000000..3e1e602
--- /dev/null
+++ b/src/main/java/org/onap/aai/modelloader/gizmo/GizmoEdge.java
@@ -0,0 +1,68 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.onap.aai.modelloader.gizmo;
+
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+
+public class GizmoEdge {
+ private static final Gson gson = new GsonBuilder().create();
+
+ private String type;
+ private String source;
+ private String target;
+
+ public String toJson() {
+ return gson.toJson(this);
+ }
+
+ public static GizmoEdge fromJson(String jsonString) {
+ return gson.fromJson(jsonString, GizmoEdge.class);
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getSource() {
+ return source;
+ }
+
+ public void setSource(String source) {
+ this.source = source;
+ }
+
+ public String getTarget() {
+ return target;
+ }
+
+ public void setTarget(String target) {
+ this.target = target;
+ }
+
+}
+
diff --git a/src/main/java/org/onap/aai/modelloader/gizmo/GizmoEdgeOperation.java b/src/main/java/org/onap/aai/modelloader/gizmo/GizmoEdgeOperation.java
new file mode 100644
index 0000000..eb578b5
--- /dev/null
+++ b/src/main/java/org/onap/aai/modelloader/gizmo/GizmoEdgeOperation.java
@@ -0,0 +1,90 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.onap.aai.modelloader.gizmo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+public class GizmoEdgeOperation {
+ private String operation;
+ private String internalId;
+ private GizmoEdge edge;
+
+ public GizmoEdgeOperation(String op, String id, GizmoEdge edge) {
+ this.operation = op;
+ this.internalId = id;
+ this.edge = edge;
+ }
+
+ public JsonElement toJsonElement() {
+ JsonObject opObj = new JsonObject();
+ JsonParser parser = new JsonParser();
+ JsonObject edgeObj = parser.parse(edge.toJson()).getAsJsonObject();
+
+ opObj.addProperty(GizmoBulkPayload.OP_KEY, operation);
+ opObj.add(internalId, edgeObj);
+
+ return opObj;
+ }
+
+ public static GizmoEdgeOperation fromJsonElement(JsonElement element) {
+ List<Map.Entry<String, JsonElement>> entries =
+ new ArrayList<Map.Entry<String, JsonElement>>(element.getAsJsonObject().entrySet());
+
+ String op = null;
+ String id = null;
+ GizmoEdge edge = null;
+
+ for (Map.Entry<String, JsonElement> entry : entries) {
+ if (entry.getKey().equalsIgnoreCase(GizmoBulkPayload.OP_KEY)) {
+ op = entry.getValue().getAsString();
+ }
+ else {
+ id = entry.getKey();
+ edge = GizmoEdge.fromJson(entry.getValue().getAsJsonObject().toString());
+ }
+ }
+
+ if (op == null) {
+ // Use default
+ op = GizmoBulkPayload.EXISTS_OP;
+ }
+
+ return new GizmoEdgeOperation(op, id, edge);
+ }
+
+ public String getOperation() {
+ return operation;
+ }
+
+ public String getInternalId() {
+ return internalId;
+ }
+
+ public GizmoEdge getEdge() {
+ return edge;
+ }
+}
diff --git a/src/main/java/org/onap/aai/modelloader/gizmo/GizmoVertex.java b/src/main/java/org/onap/aai/modelloader/gizmo/GizmoVertex.java
new file mode 100644
index 0000000..9de94cd
--- /dev/null
+++ b/src/main/java/org/onap/aai/modelloader/gizmo/GizmoVertex.java
@@ -0,0 +1,71 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.onap.aai.modelloader.gizmo;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+
+public class GizmoVertex {
+ private static final Gson gson = new GsonBuilder().create();
+
+ private String type;
+ private Map<String, String> properties;
+
+ public String toJson() {
+ return gson.toJson(this);
+ }
+
+ public static GizmoVertex fromJson(String jsonString) {
+ return gson.fromJson(jsonString, GizmoVertex.class);
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public Map<String, String> getProperties() {
+ return properties;
+ }
+
+ public String getProperty(String key) {
+ return properties.get(key);
+ }
+
+ public void setProperties(Map<String, String> properties) {
+ this.properties = properties;
+ }
+
+ public void setProperty(String key, String value) {
+ if (properties == null) {
+ properties = new HashMap<String,String>();
+ }
+
+ properties.put(key, value);
+ }
+
+}
diff --git a/src/main/java/org/onap/aai/modelloader/gizmo/GizmoVertexOperation.java b/src/main/java/org/onap/aai/modelloader/gizmo/GizmoVertexOperation.java
new file mode 100644
index 0000000..3adc284
--- /dev/null
+++ b/src/main/java/org/onap/aai/modelloader/gizmo/GizmoVertexOperation.java
@@ -0,0 +1,94 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.onap.aai.modelloader.gizmo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+
+public class GizmoVertexOperation {
+ private String operation;
+ private String internalId;
+ private GizmoVertex vertex;
+
+ public GizmoVertexOperation(String op, String id, GizmoVertex vertex) {
+ this.operation = op;
+ this.internalId = id;
+ this.vertex = vertex;
+ }
+
+ public JsonElement toJsonElement() {
+ JsonObject opObj = new JsonObject();
+ JsonParser parser = new JsonParser();
+ JsonObject vertexObj = parser.parse(vertex.toJson()).getAsJsonObject();
+
+ opObj.addProperty(GizmoBulkPayload.OP_KEY, getOperation());
+ opObj.add(internalId, vertexObj);
+
+ return opObj;
+ }
+
+ public static GizmoVertexOperation fromJsonElement(JsonElement element) {
+ List<Map.Entry<String, JsonElement>> entries =
+ new ArrayList<Map.Entry<String, JsonElement>>(element.getAsJsonObject().entrySet());
+
+ String op = null;
+ String id = null;
+ GizmoVertex vertex = null;
+
+ for (Map.Entry<String, JsonElement> entry : entries) {
+ if (entry.getKey().equalsIgnoreCase(GizmoBulkPayload.OP_KEY)) {
+ op = entry.getValue().getAsString();
+ }
+ else {
+ id = entry.getKey();
+ vertex = GizmoVertex.fromJson(entry.getValue().getAsJsonObject().toString());
+ }
+ }
+
+ if (op == null) {
+ // Use default
+ op = GizmoBulkPayload.EXISTS_OP;
+ }
+
+ return new GizmoVertexOperation(op, id, vertex);
+ }
+
+ public String getOperation() {
+ return operation;
+ }
+
+ public void setOperation(String op) {
+ operation = op;
+ }
+
+ public String getInternalId() {
+ return internalId;
+ }
+
+ public GizmoVertex getVertex() {
+ return vertex;
+ }
+}
diff --git a/src/main/java/org/onap/aai/modelloader/restclient/AaiRestClient.java b/src/main/java/org/onap/aai/modelloader/restclient/AaiRestClient.java
index 27db741..a2a4c5b 100644
--- a/src/main/java/org/onap/aai/modelloader/restclient/AaiRestClient.java
+++ b/src/main/java/org/onap/aai/modelloader/restclient/AaiRestClient.java
@@ -161,7 +161,9 @@ public class AaiRestClient {
restClient.validateServerHostname(false)
.validateServerCertChain(false)
.clientCertFile(config.getAaiKeyStorePath())
- .clientCertPassword(config.getAaiKeyStorePassword());
+ .clientCertPassword(config.getAaiKeyStorePassword())
+ .connectTimeoutMs(120000)
+ .readTimeoutMs(120000);
// @formatter:on
if (useBasicAuth()) {
diff --git a/src/main/java/org/onap/aai/modelloader/util/GizmoTranslator.java b/src/main/java/org/onap/aai/modelloader/util/GizmoTranslator.java
new file mode 100644
index 0000000..69e5971
--- /dev/null
+++ b/src/main/java/org/onap/aai/modelloader/util/GizmoTranslator.java
@@ -0,0 +1,288 @@
+/**
+ * ============LICENSE_START==========================================
+ * org.onap.aai
+ * ===================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 Amdocs
+ * ===================================================================
+ * 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.onap.aai.modelloader.util;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.onap.aai.cl.api.Logger;
+import org.onap.aai.cl.eelf.LoggerFactory;
+import org.onap.aai.modelloader.gizmo.GizmoBulkPayload;
+import org.onap.aai.modelloader.gizmo.GizmoEdge;
+import org.onap.aai.modelloader.gizmo.GizmoEdgeOperation;
+import org.onap.aai.modelloader.gizmo.GizmoVertex;
+import org.onap.aai.modelloader.gizmo.GizmoVertexOperation;
+import org.onap.aai.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 org.xml.sax.SAXException;
+
+public class GizmoTranslator {
+
+ private enum NodeType {
+ VERTEX,
+ ATTRIBUTE,
+ CONTAINER,
+ RELATIONSHIP_LIST,
+ RELATIONSHIP,
+ RELATED_TO,
+ RELATIONSHIP_DATA,
+ RELATIONSHIP_KEY,
+ RELATIONSHIP_VALUE,
+ MODEL_ELEMENT_VERTEX,
+ NQ_ELEMENT_VERTEX,
+ UNKNOWN
+ }
+
+ private static Logger logger = LoggerFactory.getInstance().getLogger(GizmoTranslator.class.getName());
+
+ public static String translate(String xmlPayload) throws ParserConfigurationException, SAXException, IOException {
+ DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
+ DocumentBuilder builder = factory.newDocumentBuilder();
+ InputSource is = new InputSource(new StringReader(xmlPayload));
+ Document doc = builder.parse(is);
+
+ GizmoBulkPayload gizmoPayload = new GizmoBulkPayload();
+
+ processNode(doc.getDocumentElement(), null, null, gizmoPayload);
+
+ return gizmoPayload.toJson();
+ }
+
+ private static void processNode(Node node, Node parentNode, GizmoVertexOperation parentVertexOp, GizmoBulkPayload gizmoPayload) {
+ if (!(node instanceof Element)) {
+ return;
+ }
+
+ Node newParent = null;
+ NodeType nodeType = getNodeType(node);
+
+ switch (nodeType) {
+ case VERTEX:
+ case MODEL_ELEMENT_VERTEX:
+ case NQ_ELEMENT_VERTEX:
+ parentVertexOp = createGizmoVertexOp(node, GizmoBulkPayload.ADD_OP);
+ gizmoPayload.addVertexOperation(parentVertexOp);
+ if (parentNode != null) {
+ gizmoPayload.addEdgeOperation(createGizmoEdgeOp(node, parentNode));
+ }
+ newParent = node;
+ break;
+ case RELATIONSHIP:
+ processRelationship((Element)node, parentVertexOp, gizmoPayload);
+ newParent = parentNode;
+ break;
+ default:
+ newParent = parentNode;
+ break;
+ }
+
+ NodeList childNodes = node.getChildNodes();
+ for (int ix = 0; ix < childNodes.getLength(); ix++) {
+ processNode(childNodes.item(ix), newParent, parentVertexOp, gizmoPayload);
+ }
+ }
+
+ private static void processRelationship(Element relationshipNode, GizmoVertexOperation sourceNode, GizmoBulkPayload gizmoPayload) {
+ NodeList relatedToList = relationshipNode.getElementsByTagName("related-to");
+ if (relatedToList.getLength() != 1) {
+ logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Unable to resolve relationship");
+ return;
+ }
+
+ GizmoVertex targetVertex = new GizmoVertex();
+ targetVertex.setType(relatedToList.item(0).getTextContent().trim());
+
+ NodeList relationData = relationshipNode.getElementsByTagName("relationship-data");
+ for (int ix = 0; ix < relationData.getLength(); ix++) {
+ Element relationNode = (Element)relationData.item(ix);
+ NodeList keyList = relationNode.getElementsByTagName("relationship-key");
+ NodeList valueList = relationNode.getElementsByTagName("relationship-value");
+
+ if ( (keyList.getLength() != 1) || (valueList.getLength() != 1) ) {
+ logger.error(ModelLoaderMsgs.DISTRIBUTION_EVENT_ERROR, "Unable to resolve relationship. Missing key/value.");
+ return;
+ }
+
+ String[] keyBits = keyList.item(0).getTextContent().trim().split("\\.");
+ String value = valueList.item(0).getTextContent().trim();
+
+ if (keyBits[0].equalsIgnoreCase(targetVertex.getType())) {
+ targetVertex.setProperty(keyBits[1], value);
+ }
+ }
+
+ gizmoPayload.addVertexOperation(new GizmoVertexOperation(GizmoBulkPayload.EXISTS_OP, getVertexId(targetVertex), targetVertex));
+
+ GizmoEdge edge = new GizmoEdge();
+
+ edge.setSource("$" + getVertexId(sourceNode.getVertex()));
+ edge.setTarget("$" + getVertexId(targetVertex));
+
+ gizmoPayload.addEdgeOperation(new GizmoEdgeOperation(GizmoBulkPayload.ADD_OP, edge.getSource() + "_" + edge.getTarget(), edge));
+ }
+
+ private static GizmoEdgeOperation createGizmoEdgeOp(Node node, Node parentNode) {
+ GizmoEdge edge = new GizmoEdge();
+
+ edge.setSource("$" + getVertexId(createGizmoVertex(node)));
+ edge.setTarget("$" + getVertexId(createGizmoVertex(parentNode)));
+
+ GizmoEdgeOperation edgeOp = new GizmoEdgeOperation(GizmoBulkPayload.ADD_OP, edge.getSource() + "_" + edge.getTarget(), edge);
+
+ return edgeOp;
+ }
+
+ private static GizmoVertexOperation createGizmoVertexOp(Node node, String operationType) {
+ GizmoVertex vertex = createGizmoVertex(node);
+ GizmoVertexOperation addOp = new GizmoVertexOperation(operationType, getVertexId(vertex), vertex);
+ return addOp;
+ }
+
+ private static String getVertexId(GizmoVertex vertex) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(vertex.getType());
+ for (Map.Entry<String, String> entry : vertex.getProperties().entrySet()) {
+ sb.append("-" + entry.getValue());
+ }
+
+ return sb.toString();
+ }
+
+ private static GizmoVertex createGizmoVertex(Node node) {
+ GizmoVertex vertex = new GizmoVertex();
+ vertex.setType(node.getNodeName().trim());
+
+ NodeList childNodes = node.getChildNodes();
+
+ for (int ix = 0; ix < childNodes.getLength(); ix++) {
+ if (getNodeType(childNodes.item(ix)).equals(NodeType.ATTRIBUTE)) {
+ vertex.setProperty(childNodes.item(ix).getNodeName().trim(), childNodes.item(ix).getTextContent().trim());
+ }
+ }
+
+ // Special case for model-element, where we need to generate an id field
+ if (getNodeType(node).equals(NodeType.MODEL_ELEMENT_VERTEX)) {
+ vertex.setProperty("model-element-uuid", generateModelElementId((Element)node));
+ }
+
+ // Special case for nq-element, where we need to generate an id field
+ if (getNodeType(node).equals(NodeType.NQ_ELEMENT_VERTEX)) {
+ vertex.setProperty("named-query-element-uuid", generateModelElementId((Element)node));
+ }
+
+ return vertex;
+ }
+
+ // Generate a unique hash to store as the id for this node
+ private static String generateModelElementId(Element node) {
+ Set<String> elemSet = new HashSet<String>();
+
+ NodeList childNodes = node.getElementsByTagName("*");
+ for (int ix = 0; ix < childNodes.getLength(); ix++) {
+ NodeType nt = getNodeType(childNodes.item(ix));
+ if ( nt.equals(NodeType.ATTRIBUTE) || nt.equals(NodeType.RELATIONSHIP_KEY) || nt.equals(NodeType.RELATIONSHIP_VALUE) ) {
+ elemSet.add(childNodes.item(ix).getTextContent().trim());
+ }
+ }
+
+ return Integer.toString(elemSet.hashCode());
+ }
+
+ private static NodeType getNodeType(Node node) {
+ if (!(node instanceof Element)) {
+ return NodeType.UNKNOWN;
+ }
+
+ if (node.getNodeName().equalsIgnoreCase("relationship-list")) {
+ return NodeType.RELATIONSHIP_LIST;
+ }
+
+ if (node.getNodeName().equalsIgnoreCase("relationship")) {
+ return NodeType.RELATIONSHIP;
+ }
+
+ if (node.getNodeName().equalsIgnoreCase("relationship-data")) {
+ return NodeType.RELATIONSHIP_DATA;
+ }
+
+ if (node.getNodeName().equalsIgnoreCase("related-to")) {
+ return NodeType.RELATED_TO;
+ }
+
+ if (node.getNodeName().equalsIgnoreCase("relationship-key")) {
+ return NodeType.RELATIONSHIP_KEY;
+ }
+
+ if (node.getNodeName().equalsIgnoreCase("relationship-value")) {
+ return NodeType.RELATIONSHIP_VALUE;
+ }
+
+ if (node.getNodeName().equalsIgnoreCase("model-element")) {
+ return NodeType.MODEL_ELEMENT_VERTEX;
+ }
+
+ if (node.getNodeName().equalsIgnoreCase("named-query-element")) {
+ return NodeType.NQ_ELEMENT_VERTEX;
+ }
+
+ NodeList childNodes = node.getChildNodes();
+ int childElements = countChildElements(childNodes);
+
+ if ( (childElements == 0) && (node.getTextContent() != null) && (!node.getTextContent().trim().isEmpty()) ) {
+ return NodeType.ATTRIBUTE;
+ }
+
+ for (int ix = 0; ix < childNodes.getLength(); ix++) {
+ if (getNodeType(childNodes.item(ix)) == NodeType.ATTRIBUTE) {
+ return NodeType.VERTEX;
+ }
+ }
+
+ if (childElements > 0) {
+ return NodeType.CONTAINER;
+ }
+
+ return NodeType.UNKNOWN;
+ }
+
+ static int countChildElements(NodeList nodes) {
+ int count = 0;
+ for (int ix = 0; ix < nodes.getLength(); ix++) {
+ if (nodes.item(ix) instanceof Element) {
+ count++;
+ }
+ }
+
+ return count;
+ }
+}
diff --git a/src/test/java/org/onap/aai/modelloader/util/GizmoTranslatorTest.java b/src/test/java/org/onap/aai/modelloader/util/GizmoTranslatorTest.java
new file mode 100644
index 0000000..5891931
--- /dev/null
+++ b/src/test/java/org/onap/aai/modelloader/util/GizmoTranslatorTest.java
@@ -0,0 +1,116 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
+ * Copyright © 2017-2018 European Software Marketing Ltd.
+ * ================================================================================
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * 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.onap.aai.modelloader.util;
+
+import static org.junit.Assert.assertTrue;
+
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.List;
+
+import org.junit.Test;
+import org.onap.aai.modelloader.gizmo.GizmoBulkPayload;
+import org.onap.aai.modelloader.gizmo.GizmoEdgeOperation;
+import org.onap.aai.modelloader.gizmo.GizmoVertexOperation;
+
+public class GizmoTranslatorTest {
+
+ @Test
+ public void translateXmlModel1() throws Exception {
+ final String XML_MODEL_FILE = "src/test/resources/models/AAI-stellService-service-1.xml";
+
+ try {
+ byte[] encoded = Files.readAllBytes(Paths.get(XML_MODEL_FILE));
+ String originalXml = new String(encoded);
+
+ String output = GizmoTranslator.translate(originalXml);
+ System.out.println("Test1 Outgoing:\n" + output);
+
+ GizmoBulkPayload request = GizmoBulkPayload.fromJson(output);
+
+ List<GizmoVertexOperation> ops = request.getVertexOperations(GizmoBulkPayload.ADD_OP);
+ assertTrue(ops.size() == 5);
+
+ ops = request.getVertexOperations(GizmoBulkPayload.EXISTS_OP);
+ assertTrue(ops.size() == 3);
+
+ List<GizmoEdgeOperation> edgeOps = request.getEdgeOperations(GizmoBulkPayload.ADD_OP);
+ assertTrue(edgeOps.size() == 7);
+ } catch (Exception e) {
+ e.printStackTrace();
+ assertTrue(false);
+ }
+ }
+
+ @Test
+ public void translateXmlModel2() throws Exception {
+ final String XML_MODEL_FILE2 = "src/test/resources/models/l3-network-widget.xml";
+
+ try {
+ byte[] encoded = Files.readAllBytes(Paths.get(XML_MODEL_FILE2));
+ String originalXml = new String(encoded);
+
+ String output = GizmoTranslator.translate(originalXml);
+ System.out.println("Test2 Outgoing:\n" + output);
+
+ GizmoBulkPayload request = GizmoBulkPayload.fromJson(output);
+
+ List<GizmoVertexOperation> ops = request.getVertexOperations(GizmoBulkPayload.ADD_OP);
+ assertTrue(ops.size() == 2);
+
+ ops = request.getVertexOperations(GizmoBulkPayload.EXISTS_OP);
+ assertTrue(ops.size() == 0);
+
+ List<GizmoEdgeOperation> edgeOps = request.getEdgeOperations(GizmoBulkPayload.ADD_OP);
+ assertTrue(edgeOps.size() == 1);
+ } catch (Exception e) {
+ e.printStackTrace();
+ assertTrue(false);
+ }
+ }
+
+ @Test
+ public void translateXmlNamedQuery() throws Exception {
+ final String XML_MODEL_FILE3 = "src/test/resources/models/named-query-wan-connector.xml";
+
+ try {
+ byte[] encoded = Files.readAllBytes(Paths.get(XML_MODEL_FILE3));
+ String originalXml = new String(encoded);
+
+ String output = GizmoTranslator.translate(originalXml);
+ System.out.println("Test3 Outgoing:\n" + output);
+
+ GizmoBulkPayload request = GizmoBulkPayload.fromJson(output);
+
+ List<GizmoVertexOperation> ops = request.getVertexOperations(GizmoBulkPayload.ADD_OP);
+ assertTrue(ops.size() == 5);
+
+ ops = request.getVertexOperations(GizmoBulkPayload.EXISTS_OP);
+ assertTrue(ops.size() == 4);
+
+ List<GizmoEdgeOperation> edgeOps = request.getEdgeOperations(GizmoBulkPayload.ADD_OP);
+ assertTrue(edgeOps.size() == 8);
+ } catch (Exception e) {
+ e.printStackTrace();
+ assertTrue(false);
+ }
+ }
+}