summaryrefslogtreecommitdiffstats
path: root/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j')
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/BatchBuilder.java79
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/CypherTemplates.java52
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/CypherTranslator.java251
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgeLabels.java8
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgePropertiesDictionary.java2
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphNeighbourTable.java64
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java12
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jClient.java983
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jEdge.java69
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jGraphBatchBuilder.java179
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jOperationStatus.java77
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/NodeRelation.java65
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/MatchFilter.java51
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/RecursiveByRelationFilter.java81
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/RecursiveFilter.java68
-rw-r--r--catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/UpdateFilter.java56
16 files changed, 2087 insertions, 10 deletions
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/BatchBuilder.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/BatchBuilder.java
new file mode 100644
index 0000000000..9d30c20683
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/BatchBuilder.java
@@ -0,0 +1,79 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j;
+
+import org.openecomp.sdc.be.dao.graph.datatype.GraphElement;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class BatchBuilder {
+ // private Map<String, List<Neo4jNode>> nodes;
+ // private List<Neo4jRelation> relations;
+ //
+ private List<GraphElement> elements;
+
+ // TODO add filter
+
+ protected BatchBuilder() {
+ // nodes = new HashMap<String, List<Neo4jNode>>();
+ // relations = new ArrayList<Neo4jRelation>();
+ elements = new ArrayList<>();
+ }
+
+ public static BatchBuilder getBuilder() {
+ return new BatchBuilder();
+ }
+
+ public BatchBuilder add(GraphElement element) {
+ elements.add(element);
+ return this;
+ }
+
+ public List<GraphElement> getElements() {
+ return elements;
+ }
+
+ // public BatchBuilder add( Neo4jNode element ){
+ // String label = element.getLabel();
+ // List<Neo4jNode> list = nodes.get(label);
+ // if ( list == null ){
+ // list = new ArrayList<Neo4jNode>();
+ // }
+ // list.add(element);
+ // nodes.put(label, list);
+
+ // return this;
+ // }
+ // public BatchBuilder add( Neo4jRelation relation ){
+ // relations.add(relation);
+ // return this;
+ // }
+ //
+ // public Map<String, List<Neo4jNode>> getNodes() {
+ // return nodes;
+ // }
+ //
+ // public List<Neo4jRelation> getRelations() {
+ // return relations;
+ // }
+
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/CypherTemplates.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/CypherTemplates.java
new file mode 100644
index 0000000000..b0b2cc20bb
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/CypherTemplates.java
@@ -0,0 +1,52 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j;
+
+public interface CypherTemplates {
+
+ public static final String CypherUrlTemplate = "http://$host$:$port$/db/data/transaction/commit";
+ public static final String batchTemplate = "http://$host$:$port$/db/data/batch";
+ public static final String getAllIndexsTemplate = "http://$host$:$port$/db/data/schema/index";
+
+ public static final String CypherCreateNodeTemplate = "{\n\"statements\" : [ {\n \"statement\" : \"CREATE (n:$label$ { props } ) RETURN n\",\n \"parameters\" : { \n \"props\" : $props$ \n } } ] }";
+
+ public static final String CypherMatchTemplate = "{\"statements\": [{\"statement\": \"MATCH (n:$label$ {$filter$}) RETURN ($type$) \" }]}";
+
+ public static final String CypherUpdateTemplate = "{\"statements\": [{\"statement\": \"MATCH (n:$label$ {$filter$}) SET n += {props} RETURN ($type$) \",\"parameters\" : {\"props\" : {$props$}}}]}";
+ public static final String CypherDeleteNodeTemplate = "{\"statements\": [{\"statement\": \"MATCH ( n:$label$ {$filter$} ) DELETE n \" }]}";
+
+ public static final String BatchTemplate = "{ \"statements\" : [ $statementList$ ] }";
+
+ public static final String RegularStatementTemplate = "{ \"statement\" : $statement$ }";
+
+ public static final String CreateSingleNodeTemplate = " \"CREATE (n:$label$ { props } ) RETURN n, labels(n)\", \"parameters\" : { \"props\" : $props$ }";
+
+ public static final String CreateRelationTemplate = "\"MATCH (a:$labelFrom$),(b:$labelTo$) WHERE a.$idNameFrom$ = '$idValueFrom$' AND b.$idNameTo$ = '$idvalueTo$' CREATE (a)-[r:$type$ { props } ]->(b) RETURN a, labels(a), b, labels(b), r, type(r)\", \"parameters\": {\"props\": $props$ } ";
+
+ public static final String CreateRelationTemplateNoProps = "\"MATCH (a:$labelFrom$),(b:$labelTo$) WHERE a.$idNameFrom$ = '$idValueFrom$' AND b.$idNameTo$ = '$idvalueTo$' CREATE (a)-[r:$type$ ]->(b) RETURN a,labels(a), b, labels(b), r, type(r)\"";
+
+ public static final String UpdateNodeStatementTemplate = "\"MATCH (n:$label$ {$filter$}) SET n += {props} \",\"parameters\" : {\"props\" : $props$}";
+
+ public static final String GetNodeRecursiveTemplate = "\"MATCH (m:$label$ {$filter$} )-[f$typesList$]->l RETURN m, labels(m), l, labels(l),f, type(f)\"";
+
+ public static final String GetByRelationNodeRecursiveTemplate = "\"MATCH (n:$labelNode$ ($propsNode$} )-[r:$type$ {$propsRel$}]->(m:$labelSrc$)-[f$typesList$]->l RETURN n, labels(n), r, type(r), m, labels(m), l, labels(l),f, type(f)\"";
+
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/CypherTranslator.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/CypherTranslator.java
new file mode 100644
index 0000000000..2f53736c59
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/CypherTranslator.java
@@ -0,0 +1,251 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j;
+
+import org.apache.commons.lang3.tuple.ImmutablePair;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphElement;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
+import org.openecomp.sdc.be.dao.graph.datatype.RelationEndPoint;
+import org.openecomp.sdc.be.dao.neo4j.filters.MatchFilter;
+import org.openecomp.sdc.be.dao.neo4j.filters.RecursiveByRelationFilter;
+import org.openecomp.sdc.be.dao.neo4j.filters.RecursiveFilter;
+import org.openecomp.sdc.be.dao.utils.DaoUtils;
+
+import java.util.List;
+import java.util.Map;
+
+public class CypherTranslator {
+
+ public String translate(BatchBuilder builder) {
+ String json = null;
+ StringBuilder statementList = new StringBuilder();
+
+ List<GraphElement> elements = builder.getElements();
+ int statementCounter = 0;
+ for (GraphElement element : elements) {
+ String singleStatementBody = null;
+ switch (element.getElementType()) {
+ case Node:
+ singleStatementBody = prepareNodeStatement(element);
+ break;
+ case Relationship:
+ singleStatementBody = prepareRelationStatement(element);
+ break;
+ }
+ if (singleStatementBody != null && !singleStatementBody.isEmpty()) {
+
+ String singleStatement = CypherTemplates.RegularStatementTemplate.replace("$statement$",
+ singleStatementBody);
+
+ statementList.append(singleStatement);
+ }
+ ++statementCounter;
+ if (statementCounter < elements.size() && singleStatementBody != null) {
+ statementList.append(",");
+ }
+
+ }
+ json = CypherTemplates.BatchTemplate.replace("$statementList$", statementList.toString());
+ return json;
+ }
+
+ private String prepareNodeStatement(GraphElement element) {
+ if (element instanceof GraphNode) {
+ GraphNode node = (GraphNode) element;
+
+ switch (node.getAction()) {
+ case Create:
+ return createNodeStatement(node);
+ case Update:
+ return updateNodeStatement(node);
+ case Delete:
+ // TODO
+ break;
+ default:
+ break;
+ }
+ }
+ return null;
+ }
+
+ private String updateNodeStatement(GraphNode node) {
+ String singleStatement = CypherTemplates.UpdateNodeStatementTemplate.replace("$label$", node.getLabel());
+ String filter = prepareKeyValueFilter(node);
+
+ singleStatement = singleStatement.replace("$filter$", filter);
+
+ singleStatement = singleStatement.replace("$props$", DaoUtils.convertToJson(node.toGraphMap()));
+
+ return singleStatement;
+ }
+
+ private String createNodeStatement(GraphNode node) {
+ String singleStatement = CypherTemplates.CreateSingleNodeTemplate.replace("$label$", node.getLabel());
+
+ singleStatement = singleStatement.replace("$props$", DaoUtils.convertToJson(node.toGraphMap()));
+ return singleStatement;
+ }
+
+ private String prepareRelationStatement(GraphElement element) {
+ if (element instanceof GraphRelation) {
+
+ GraphRelation relation = (GraphRelation) element;
+
+ switch (relation.getAction()) {
+ case Create:
+ return createRelationStatement(relation);
+ case Update:
+ return updateRelationStatement(relation);
+ case Delete:
+ // TODO
+ break;
+ default:
+ break;
+ }
+ }
+ return null;
+ }
+
+ private String createRelationStatement(GraphRelation relation) {
+ RelationEndPoint from = relation.getFrom();
+ String singleStatement;
+
+ Map<String, Object> props = relation.toGraphMap();
+ if (props == null || props.isEmpty()) {
+ singleStatement = CypherTemplates.CreateRelationTemplateNoProps.replace("$labelFrom$",
+ from.getLabel().getName());
+ } else {
+ singleStatement = CypherTemplates.CreateRelationTemplate.replace("$labelFrom$", from.getLabel().getName());
+ singleStatement = singleStatement.replace("$props$", DaoUtils.convertToJson(props));
+ }
+
+ singleStatement = singleStatement.replace("$idNameFrom$", from.getIdName());
+ singleStatement = singleStatement.replace("$idValueFrom$", from.getIdValue().toString());
+
+ RelationEndPoint to = relation.getTo();
+ singleStatement = singleStatement.replace("$labelTo$", to.getLabel().getName());
+ singleStatement = singleStatement.replace("$idNameTo$", to.getIdName());
+ singleStatement = singleStatement.replace("$idvalueTo$", to.getIdValue().toString());
+
+ singleStatement = singleStatement.replace("$type$", relation.getType());
+ return singleStatement;
+ }
+
+ private String updateRelationStatement(GraphRelation relation) {
+ // TODO
+ return null;
+ }
+
+ private String prepareKeyValueFilter(GraphNode node) {
+ StringBuilder sb = new StringBuilder();
+
+ ImmutablePair<String, Object> keyValueId = node.getKeyValueId();
+
+ sb.append(keyValueId.getKey()).append(":");
+ if (keyValueId.getValue() instanceof String) {
+ sb.append("'");
+ }
+ sb.append(keyValueId.getValue());
+
+ if (keyValueId.getValue() instanceof String) {
+ sb.append("'");
+ }
+
+ return sb.toString();
+ }
+
+ public String translateGet(RecursiveFilter filter) {
+ String requestJson = null;
+ String statement;
+
+ if (filter instanceof RecursiveByRelationFilter) {
+ RecursiveByRelationFilter byRelationFilter = (RecursiveByRelationFilter) filter;
+
+ statement = CypherTemplates.GetByRelationNodeRecursiveTemplate.replace("$labelNode$",
+ byRelationFilter.getNode().getLabel());
+ String keyValueId = prepareKeyValueFilter(byRelationFilter.getNode());
+
+ statement = statement.replace("$propsNode$", keyValueId);
+
+ statement = statement.replace("$type$", byRelationFilter.getRelationType());
+
+ String relationProps = prepareFilterBody(filter);
+ statement = statement.replace("$propsRel$", relationProps);
+ statement = statement.replace("$labelSrc$", filter.getNodeType().getName());
+
+ } else {
+
+ statement = CypherTemplates.GetNodeRecursiveTemplate.replace("$label$", filter.getNodeType().getName());
+
+ // replace filter
+ if (filter.getProperties().isEmpty()) {
+ // get all records by label
+ statement = statement.replace("{$filter$}", "");
+ } else {
+ String filterStr = prepareFilterBody(filter);
+ statement = statement.replace("$filter$", filterStr);
+ }
+ }
+
+ if (filter.getChildRelationTypes() == null || filter.getChildRelationTypes().isEmpty()) {
+ statement = statement.replace("$typesList$", "");
+
+ } else {
+ StringBuilder typesList = new StringBuilder();
+ int count = 0;
+ for (String type : filter.getChildRelationTypes()) {
+ typesList.append(":").append(type);
+ ++count;
+ if (count < filter.getChildRelationTypes().size()) {
+ typesList.append("|");
+ }
+ }
+ statement = statement.replace("$typesList$", typesList.toString());
+ }
+ String singleStatement = CypherTemplates.RegularStatementTemplate.replace("$statement$", statement);
+ requestJson = CypherTemplates.BatchTemplate.replace("$statementList$", singleStatement);
+
+ return requestJson;
+ }
+
+ public static String prepareFilterBody(MatchFilter filter) {
+ StringBuilder sb = new StringBuilder();
+ int count = 0;
+ int size = filter.getProperties().entrySet().size();
+ for (Map.Entry<String, Object> entry : filter.getProperties().entrySet()) {
+ sb.append(entry.getKey()).append(":");
+ if (entry.getValue() instanceof String) {
+ sb.append("'");
+ }
+ sb.append(entry.getValue());
+ if (entry.getValue() instanceof String) {
+ sb.append("'");
+ }
+ ++count;
+ if (count < size) {
+ sb.append(",");
+ }
+ }
+ return sb.toString();
+ }
+
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgeLabels.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgeLabels.java
index 790e92ec55..5b386f18bb 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgeLabels.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgeLabels.java
@@ -28,7 +28,8 @@ public enum GraphEdgeLabels {
// field name
//
STATE("STATE"), LAST_STATE("LAST_STATE"), CREATOR("CREATOR"), LAST_MODIFIER("LAST_MODIFIER"), ATTRIBUTE("EDGE_ATTRIBUTE"), PROPERTY("EDGE_PROPERTY"), CATEGORY("CATEGORY"), DERIVED_FROM("DERIVED_FROM"), REQUIREMENT("REQUIREMENT"),
- CAPABILITY_TYPE("CAPABILITY_TYPE"), RELATIONSHIP_TYPE("RELATIONSHIP_TYPE"), CAPABILITY("CAPABILITY"), INSTANCE_OF("INSTANCE_OF"), INTERFACE("INTERFACE"), INTERFACE_OPERATION("INTERFACE_OPERATION"), ARTIFACT_REF("ARTIFACT_REF"),
+ CAPABILITY_TYPE("CAPABILITY_TYPE"), RELATIONSHIP_TYPE("RELATIONSHIP_TYPE"), CAPABILITY("CAPABILITY"), CAPABILITY_IMPL("CAPABILITY_IMPL"),
+ INSTANCE_OF("INSTANCE_OF"), INTERFACE("INTERFACE"), INTERFACE_OPERATION("INTERFACE_OPERATION"), ARTIFACT_REF("ARTIFACT_REF"),
INPUTS("INPUTS"), REQUIREMENT_IMPL("REQUIREMENT_IMPL"), NODE_IMPL("NODE_IMPL"), IMPLEMENTATION_OF("IMPLEMENTATION_OF"), ATTRIBUTE_VALUE("ATTRIBUTE_VALUE"), INPUT_VALUE("INPUT_VALUE"), PROPERTY_VALUE("PROPERTY_VALUE"),
CAPABILITY_INST("CAPABILITY_INST"), TYPE_OF("TYPE_OF"), RESOURCE_INST("RESOURCE_INST"), RELATIONSHIP_INST("RELATIONSHIP_INST"), CAPABILITY_NODE("CAPABILITY_NODE"), LAST_DISTRIBUTION_STATE_MODIFAIER("LAST_DISTRIBUTION_STATE_MODIFAIER"),
ATTRIBUTE_IMPL("ATTRIBUTE_IMPL"), INPUT_IMPL("INPUT_IMPL"), PROPERTY_IMPL("PROPERTY_IMPL"), ADDITIONAL_INFORMATION("ADDITIONAL_INFORMATION"), HEAT_PARAMETER("HEAT_PARAMETER"), SUB_CATEGORY("SUB_CATEGORY"), GROUPING("GROUPING"),
@@ -37,7 +38,8 @@ public enum GraphEdgeLabels {
CALCULATED_REQUIREMENT("CALCULATED_REQUIREMENT"), CALCULATED_CAPABILITY("CALCULATED_CAPABILITY"), RELATIONSHIP_ORIGIN("RELATIONSHIP_ORIGIN"), CAPABILITY_ORIGIN("CAPABILITY_ORIGIN"),
CALCULATED_REQUIREMENT_FULLFILLED("CALCULATED_REQUIREMENT_FULLFILLED"), CALCULATED_CAPABILITY_FULLFILLED("CALCULATED_CAPABILITY_FULLFILLED"),
// Group
- GROUP("GROUP"), GROUP_ARTIFACT_REF("GROUP_ARTIFACT_REF"), GROUP_MEMBER("GROUP_MEMBER"), INPUT("EDGE_INPUT"), GET_INPUT("GET_INPUT"), GROUP_INST("GROUP_INST"), GROUP_TYPE_CAPABILITY_TYPE("GROUP_TYPE_CAPABILITY_TYPE");
+ GROUP("GROUP"), GROUP_ARTIFACT_REF("GROUP_ARTIFACT_REF"), GROUP_MEMBER("GROUP_MEMBER"), INPUT("EDGE_INPUT"), GET_INPUT("GET_INPUT"), GROUP_INST("GROUP_INST"),
+ GROUP_TYPE_CAPABILITY_TYPE("GROUP_TYPE_CAPABILITY_TYPE"), GROUP_TYPE_CAPABILITY("GROUP_TYPE_CAPABILITY");
private String property;
@@ -55,7 +57,7 @@ public enum GraphEdgeLabels {
public static List<String> getAllProperties() {
- List<String> arrayList = new ArrayList<String>();
+ List<String> arrayList = new ArrayList<>();
for (GraphEdgeLabels graphProperty : GraphEdgeLabels.values()) {
arrayList.add(graphProperty.getProperty());
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgePropertiesDictionary.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgePropertiesDictionary.java
index 6bba5dac9d..58bd098d77 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgePropertiesDictionary.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgePropertiesDictionary.java
@@ -62,7 +62,7 @@ public enum GraphEdgePropertiesDictionary {
public static List<String> getAllProperties() {
- List<String> arrayList = new ArrayList<String>();
+ List<String> arrayList = new ArrayList<>();
for (GraphEdgePropertiesDictionary graphProperty : GraphEdgePropertiesDictionary.values()) {
arrayList.add(graphProperty.getProperty());
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphNeighbourTable.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphNeighbourTable.java
new file mode 100644
index 0000000000..9a62e07a2d
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphNeighbourTable.java
@@ -0,0 +1,64 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j;
+
+import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class GraphNeighbourTable {
+
+ List<GraphNode> nodes = new ArrayList<>();
+
+ List<NodeRelation> directedEdges = new ArrayList<>();
+
+ public List<GraphNode> getNodes() {
+ return nodes;
+ }
+
+ public void setNodes(List<GraphNode> nodes) {
+ this.nodes = nodes;
+ }
+
+ public List<NodeRelation> getDirectedEdges() {
+ return directedEdges;
+ }
+
+ public void setDirectedEdges(List<NodeRelation> directedEdges) {
+ this.directedEdges = directedEdges;
+ }
+
+ public int addNode(GraphNode node) {
+ this.nodes.add(node);
+ return this.nodes.size() - 1;
+ }
+
+ public void addEdge(NodeRelation directedEdge) {
+ this.directedEdges.add(directedEdge);
+ }
+
+ @Override
+ public String toString() {
+ return "GraphNeighbourTable [nodes=" + nodes + ", directedEdges=" + directedEdges + "]";
+ }
+
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java
index 6258346a40..1da09e0cc5 100644
--- a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java
@@ -25,11 +25,11 @@ public enum GraphPropertiesDictionary {
// stored in graph index
// Common
LABEL ("nodeLabel", String.class, false, true),
- HEALTH_CHECK ("healthcheckis", String.class, true, true), //yavivi
+ HEALTH_CHECK ("healthcheckis", String.class, true, true),
// Resource
NAME ("name", String.class, false, true),
TOSCA_RESOURCE_NAME ("toscaResourceName", String.class, false, true),
- CATEGORY_NAME ("categoryName", String.class, false, true), // ?
+ CATEGORY_NAME ("categoryName", String.class, false, true),
VERSION ("version", String.class, false, true),
CREATION_DATE ("creationDate", Long.class, false, false),
LAST_UPDATE_DATE ("modificationDate", Long.class, false, false),
@@ -145,8 +145,9 @@ public enum GraphPropertiesDictionary {
FUNCTIONAL_MENU ("functionalMenu", String.class, false, false),
REQUIRED_ARTIFACTS ("requiredArtifacts", String.class, false, false),
CUSTOMIZATION_UUID ("customizationUUID", String.class, false, false),
- ;
-
+ IS_ARCHIVED ("isArchived", Boolean.class, false, true),
+ IS_VSP_ARCHIVED ("isVspArchived", Boolean.class, false, true),
+ ARCHIVE_TIME ("archiveTime", Long.class, false, true);
private final String property;
@@ -154,7 +155,6 @@ public enum GraphPropertiesDictionary {
private final boolean unique;
private final boolean indexed;
-
GraphPropertiesDictionary(String property,Class clazz, boolean unique,boolean indexed) {
this.property = property;
this.clazz = clazz;
@@ -170,7 +170,7 @@ public enum GraphPropertiesDictionary {
public Class getClazz() {
return clazz;
}
-
+
public boolean isUnique() {
return unique;
}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jClient.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jClient.java
new file mode 100644
index 0000000000..cc7a3fceb3
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jClient.java
@@ -0,0 +1,983 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j;
+
+import fj.data.Either;
+import org.apache.http.HttpEntity;
+import org.apache.http.client.ClientProtocolException;
+import org.apache.http.client.HttpResponseException;
+import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.BasicResponseHandler;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+import org.apache.http.util.EntityUtils;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
+import org.json.simple.parser.ParseException;
+import org.openecomp.sdc.be.config.ConfigurationManager;
+import org.openecomp.sdc.be.dao.graph.GraphElementFactory;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphElement;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum;
+import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
+import org.openecomp.sdc.be.dao.neo4j.filters.MatchFilter;
+import org.openecomp.sdc.be.dao.neo4j.filters.RecursiveFilter;
+import org.openecomp.sdc.be.dao.neo4j.filters.UpdateFilter;
+import org.openecomp.sdc.be.dao.utils.DaoUtils;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+import java.io.IOException;
+import java.util.*;
+
+//@Component("neo4j-client")
+public class Neo4jClient {
+ private CloseableHttpClient httpClient;
+ private JSONParser jsonParser;
+
+ private CypherTranslator cypherTranslator;
+
+ private static Logger logger = Logger.getLogger(Neo4jClient.class.getName());
+
+ private static final String getServiceRoot = "http://$host$:$port$/db/data/";
+ // Error's Classification templates
+ private static final String ClientError = "ClientError";
+ private static final String DatabaseError = "DatabaseError";
+ private static final String TransientError = "TransientError";
+
+ // Error's Category templates
+ private static final String General = "General";
+ private static final String LegacyIndex = "LegacyIndex";
+ private static final String Request = "Request";
+ private static final String Schema = "Schema";
+ private static final String Security = "Security";
+ private static final String Statement = "Statement";
+ private static final String Transaction = "Transaction";
+
+ // Error's Title templates
+ private static final String EntityNotFound = "EntityNotFound";
+ private static final String ConstraintViolation = "ConstraintViolation";
+
+ @PostConstruct
+ public void init() {
+
+ PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
+ connectionManager.setMaxTotal(100);
+ connectionManager.setDefaultMaxPerRoute(20);
+ connectionManager.setValidateAfterInactivity(15000);
+ this.httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();
+ jsonParser = new JSONParser();
+ cypherTranslator = new CypherTranslator();
+
+ }
+
+ @PreDestroy
+ public void shutdown() {
+ try {
+ httpClient.close();
+ logger.debug("Http client to Neo4j Graph closed");
+ } catch (Exception e) {
+ logger.info("Failed to close http client", e);
+ }
+ }
+
+ /**
+ *
+ * @param builder
+ * @return
+ */
+ public Either<List<List<GraphElement>>, Neo4jOperationStatus> execute(BatchBuilder builder) {
+
+ String json = cypherTranslator.translate(builder);
+ logger.debug("Try to execute cypher request [{}]", json);
+
+ Either<String, Neo4jOperationStatus> result = sendPostCypher(json);
+ if (result.isRight()) {
+ return Either.right(result.right().value());
+ }
+ List<List<GraphElement>> batchResult;
+ try {
+ batchResult = parseResult(result.left().value(), false);
+ } catch (ParseException e) {
+ logger.error("Failed to parse batchresponse", e);
+ return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
+ }
+
+ return Either.left(batchResult);
+ }
+
+ public Either<List<List<GraphElement>>, Neo4jOperationStatus> executeGet(RecursiveFilter filter) {
+ String json = cypherTranslator.translateGet(filter);
+ logger.debug("Try to execute cypher request [{}]", json);
+
+ Either<String, Neo4jOperationStatus> result = sendPostCypher(json);
+ if (result.isRight()) {
+ return Either.right(result.right().value());
+ }
+ List<List<GraphElement>> batchResult;
+ try {
+ batchResult = parseResult(result.left().value(), true);
+ } catch (ParseException e) {
+ logger.error("Failed to parse batchresponse", e);
+ return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
+ }
+
+ return Either.left(batchResult);
+
+ }
+
+ /**
+ *
+ * @param element
+ * @param ip
+ * @param user
+ * @param password
+ * @return
+ */
+ public Neo4jOperationStatus createElement(GraphElement element) {
+ Neo4jOperationStatus result = Neo4jOperationStatus.OK;
+ switch (element.getElementType()) {
+ case Node:
+ Either<String, Neo4jOperationStatus> status = createNode(element);
+ if (status.isRight()) {
+ result = status.right().value();
+ }
+ break;
+ case Relationship:
+ // TODO
+ break;
+
+ default:
+ break;
+ }
+
+ return result;
+ }
+
+ public Either<GraphElement, Neo4jOperationStatus> createSingleElement(GraphElement element) {
+ switch (element.getElementType()) {
+ case Node:
+ Either<String, Neo4jOperationStatus> status = createNode(element);
+ if (status.isRight()) {
+ return Either.right(status.right().value());
+ }
+ // parse response
+ String response = status.left().value();
+ try {
+ List<GraphElement> listElements = parseGetResponse(element.getElementType(),
+ ((GraphNode) element).getLabel(), response);
+ if (listElements == null || listElements.isEmpty()) {
+ return Either.right(Neo4jOperationStatus.NOT_FOUND);
+ } else {
+ return Either.left(listElements.get(0));
+ }
+ } catch (Exception e) {
+ logger.error("Failed to parse fetched data from graph", e);
+ return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
+ }
+ case Relationship:
+ // TODO
+ break;
+
+ default:
+ break;
+ }
+
+ return Either.right(Neo4jOperationStatus.NOT_SUPPORTED);
+ }
+
+ /**
+ *
+ * @param type
+ * @param label
+ * @param filter
+ * @param ip
+ * @param user
+ * @param password
+ * @return
+ */
+ public Either<List<GraphElement>, Neo4jOperationStatus> getByFilter(GraphElementTypeEnum type, String label,
+ MatchFilter filter) {
+
+ List<GraphElement> result = null;
+
+ String requestJson;
+ // replace return type
+ if (type.equals(GraphElementTypeEnum.Node)) {
+ requestJson = CypherTemplates.CypherMatchTemplate.replace("$type$", "n");
+ } else {
+ requestJson = CypherTemplates.CypherMatchTemplate.replace("$type$", "r");
+ }
+ // replace label
+ if (label != null && !label.isEmpty()) {
+ requestJson = requestJson.replace("$label$", label);
+ } else {
+ requestJson = requestJson.replace("$label$", "");
+ }
+
+ // replace filter
+ if (filter.getProperties().isEmpty()) {
+ // get all records by label
+ requestJson = requestJson.replace("{$filter$}", "");
+ } else {
+ String filterStr = CypherTranslator.prepareFilterBody(filter);
+ requestJson = requestJson.replace("$filter$", filterStr);
+ }
+ logger.debug("Try to perform request []", requestJson);
+
+ Either<String, Neo4jOperationStatus> status = sendPostCypher(requestJson);
+ if (status.isRight()) {
+ return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
+ }
+ // parse response
+ String response = status.left().value();
+ try {
+ result = parseGetResponse(type, label, response);
+ } catch (Exception e) {
+ logger.error("Failed to parse fetched data from graph", e);
+ Either.right(Neo4jOperationStatus.GENERAL_ERROR);
+ }
+
+ return Either.left(result);
+ }
+
+ /**
+ *
+ * @param type
+ * @param label
+ * @param toMatch
+ * @param toUpdate
+ * @param ip
+ * @param user
+ * @param password
+ * @return
+ */
+ public Neo4jOperationStatus updateElement(GraphElementTypeEnum type, String label, UpdateFilter toUpdate) {
+
+ String requestJson;
+ // replace return type
+ if (type.equals(GraphElementTypeEnum.Node)) {
+ requestJson = CypherTemplates.CypherUpdateTemplate.replace("$type$", "n");
+ } else {
+ requestJson = CypherTemplates.CypherUpdateTemplate.replace("$type$", "r");
+ }
+ // replace label
+ if (label != null && !label.isEmpty()) {
+ requestJson = requestJson.replace("$label$", label);
+ } else {
+ requestJson = requestJson.replace("$label$", "");
+ }
+
+ // replace filter
+ if (toUpdate.getProperties().isEmpty()) {
+ // get all records by label
+ requestJson = requestJson.replace("{$filter$}", "");
+ } else {
+ String filterStr = CypherTranslator.prepareFilterBody(toUpdate);
+ requestJson = requestJson.replace("$filter$", filterStr);
+ }
+ String props = preparePropertiesInStatement(toUpdate.getToUpdate());
+ requestJson = requestJson.replace("$props$", props);
+
+ logger.debug("Try to perform request [{}]", requestJson);
+
+ Either<String, Neo4jOperationStatus> result = sendPostCypher(requestJson);
+ if (result.isRight()) {
+ return Neo4jOperationStatus.GENERAL_ERROR;
+ }
+ return Neo4jOperationStatus.OK;
+ }
+
+ /**
+ *
+ * @param type
+ * @param label
+ * @param response
+ * @return
+ * @throws ParseException
+ */
+
+ private List<GraphElement> parseGetResponse(GraphElementTypeEnum type, String label, String response)
+ throws ParseException {
+ List<GraphElement> result = new ArrayList<>();
+ JSONObject responseData = (JSONObject) jsonParser.parse(response);
+ JSONArray results = (JSONArray) responseData.get("results");
+ Iterator<JSONObject> iteratorResults = results.iterator();
+ while (iteratorResults.hasNext()) {
+ JSONObject elementResult = iteratorResults.next();
+ // JSONArray data = (JSONArray) elementResult.get("row");
+ JSONArray data = (JSONArray) elementResult.get("data");
+
+ Iterator<JSONObject> iterator = data.iterator();
+ JSONObject element;
+ while (iterator.hasNext()) {
+ element = (JSONObject) iterator.next();
+ JSONArray row = (JSONArray) element.get("row");
+
+ Iterator<JSONObject> iteratorRow = row.iterator();
+ while (iteratorRow.hasNext()) {
+ JSONObject rowElement = iteratorRow.next();
+
+ Map<String, Object> props = new HashMap<>();
+
+ for (Map.Entry<String, Object> entry : (Set<Map.Entry<String, Object>>) rowElement.entrySet()) {
+ // props.put(entry.getKey(),
+ // rowElement.get(entry.getValue()));
+ props.put(entry.getKey(), entry.getValue());
+ }
+ GraphElement newElement = GraphElementFactory.createElement(label, type, props);
+ result.add(newElement);
+ }
+ }
+ }
+ return result;
+ }
+
+ private List<List<GraphElement>> parseResult(String response, boolean storeRelationNode) throws ParseException {
+
+ List<List<GraphElement>> batchList = new ArrayList<>();
+
+ JSONObject responseData = (JSONObject) jsonParser.parse(response);
+ JSONArray results = (JSONArray) responseData.get("results");
+ Iterator<JSONObject> iteratorResults = results.iterator();
+
+ while (iteratorResults.hasNext()) {
+ JSONObject elementResult = iteratorResults.next();
+ JSONArray data = (JSONArray) elementResult.get("data");
+ JSONArray columns = (JSONArray) elementResult.get("columns");
+ Iterator<JSONObject> iteratorData = data.iterator();
+ List<GraphElement> singleDataList = new ArrayList<>();
+ while (iteratorData.hasNext()) {
+
+ JSONObject singleData = iteratorData.next();
+ JSONArray row = (JSONArray) singleData.get("row");
+ if (columns.size() == 2) {
+ // node
+ JSONArray labelArray = (JSONArray) row.get(1);
+ JSONObject node = (JSONObject) row.get(0);
+
+ Map<String, Object> props = jsonObjectToMap(node);
+ // get only first label on node. Now single label supported
+ GraphElement newElement = GraphElementFactory.createElement((String) labelArray.get(0),
+ GraphElementTypeEnum.Node, props);
+ singleDataList.add(newElement);
+ }
+ if (columns.size() == 10) {
+ // relation
+ JSONObject startNode = (JSONObject) row.get(0);
+ JSONArray startNodeArray = (JSONArray) row.get(1);
+
+ JSONObject relationFromStart = (JSONObject) row.get(2);
+ String relationFromStartType = (String) row.get(3);
+
+ JSONObject nodeFrom = (JSONObject) row.get(4);
+ JSONArray labelFromArray = (JSONArray) row.get(5);
+
+ JSONObject nodeTo = (JSONObject) row.get(6);
+ JSONArray labelToArray = (JSONArray) row.get(7);
+
+ JSONObject relation = (JSONObject) row.get(8);
+ String type = (String) row.get(9);
+
+ Map<String, Object> propsStartNode = jsonObjectToMap(startNode);
+ Map<String, Object> propsRelationStartNode = jsonObjectToMap(relationFromStart);
+
+ Map<String, Object> propsFrom = jsonObjectToMap(nodeFrom);
+ Map<String, Object> propsTo = jsonObjectToMap(nodeTo);
+ Map<String, Object> propsRelation = jsonObjectToMap(relation);
+
+ GraphNode startN = (GraphNode) GraphElementFactory.createElement((String) startNodeArray.get(0),
+ GraphElementTypeEnum.Node, propsStartNode);
+
+ GraphNode from = (GraphNode) GraphElementFactory.createElement((String) labelFromArray.get(0),
+ GraphElementTypeEnum.Node, propsFrom);
+ GraphNode to = (GraphNode) GraphElementFactory.createElement((String) labelToArray.get(0),
+ GraphElementTypeEnum.Node, propsTo);
+
+ singleDataList.add(startN);
+
+ GraphElement relationFromStartNode = GraphElementFactory.createRelation(type,
+ propsRelationStartNode, startN, from);
+ singleDataList.add(relationFromStartNode);
+
+ singleDataList.add(from);
+ singleDataList.add(to);
+ // get only first type on relationship. Now single type
+ // supported
+ GraphElement newElement = GraphElementFactory.createRelation(type, propsRelation, from, to);
+ singleDataList.add(newElement);
+ }
+ if (columns.size() == 8) {
+
+ }
+ }
+ batchList.add(singleDataList);
+ }
+ return batchList;
+ }
+
+ private Map<String, Object> jsonObjectToMap(JSONObject node) {
+ Map<String, Object> props = new HashMap<>();
+
+ for (Map.Entry<String, Object> entry : (Set<Map.Entry<String, Object>>) node.entrySet()) {
+ props.put(entry.getKey(), entry.getValue());
+ }
+ return props;
+ }
+
+ private String preparePropertiesInStatement(Map<String, Object> properties) {
+ StringBuilder sb = new StringBuilder();
+ int count = 0;
+ int size = properties.entrySet().size();
+ for (Map.Entry<String, Object> entry : properties.entrySet()) {
+ sb.append("\"").append(entry.getKey()).append("\"").append(":");
+ if (entry.getValue() instanceof String) {
+ sb.append("\"");
+ }
+ sb.append(entry.getValue());
+ if (entry.getValue() instanceof String) {
+ sb.append("\"");
+ }
+ ++count;
+ if (count < size) {
+ sb.append(",");
+ }
+ }
+ return sb.toString();
+ }
+
+ private Either<String, Neo4jOperationStatus> createNode(GraphElement element) {
+ Either<String, Neo4jOperationStatus> status;
+ if (element instanceof GraphNode) {
+ GraphNode node = (GraphNode) element;
+ String json = prepareCreateNodeBody(node);
+
+ logger.debug("Try to save Node [{}] on graph", json);
+
+ status = sendPostCypher(json);
+
+ return status;
+
+ } else {
+ return Either.right(Neo4jOperationStatus.WRONG_INPUT);
+ }
+ }
+
+ private Either<String, Neo4jOperationStatus> sendPostCypher(String json) {
+ Map<String, Object> neo4jParams = ConfigurationManager.getConfigurationManager().getConfiguration().getNeo4j();
+ String host = (String) neo4jParams.get("host");
+ Integer port = (Integer) neo4jParams.get("port");
+ String user = (String) neo4jParams.get("user");
+ String password = (String) neo4jParams.get("password");
+
+ String uri = CypherTemplates.CypherUrlTemplate.replace("$host$", host);
+ uri = uri.replace("$port$", port.toString());
+
+ HttpClientContext context = creatClientContext(host, user, password);
+ CloseableHttpResponse response = null;
+
+ HttpPost post = new HttpPost(uri);
+ try {
+ StringEntity input = new StringEntity(json);
+ input.setContentType("application/json");
+ post.setEntity(input);
+
+ response = httpClient.execute(post, context);
+
+ int status = response.getStatusLine().getStatusCode();
+ String responseString;
+ responseString = new BasicResponseHandler().handleResponse(response);
+ logger.debug("response [{}]", responseString);
+
+ if (status == 200 || status == 201) {
+ logger.debug("cypher request [{}] was succeeded", json);
+ Neo4jOperationStatus responseStatus = checkResponse(responseString);
+ if (Neo4jOperationStatus.OK.equals(responseStatus)) {
+ return Either.left(responseString);
+ } else {
+ return Either.right(responseStatus);
+ }
+ } else {
+ logger.debug("cypher request [{}] was failed : [{}]", json, responseString);
+ return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
+ }
+
+ } catch (HttpResponseException e) {
+ logger.debug("failed to perform cypher request [{}]", json, e);
+ if (e.getStatusCode() == 401) {
+ return Either.right(Neo4jOperationStatus.NOT_AUTHORIZED);
+ } else {
+ return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
+ }
+ } catch (ClientProtocolException e) {
+ logger.debug("failed to perform cypher request [{}]", json, e);
+ return Either.right(Neo4jOperationStatus.HTTP_PROTOCOL_ERROR);
+ } catch (IOException e) {
+ logger.debug("failed to perform cypher request [{}]", json, e);
+ return Either.right(Neo4jOperationStatus.NOT_CONNECTED);
+ } finally {
+ releaseResource(response);
+ }
+ }
+
+ private Neo4jOperationStatus checkResponse(String responseString) {
+ try {
+ JSONObject response = (JSONObject) jsonParser.parse(responseString);
+ JSONArray errors = (JSONArray) response.get("errors");
+ if (errors.size() == 0) {
+ return Neo4jOperationStatus.OK;
+ } else {
+ Iterator<JSONObject> iterator = errors.iterator();
+ JSONObject error;
+ while (iterator.hasNext()) {
+ error = (JSONObject) iterator.next();
+ String code = (String) error.get("code");
+ String message = (String) error.get("message");
+
+ return mapToNeoError(code, message);
+ }
+ return Neo4jOperationStatus.GENERAL_ERROR;
+ }
+ } catch (ParseException e) {
+ logger.error("Failed to parse response", e);
+ return Neo4jOperationStatus.GENERAL_ERROR;
+ }
+ }
+
+ private Neo4jOperationStatus mapToNeoError(String code, String message) {
+ Neo4jOperationStatus error;
+
+ String[] errorCode = code.split("\\.");
+ if (errorCode.length < 4) {
+ error = Neo4jOperationStatus.GENERAL_ERROR;
+ } else {
+ // by Classification
+ switch (errorCode[1]) {
+ case ClientError:
+ // by Category
+ switch (errorCode[2]) {
+ case General:
+ error = Neo4jOperationStatus.DB_READ_ONLY;
+ break;
+ case LegacyIndex:
+ error = Neo4jOperationStatus.LEGACY_INDEX_ERROR;
+ break;
+ case Request:
+ error = Neo4jOperationStatus.BAD_REQUEST;
+ break;
+ case Schema:
+ if (errorCode[3].equals(ConstraintViolation)) {
+ error = Neo4jOperationStatus.ENTITY_ALREADY_EXIST;
+ } else {
+ error = Neo4jOperationStatus.SCHEMA_ERROR;
+ }
+ break;
+ case Security:
+ error = Neo4jOperationStatus.NOT_AUTHORIZED;
+ break;
+ case Statement:
+ // by Title
+ if (errorCode[3].equals(EntityNotFound)) {
+ error = Neo4jOperationStatus.NOT_FOUND;
+ } else {
+ if (errorCode[3].equals(ConstraintViolation)) {
+ error = Neo4jOperationStatus.ENTITY_ALREADY_EXIST;
+ } else {
+ error = Neo4jOperationStatus.BAD_REQUEST;
+ }
+ }
+ break;
+ case Transaction:
+ error = Neo4jOperationStatus.TRANSACTION_ERROR;
+ break;
+ default:
+ error = Neo4jOperationStatus.GENERAL_ERROR;
+ break;
+ }
+ break;
+ case DatabaseError:
+ // by Category
+ switch (errorCode[2]) {
+ case General:
+ error = Neo4jOperationStatus.GENERAL_ERROR;
+ break;
+ case Schema:
+ error = Neo4jOperationStatus.SCHEMA_ERROR;
+ break;
+ case Statement:
+ error = Neo4jOperationStatus.EXECUTION_FAILED;
+ break;
+ case Transaction:
+ error = Neo4jOperationStatus.TRANSACTION_ERROR;
+ break;
+ default:
+ error = Neo4jOperationStatus.GENERAL_ERROR;
+ break;
+ }
+ break;
+ case TransientError:
+ error = Neo4jOperationStatus.DB_NOT_AVAILABLE;
+ break;
+ default:
+ error = Neo4jOperationStatus.GENERAL_ERROR;
+ break;
+ }
+ error.setOriginError(code).setMessage(message);
+ String errorFromCfg = code.replace(".", "_");
+ String helpMessage = ConfigurationManager.getConfigurationManager().getNeo4jErrorsConfiguration()
+ .getErrorMessage(errorFromCfg);
+ if (helpMessage != null && !helpMessage.isEmpty()) {
+ error.setHelpErrorMsg(helpMessage);
+ }
+ }
+ return error;
+ }
+
+ private String prepareCreateNodeBody(GraphNode node) {
+
+ String body = CypherTemplates.CypherCreateNodeTemplate.replace("$label$", node.getLabel());
+
+ body = body.replace("$props$", DaoUtils.convertToJson(node.toGraphMap()));
+
+ return body;
+ }
+
+ /**
+ * the method returns all the indexes for the given label if no label is
+ * supplied ( null or "") all indexes will be returned
+ *
+ * @param label
+ * the name of the label
+ * @param ip
+ * @param user
+ * @param password
+ * @return a map of labels and there properties
+ */
+ public Either<Map<String, List<String>>, Neo4jOperationStatus> getIndexes(String label) {
+ Map<String, Object> neo4jParams = ConfigurationManager.getConfigurationManager().getConfiguration().getNeo4j();
+ String host = (String) neo4jParams.get("host");
+ Integer port = (Integer) neo4jParams.get("port");
+ String user = (String) neo4jParams.get("user");
+ String password = (String) neo4jParams.get("password");
+
+ String uri = null;
+ if (label == null || "".equals(label)) {
+ uri = CypherTemplates.getAllIndexsTemplate.replace("$host$", host);
+ } else {
+ uri = CypherTemplates.getAllIndexsTemplate.replace("$host$", host) + "/" + label;
+ }
+ uri = uri.replace("$port$", port.toString());
+
+ HttpClientContext context = creatClientContext(host, user, password);
+ CloseableHttpResponse response = null;
+
+ HttpGet get = new HttpGet(uri);
+ get.setHeader("Content-Type", "application/json");
+ get.setHeader("Accept", "application/json; charset=UTF-8");
+
+ try {
+
+ response = httpClient.execute(get, context);
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != 200) {
+ logger.error("failed to get indexes requeste returned {}", statusCode);
+ return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
+ } else {
+ Map<String, List<String>> labels = getLeablesFromJson(response);
+ return Either.left(labels);
+ }
+ } catch (Exception e) {
+ logger.debug("failed to get indexes ", e);
+ return Either.right(Neo4jOperationStatus.GENERAL_ERROR);
+ } finally {
+ releaseResource(response);
+
+ }
+
+ }
+
+ private Map<String, List<String>> getLeablesFromJson(CloseableHttpResponse response)
+ throws HttpResponseException, IOException, ParseException {
+ Map<String, List<String>> labels = new HashMap<>();
+ String responseString = new BasicResponseHandler().handleResponse(response);
+ JSONArray results = (JSONArray) jsonParser.parse(responseString);
+ Iterator<JSONObject> iteratorResults = results.iterator();
+ while (iteratorResults.hasNext()) {
+ JSONObject elementResult = iteratorResults.next();
+ String label = (String) elementResult.get("label");
+ List<String> props = labels.get(label);
+ if (props == null) {
+ props = new ArrayList<>();
+ labels.put(label, props);
+ }
+ JSONArray properties = (JSONArray) elementResult.get("property_keys");
+ Iterator<String> iterator = properties.iterator();
+ while (iterator.hasNext()) {
+ props.add(iterator.next());
+ }
+ }
+ return labels;
+ }
+
+ public Neo4jOperationStatus createIndex(String label, List<String> propertyNames) {
+
+ Neo4jOperationStatus result = Neo4jOperationStatus.OK;
+ if (propertyNames != null && !propertyNames.isEmpty()) {
+
+ Map<String, Object> neo4jParams = ConfigurationManager.getConfigurationManager().getConfiguration()
+ .getNeo4j();
+ String host = (String) neo4jParams.get("host");
+ Integer port = (Integer) neo4jParams.get("port");
+ String user = (String) neo4jParams.get("user");
+ String password = (String) neo4jParams.get("password");
+
+ String uri = CypherTemplates.batchTemplate.replace("$host$", host);
+ uri = uri.replace("$port$", port.toString());
+
+ String opertionUri = "/schema/index/" + label;
+
+ HttpClientContext context = creatClientContext(host, user, password);
+
+ CloseableHttpResponse response = null;
+
+ HttpPost post = new HttpPost(uri);
+
+ String json = createBatchJson(HttpMethod.POST, opertionUri, propertyNames);
+
+ try {
+ StringEntity input = new StringEntity(json);
+ input.setContentType("application/json");
+ post.setEntity(input);
+ response = httpClient.execute(post, context);
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != 200) {
+ logger.error("failed to create index for label [{}] with properties:{} requeste returned {}",label,propertyNames,statusCode);
+ result = Neo4jOperationStatus.GENERAL_ERROR;
+ } else {
+ logger.debug("index for label [{}] with properties: {} created", label, propertyNames);
+ }
+ } catch (Exception e) {
+ logger.debug("failed to create index for label [{}] with properties: {}", label, propertyNames);
+ result = Neo4jOperationStatus.GENERAL_ERROR;
+ } finally {
+
+ releaseResource(response);
+
+ }
+
+ }
+
+ else {
+ logger.debug("no index was created for label :{} the recived propertyNames list: {} is invalide",label,propertyNames);
+ return Neo4jOperationStatus.WRONG_INPUT;
+ }
+
+ return result;
+ }
+
+ public Neo4jOperationStatus createUniquenessConstraints(String label, List<String> propertyNames) {
+ Neo4jOperationStatus result = Neo4jOperationStatus.OK;
+ if (propertyNames != null && !propertyNames.isEmpty()) {
+
+ Map<String, Object> neo4jParams = ConfigurationManager.getConfigurationManager().getConfiguration()
+ .getNeo4j();
+ String host = (String) neo4jParams.get("host");
+ Integer port = (Integer) neo4jParams.get("port");
+ String user = (String) neo4jParams.get("user");
+ String password = (String) neo4jParams.get("password");
+
+ String uri = CypherTemplates.batchTemplate.replace("$host$", host);
+ uri = uri.replace("$port$", port.toString());
+
+ String opertionUri = "/schema/constraint/" + label + "/uniqueness/";
+
+ HttpClientContext context = creatClientContext(host, user, password);
+
+ CloseableHttpResponse response = null;
+
+ HttpPost post = new HttpPost(uri);
+
+ String json = createBatchJson(HttpMethod.POST, opertionUri, propertyNames);
+
+ try {
+ StringEntity input = new StringEntity(json);
+ input.setContentType("application/json");
+ post.setEntity(input);
+ response = httpClient.execute(post, context);
+
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != 200) {
+ logger.error("failed to create uniqueness constraint for label [{}] on properties:{}. request returned ",
+ label,propertyNames,statusCode);
+ result = Neo4jOperationStatus.GENERAL_ERROR;
+ } else {
+ logger.debug("uniqueness constraint for label [{}] on properties:{} created",label,propertyNames);
+ }
+ } catch (Exception e) {
+ logger.error("failed to create uniqueness constraint [{}] with properties:{}",label,propertyNames,e);
+ result = Neo4jOperationStatus.GENERAL_ERROR;
+ } finally {
+ releaseResource(response);
+ }
+
+ }
+
+ else {
+ logger.debug("no index was created for label :{} the recived propertyNames list: {} is invalide",label,propertyNames);
+ return Neo4jOperationStatus.WRONG_INPUT;
+ }
+
+ return result;
+ }
+
+ public Neo4jOperationStatus deleteElement(GraphElementTypeEnum type, String label, MatchFilter filter) {
+
+ String requestJson;
+ // replace return type
+ if (type.equals(GraphElementTypeEnum.Node)) {
+ logger.debug("removing node label: {}", label);
+ requestJson = createDeleteNodeStatment(label, filter);
+
+ } else {
+ logger.error(" delete on type {} is not yet supported", type);
+ throw new RuntimeException(" delete on type " + type + " is not yet supported");
+ }
+
+ logger.debug("Try to perform request [{}]", requestJson);
+
+ Either<String, Neo4jOperationStatus> status = sendPostCypher(requestJson);
+ if (status.isRight()) {
+ logger.error(" delete request failed with: {}", status.right());
+ return Neo4jOperationStatus.GENERAL_ERROR;
+ } else {
+ return Neo4jOperationStatus.OK;
+ }
+ }
+
+ public String getNeo4jVersion() throws Exception {
+ Map<String, Object> neo4jParams = ConfigurationManager.getConfigurationManager().getConfiguration().getNeo4j();
+ String host = (String) neo4jParams.get("host");
+ Integer port = (Integer) neo4jParams.get("port");
+ String user = (String) neo4jParams.get("user");
+ String password = (String) neo4jParams.get("password");
+
+ String uri = getServiceRoot.replace("$host$", host).replace("$port$", port.toString());
+
+ HttpClientContext context = creatClientContext(host, user, password);
+ CloseableHttpResponse response = null;
+ String result = null;
+
+ HttpGet get = new HttpGet(uri);
+ get.setHeader("Content-Type", "application/json");
+ get.setHeader("Accept", "application/json; charset=UTF-8");
+
+ try {
+ response = httpClient.execute(get, context);
+ int statusCode = response.getStatusLine().getStatusCode();
+ if (statusCode != 200) {
+ throw new Exception("Couldn't get Neo4j service root, HTTP status " + statusCode);
+ } else {
+ // Parse response
+ String responseString = new BasicResponseHandler().handleResponse(response);
+ JSONObject responseData = (JSONObject) jsonParser.parse(responseString);
+ Object obj = responseData.get("neo4j_version");
+ if (obj != null) {
+ result = (String) obj;
+ }
+ return result;
+ }
+ } finally {
+ releaseResource(response);
+ }
+ }
+
+ private String createDeleteNodeStatment(String label, MatchFilter filter) {
+ String requestJson;
+ requestJson = CypherTemplates.CypherDeleteNodeTemplate;
+
+ if (label != null && !label.isEmpty()) {
+ requestJson = requestJson.replace("$label$", label);
+ } else {
+ requestJson = requestJson.replace("$label$", "");
+ }
+
+ // replace filter
+ if (filter.getProperties().isEmpty()) {
+ // get all records by label
+ requestJson = requestJson.replace("{$filter$}", "");
+ } else {
+ String filterStr = CypherTranslator.prepareFilterBody(filter);
+ requestJson = requestJson.replace("$filter$", filterStr);
+ }
+ return requestJson;
+ }
+
+ /*
+ * removed do to fortify scan CredentialsProvider cp = new
+ * BasicCredentialsProvider(); cp.setCredentials(AuthScope.ANY, new
+ * UsernamePasswordCredentials(user, password)); AuthCache authCache = new
+ * BasicAuthCache(); BasicScheme basicAuth = new BasicScheme();
+ * authCache.put(new HttpHost(ip, 7474, "http"), basicAuth);
+ * context.setAuthCache(authCache); context.setCredentialsProvider(cp);
+ *
+ */
+ private HttpClientContext creatClientContext(String ip, String user, String password) {
+
+ return HttpClientContext.create();
+ }
+
+ private void releaseResource(CloseableHttpResponse response) {
+ if (response != null) {
+ try {
+ HttpEntity entity = response.getEntity();
+ EntityUtils.consume(entity);
+ response.close();
+ } catch (Exception e) {
+ logger.error("failed to close connection exception", e);
+ }
+ }
+ }
+
+ private String createBatchJson(HttpMethod method, String opertionUri, List<String> propertyNames) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("[ ");
+ for (int i = 0; i < propertyNames.size(); i++) {
+ sb.append("{ \"method\" : \"" + method + "\" , \"to\" : \"" + opertionUri
+ + "\" , \"body\" : { \"property_keys\" : [ \"" + propertyNames.get(i) + "\" ] } }");
+ if (i + 1 < propertyNames.size()) {
+ sb.append(",");
+ }
+ }
+ sb.append(" ]");
+ return sb.toString();
+ }
+
+ enum HttpMethod {
+ GET, PUT, POST, DELETE
+ }
+
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jEdge.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jEdge.java
new file mode 100644
index 0000000000..bdd17b6512
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jEdge.java
@@ -0,0 +1,69 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j;
+
+import org.openecomp.sdc.be.dao.graph.datatype.ActionEnum;
+
+import java.util.Map;
+
+public class Neo4jEdge {
+
+ private GraphEdgeLabels edgeType;
+ private Map<String, Object> properties;
+ private ActionEnum action;
+
+ public Neo4jEdge(GraphEdgeLabels edgeType, Map<String, Object> properties, ActionEnum actionEnum) {
+ super();
+ this.edgeType = edgeType;
+ this.properties = properties;
+ this.action = actionEnum;
+ }
+
+ public GraphEdgeLabels getEdgeType() {
+ return edgeType;
+ }
+
+ public void setEdgeType(GraphEdgeLabels edgeType) {
+ this.edgeType = edgeType;
+ }
+
+ public Map<String, Object> getProperties() {
+ return properties;
+ }
+
+ public void setProperties(Map<String, Object> properties) {
+ this.properties = properties;
+ }
+
+ public ActionEnum getAction() {
+ return action;
+ }
+
+ public void setAction(ActionEnum action) {
+ this.action = action;
+ }
+
+ @Override
+ public String toString() {
+ return "Neo4jEdge [edgeType=" + edgeType + ", properties=" + properties + ", action=" + action + "]";
+ }
+
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jGraphBatchBuilder.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jGraphBatchBuilder.java
new file mode 100644
index 0000000000..f28baf0017
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jGraphBatchBuilder.java
@@ -0,0 +1,179 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j;
+
+import fj.data.Either;
+import org.openecomp.sdc.be.dao.graph.datatype.*;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+import org.openecomp.sdc.common.log.wrappers.Logger;
+
+import java.util.*;
+
+public class Neo4jGraphBatchBuilder {
+
+ private static Logger logger = Logger.getLogger(Neo4jGraphBatchBuilder.class.getName());
+
+ public Either<BatchBuilder, Neo4jOperationStatus> buildBatchBuilderFromTable(
+ GraphNeighbourTable graphNeighbourTable) {
+
+ logger.debug("The table sent in order to build BatchBuilder is {}", graphNeighbourTable);
+
+ List<GraphNode> nodes = graphNeighbourTable.getNodes();
+ if (nodes != null && nodes.size() > 0) {
+ List<NodeRelation> directedEdges = graphNeighbourTable.getDirectedEdges();
+
+ List<RelationEndPoint> relationEndPoints = new ArrayList<>(nodes.size());
+ Set<Integer> nodesInRelations = findDistinctNodesIndex(directedEdges);
+
+ buildRelationEndPoints(nodes, nodesInRelations, relationEndPoints);
+
+ BatchBuilder batchBuilder = BatchBuilder.getBuilder();
+
+ for (GraphElement neo4jElement : nodes) {
+ if (neo4jElement.getAction() != ActionEnum.Delete) {
+ logger.debug("Goint to add node {} to batch builder.", neo4jElement);
+ batchBuilder.add(neo4jElement);
+ }
+ }
+
+ if (directedEdges != null) {
+ for (NodeRelation nodeRelation : directedEdges) {
+ GraphRelation relation = buildNeo4jRelation(relationEndPoints, nodeRelation);
+ logger.debug("Goint to add relation {} to batch builder.", relation);
+ batchBuilder.add(relation);
+ }
+ }
+
+ for (GraphElement neo4jElement : nodes) {
+ if (neo4jElement.getAction() == ActionEnum.Delete) {
+ logger.debug("Goint to add node {} to batch builder.", neo4jElement);
+ batchBuilder.add(neo4jElement);
+ }
+ }
+
+ return Either.left(batchBuilder);
+
+ } else {
+ logger.error("No node was sent in order to create the resource.");
+ return Either.right(Neo4jOperationStatus.BAD_REQUEST);
+ }
+ }
+
+ private Pair<String, String> getUniqueIdKeyValue(GraphNode neo4jNode) {
+
+ // String label = neo4jNode.getLabel();
+ // NodeTypeEnum nodeTypeEnum = NodeTypeEnum.getByName(label);
+ //
+ return Pair.createPair(neo4jNode.getUniqueIdKey(), neo4jNode.getUniqueId().toString());
+ }
+
+ private Set<Integer> findDistinctNodesIndex(List<NodeRelation> directedEdges) {
+
+ HashSet<Integer> nodesIndex = new HashSet<>();
+
+ if (directedEdges != null) {
+ for (NodeRelation nodeRelation : directedEdges) {
+ nodesIndex.add(nodeRelation.getFromIndex());
+ nodesIndex.add(nodeRelation.getToIndex());
+ }
+ }
+
+ return nodesIndex;
+ }
+
+ private String findResourceDataIdFromNodes(List<GraphNode> nodes) {
+
+ if (nodes != null) {
+
+ for (GraphNode neo4jNode : nodes) {
+ String label = neo4jNode.getLabel();
+ if (label.equals(NodeTypeEnum.Resource.getName())) {
+ return neo4jNode.getUniqueId().toString();
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private GraphRelation buildNeo4jRelation(List<RelationEndPoint> relationEndPoints, NodeRelation nodeRelation) {
+ GraphRelation relation = new GraphRelation();
+ int fromIndex = nodeRelation.getFromIndex();
+ int toIndex = nodeRelation.getToIndex();
+ Neo4jEdge neo4jEdge = nodeRelation.getEdge();
+ relation.setFrom(relationEndPoints.get(fromIndex));
+ relation.setTo(relationEndPoints.get(toIndex));
+ relation.setType(neo4jEdge.getEdgeType().getProperty());
+
+ // TODO: fix it after change
+ Map<String, Object> edgeProps = neo4jEdge.getProperties();
+ if (edgeProps != null && !edgeProps.isEmpty()) {
+ relation.addPropertis(edgeProps);
+ }
+
+ relation.setAction(neo4jEdge.getAction());
+ return relation;
+ }
+
+ private void buildRelationEndPoints(List<GraphNode> nodes, Set<Integer> nodesInRelations,
+ List<RelationEndPoint> relationEndPoints) {
+
+ if (nodesInRelations != null) {
+ for (Integer nodeIndex : nodesInRelations) {
+
+ GraphElement neo4jElement = nodes.get(nodeIndex);
+ GraphNode neo4jNode = (GraphNode) neo4jElement;
+ String label = neo4jNode.getLabel();
+ Pair<String, String> uniqueKeyValue = getUniqueIdKeyValue(neo4jNode);
+
+ RelationEndPoint endPoint = new RelationEndPoint(NodeTypeEnum.getByName(label), uniqueKeyValue.getKey(),
+ uniqueKeyValue.getValue());
+ relationEndPoints.add(nodeIndex, endPoint);
+
+ }
+ }
+
+ }
+
+ public static class Pair<K, V> {
+
+ private final K key;
+ private final V value;
+
+ public static <K, V> Pair<K, V> createPair(K key, V value) {
+ return new Pair<>(key, value);
+ }
+
+ public Pair(K key, V value) {
+ this.key = key;
+ this.value = value;
+ }
+
+ public K getKey() {
+ return key;
+ }
+
+ public V getValue() {
+ return value;
+ }
+
+ }
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jOperationStatus.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jOperationStatus.java
new file mode 100644
index 0000000000..154449b521
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jOperationStatus.java
@@ -0,0 +1,77 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j;
+
+public enum Neo4jOperationStatus {
+
+ OK, NOT_CONNECTED, NOT_AUTHORIZED, HTTP_PROTOCOL_ERROR, DB_NOT_AVAILABLE, DB_READ_ONLY, BAD_REQUEST, LEGACY_INDEX_ERROR, SCHEMA_ERROR, TRANSACTION_ERROR, EXECUTION_FAILED, ENTITY_ALREADY_EXIST,
+
+ WRONG_INPUT, GENERAL_ERROR, NOT_SUPPORTED, NOT_FOUND;
+
+ private String originError;
+ private String message;
+ private String helpErrorMsg;
+
+ private static final String NA = "NA";
+
+ Neo4jOperationStatus() {
+ originError = NA;
+ message = NA;
+ helpErrorMsg = NA;
+ }
+
+ public Neo4jOperationStatus setOriginError(String originError) {
+ this.originError = originError;
+ return this;
+ }
+
+ public Neo4jOperationStatus setMessage(String message) {
+ if (message != null && !message.isEmpty()) {
+ this.message = message;
+ }
+ return this;
+ }
+
+ public Neo4jOperationStatus setHelpErrorMsg(String helpErrorMsg) {
+ this.helpErrorMsg = helpErrorMsg;
+ return this;
+ }
+
+ public String getOriginError() {
+ return originError;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+
+ public String getHelpErrorMsg() {
+ return helpErrorMsg;
+ }
+
+ public String printError() {
+ StringBuilder sb = new StringBuilder();
+ sb.append("[").append(toString()).append("-").append(originError).append("-").append(helpErrorMsg).append("-")
+ .append(message).append("]");
+ return sb.toString();
+ }
+
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/NodeRelation.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/NodeRelation.java
new file mode 100644
index 0000000000..c1402f402f
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/NodeRelation.java
@@ -0,0 +1,65 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j;
+
+public class NodeRelation {
+
+ private int fromIndex;
+ private int toIndex;
+ private Neo4jEdge edge;
+
+ public NodeRelation(int fromIndex, int toIndex, Neo4jEdge edge) {
+ super();
+ this.fromIndex = fromIndex;
+ this.toIndex = toIndex;
+ this.edge = edge;
+ }
+
+ public int getFromIndex() {
+ return fromIndex;
+ }
+
+ public void setFromIndex(int fromIndex) {
+ this.fromIndex = fromIndex;
+ }
+
+ public int getToIndex() {
+ return toIndex;
+ }
+
+ public void setToIndex(int toIndex) {
+ this.toIndex = toIndex;
+ }
+
+ public Neo4jEdge getEdge() {
+ return edge;
+ }
+
+ public void setEdge(Neo4jEdge edge) {
+ this.edge = edge;
+ }
+
+ @Override
+ public String toString() {
+ return "NodeRelation [fromIndex=" + fromIndex + ", toIndex=" + toIndex + ", edge=" + edge + "]";
+ }
+
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/MatchFilter.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/MatchFilter.java
new file mode 100644
index 0000000000..7933efbb84
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/MatchFilter.java
@@ -0,0 +1,51 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j.filters;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class MatchFilter {
+ private Map<String, Object> toMatchProperties;
+
+ public MatchFilter() {
+ toMatchProperties = new HashMap<>();
+ }
+
+ public MatchFilter(Map<String, Object> toMatchProperties) {
+ super();
+ this.toMatchProperties = toMatchProperties;
+ }
+
+ public Map<String, Object> getProperties() {
+ return toMatchProperties;
+ }
+
+ public void setProperties(Map<String, Object> properties) {
+ this.toMatchProperties = properties;
+ }
+
+ public MatchFilter addToMatch(String propName, Object value) {
+ toMatchProperties.put(propName, value);
+ return this;
+ }
+
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/RecursiveByRelationFilter.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/RecursiveByRelationFilter.java
new file mode 100644
index 0000000000..698077d45b
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/RecursiveByRelationFilter.java
@@ -0,0 +1,81 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j.filters;
+
+import org.openecomp.sdc.be.dao.graph.datatype.GraphNode;
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+
+public class RecursiveByRelationFilter extends RecursiveFilter {
+
+ private GraphNode node;
+ private String relationType;
+
+ public RecursiveByRelationFilter() {
+ super();
+ }
+
+ public RecursiveByRelationFilter(NodeTypeEnum nodeType, GraphNode node) {
+ super(nodeType);
+ this.node = node;
+ }
+
+ public RecursiveByRelationFilter(NodeTypeEnum nodeType) {
+ super(nodeType);
+ }
+
+ public RecursiveByRelationFilter(NodeTypeEnum nodeType, GraphNode node, String relationType) {
+ super(nodeType);
+ this.node = node;
+ this.relationType = relationType;
+ }
+
+ public RecursiveByRelationFilter addNode(GraphNode node) {
+ this.node = node;
+ return this;
+ }
+
+ public RecursiveByRelationFilter addRelation(String relationType) {
+ this.relationType = relationType;
+ return this;
+ }
+
+ public GraphNode getNode() {
+ return node;
+ }
+
+ public void setNode(GraphNode node) {
+ this.node = node;
+ }
+
+ public String getRelationType() {
+ return relationType;
+ }
+
+ public void setRelationType(String relationType) {
+ this.relationType = relationType;
+ }
+
+ @Override
+ public String toString() {
+ return "RecursiveByRelationFilter [node=" + node + ", relationType=" + relationType + "]";
+ }
+
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/RecursiveFilter.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/RecursiveFilter.java
new file mode 100644
index 0000000000..6dafd51930
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/RecursiveFilter.java
@@ -0,0 +1,68 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j.filters;
+
+import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class RecursiveFilter extends MatchFilter {
+
+ private List<String> childRelationTypes;
+ NodeTypeEnum nodeType;
+
+ public RecursiveFilter() {
+ childRelationTypes = new ArrayList<>();
+ }
+
+ public RecursiveFilter(NodeTypeEnum nodeType) {
+ childRelationTypes = new ArrayList<>();
+ this.nodeType = nodeType;
+ }
+
+ public RecursiveFilter addChildRelationType(String type) {
+ childRelationTypes.add(type);
+ return this;
+ }
+
+ public List<String> getChildRelationTypes() {
+ return childRelationTypes;
+ }
+
+ public void setChildRelationTypes(List<String> childRelationTypes) {
+ this.childRelationTypes = childRelationTypes;
+ }
+
+ public NodeTypeEnum getNodeType() {
+ return nodeType;
+ }
+
+ public void setNodeType(NodeTypeEnum nodeType) {
+ this.nodeType = nodeType;
+ }
+
+ @Override
+ public String toString() {
+ return "RecursiveFilter [childRelationTypes=" + childRelationTypes + ", nodeType=" + nodeType + "]";
+ }
+
+}
diff --git a/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/UpdateFilter.java b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/UpdateFilter.java
new file mode 100644
index 0000000000..190993668d
--- /dev/null
+++ b/catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/UpdateFilter.java
@@ -0,0 +1,56 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * SDC
+ * ================================================================================
+ * 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.sdc.be.dao.neo4j.filters;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class UpdateFilter extends MatchFilter {
+
+ private Map<String, Object> toUpdate;
+
+ public UpdateFilter(Map<String, Object> toUpdate) {
+ super();
+ this.toUpdate = toUpdate;
+ }
+
+ public UpdateFilter() {
+ super();
+ toUpdate = new HashMap<>();
+ }
+
+ public UpdateFilter(Map<String, Object> toMatch, Map<String, Object> toUpdate) {
+ super(toMatch);
+ this.toUpdate = toUpdate;
+ }
+
+ public Map<String, Object> getToUpdate() {
+ return toUpdate;
+ }
+
+ public void setToUpdate(Map<String, Object> toUpdate) {
+ this.toUpdate = toUpdate;
+ }
+
+ public void addToUpdate(String property, Object value) {
+ toUpdate.put(property, value);
+ }
+}