summaryrefslogtreecommitdiffstats
path: root/aai-core/src/main/java
diff options
context:
space:
mode:
authorThreefoot, Jane (jt6620) <jt6620@att.com>2017-07-31 15:49:04 -0400
committerThreefoot, Jane (jt6620) <jt6620@att.com>2017-07-31 15:52:53 -0400
commit9941d0d8597d9d69954819ca9458962aee281b10 (patch)
treec48876e6a16b10920259287fe3ec51436f94b864 /aai-core/src/main/java
parenta9320e7933bc04954264d9f3f34b9cb904b61353 (diff)
[AAI-100 Amsterdam] refactored dbedgerules
Change-Id: I778a56f525cba0ebd39d24d366fc9f0935be71f2 Signed-off-by: Threefoot, Jane (jt6620) <jt6620@att.com>
Diffstat (limited to 'aai-core/src/main/java')
-rw-r--r--aai-core/src/main/java/org/openecomp/aai/dbgen/SchemaGenerator.java14
-rw-r--r--aai-core/src/main/java/org/openecomp/aai/dbmodel/DbEdgeRules.java45
-rw-r--r--aai-core/src/main/java/org/openecomp/aai/dbmodel/DbEdgeRulesConverter.java222
-rw-r--r--aai-core/src/main/java/org/openecomp/aai/dbmodel/EdgeRuleBean.java88
-rw-r--r--aai-core/src/main/java/org/openecomp/aai/introspection/Version.java8
-rw-r--r--aai-core/src/main/java/org/openecomp/aai/serialization/db/EdgeRule.java22
-rw-r--r--aai-core/src/main/java/org/openecomp/aai/serialization/db/EdgeRules.java285
7 files changed, 514 insertions, 170 deletions
diff --git a/aai-core/src/main/java/org/openecomp/aai/dbgen/SchemaGenerator.java b/aai-core/src/main/java/org/openecomp/aai/dbgen/SchemaGenerator.java
index 63606017..c5186b01 100644
--- a/aai-core/src/main/java/org/openecomp/aai/dbgen/SchemaGenerator.java
+++ b/aai-core/src/main/java/org/openecomp/aai/dbgen/SchemaGenerator.java
@@ -96,16 +96,12 @@ public class SchemaGenerator{
Multimap<String, EdgeRule> edges = null;
Set<String> labels = new HashSet<>();
- try {
- edges = EdgeRules.getInstance().getAllRules();
- for (EdgeRule rule : edges.values()) {
- labels.add(rule.getLabel());
- }
- } catch (AAIException e) {
- LOGGER.error("could not get edge rules", e);
- System.out.println("could not get edge rules");
- System.exit(1);
+
+ edges = EdgeRules.getInstance().getAllRules();
+ for (EdgeRule rule : edges.values()) {
+ labels.add(rule.getLabel());
}
+
for( String label: labels){
if( graphMgmt.containsRelationType(label) ) {
String dmsg = " EdgeLabel [" + label + "] already existed. ";
diff --git a/aai-core/src/main/java/org/openecomp/aai/dbmodel/DbEdgeRules.java b/aai-core/src/main/java/org/openecomp/aai/dbmodel/DbEdgeRules.java
index f4b55504..2ab378e2 100644
--- a/aai-core/src/main/java/org/openecomp/aai/dbmodel/DbEdgeRules.java
+++ b/aai-core/src/main/java/org/openecomp/aai/dbmodel/DbEdgeRules.java
@@ -424,49 +424,4 @@ public class DbEdgeRules {
.putAll("license","THIS_NODE_ONLY")
.putAll("zone", "THIS_NODE_ONLY")
.putAll("route-target", "CASCADE_TO_CHILDREN").build();
-
- // NOTE -- Sorry, this is ugly, but we are mapping the nodeTypeCategory two
- // ways just to
- // make the code a little less bulky. But that means that we need to ensure
- // that
- // nodeTypeCategory and nodeTypeCatMap are kept in synch.
-
- // NodeTypeCategory: key is: nodeTypeCategory, value is:
- // "nodeTypes,keyProperties,AltKeyProps,depNode4UniquenessFlag"
- public static final Multimap<String, String> NodeTypeCategory = new ImmutableSetMultimap.Builder<String, String>()
- .putAll("vnf", "vce|vpe|generic-vnf,vnf-id,,true").build();
-
- // NodeTypeCatMap: key is nodeType; value is: "nodeTypeCategory"
- // So -- we're assuming that a nodeType can only be in one nodeTypeCategory.
- public static final Map<String, String> NodeTypeCatMap;
- static {
- NodeTypeCatMap = new HashMap<String, String>();
- NodeTypeCatMap.put("vpe", "vnf");
- NodeTypeCatMap.put("vce", "vnf");
- NodeTypeCatMap.put("generic-vnf", "vnf");
- }
-
- // ReservedPropNames: keys are property names of (node) properties that are
- // common to all nodes and
- // should not be removed if not passed in on an UPDATE request.
- public static final Map<String, String> ReservedPropNames;
- static {
- ReservedPropNames = new HashMap<String, String>();
- ReservedPropNames.put("source-of-truth", "");
- ReservedPropNames.put("last-mod-source-of-truth", "");
- ReservedPropNames.put("aai-created-ts", "");
- ReservedPropNames.put("aai-last-mod-ts", "");
- }
-
- // This just lists which node types can be connected to themselves recursively.
- // It's temporary - since DbEdgeRules is going to be overhauled in 16-10, this will
- // get generated automatically. But for 1607, it can work like this.
- public static final Map<String, String> CanBeRecursiveNT;
- static {
- CanBeRecursiveNT = new HashMap<String, String>();
- CanBeRecursiveNT.put("model-element", "");
- CanBeRecursiveNT.put("service-instance", "");
- CanBeRecursiveNT.put("named-query-element", "");
- }
-
}
diff --git a/aai-core/src/main/java/org/openecomp/aai/dbmodel/DbEdgeRulesConverter.java b/aai-core/src/main/java/org/openecomp/aai/dbmodel/DbEdgeRulesConverter.java
new file mode 100644
index 00000000..bbb456bd
--- /dev/null
+++ b/aai-core/src/main/java/org/openecomp/aai/dbmodel/DbEdgeRulesConverter.java
@@ -0,0 +1,222 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * 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.aai.dbmodel;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.openecomp.aai.introspection.Version;
+
+import com.google.common.collect.Multimap;
+
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import freemarker.template.TemplateException;
+import freemarker.template.TemplateExceptionHandler;
+
+/**
+ * Converts the old DbEdgeRules multimap to new json format
+ */
+public class DbEdgeRulesConverter {
+ private static final int LABEL = 0;
+ private static final int DIRECTION = 1;
+ private static final int MULTIPLICITY = 2;
+ private static final int ISPARENT = 3;
+ private static final int USESRESOURCE = 4;
+ private static final int HASDELTARGET = 5;
+ private static final int SVCINFRA = 6;
+
+ private Configuration config = new Configuration();
+ private Template template;
+ private String destDirectory;
+ private FileOutputStream writeStream;
+
+ public DbEdgeRulesConverter(){ /*pretty much just so I can test functionality without dealing with template setup*/ }
+
+ public DbEdgeRulesConverter(String destinationDir) {
+ destDirectory = destinationDir;
+ try {
+ setup(destinationDir);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Sets up the freemarker template and the directory to be written to. Run this once before
+ * doing any converting, does not need to be run per file generated (unless you want different directories for each file).
+ *
+ * @param destinationDir - String of the path to the directory where you want the new format files written to,
+ * relative to aai-core/
+ * @throws IOException if it can't find the template loading directory or the template file itself
+ */
+ public void setup(String destinationDir) throws IOException {
+ config.setDirectoryForTemplateLoading(new File("src/main/resources/dbedgerules/conversion"));
+ config.setDefaultEncoding("UTF-8");
+ config.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
+ template = config.getTemplate("edgerulesTemplate.ftlh");
+
+ File destination = new File(destinationDir);
+ if (!destination.exists()) {
+ destination.mkdir();
+ }
+ }
+
+ /**
+ * Converts the given DbEdgeRules multimap representation into a json file of the new format.
+ *
+ * @param rules - a Multimap<String, String> of the old DbEdgeRules format
+ * @param writer - writes to the output file (designate that file when you instantiate the writer)
+ */
+ public void convert(Multimap<String, String> rules, Writer writer) {
+
+ List<EdgeRuleBean> rulesToWrite = new ArrayList<>();
+ for (Entry<String, String> rule : rules.entries()) {
+ rulesToWrite.add(extractData(rule));
+ }
+ Map<String, List<EdgeRuleBean>> wrappedRules = new HashMap<>();
+ wrappedRules.put("wrappedRules", rulesToWrite);
+ try {
+ template.process(wrappedRules, writer);
+ } catch (TemplateException e) {
+ System.out.println("Something went wrong when trying to combine the data and the template");
+ e.printStackTrace();
+ } catch (IOException e) {
+ System.out.println("There was a problem writing to the output file");
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Extracts the pieces of information that go in each field of the new json format from the old
+ * DbEdgeRules format.
+ *
+ * @param rule - one <String, String> entry from the DbEdgeRules multimap representation
+ * Takes the form <"from-node|to-node", "label,direction,multiplicity,isParent,usesResource,hasDelTarget,svc-infra">
+ * @return EdgeRuleBean with the pieces of information the template needs, in a format the template can understand
+ */
+ public EdgeRuleBean extractData(Entry<String, String> rule){
+ EdgeRuleBean data = new EdgeRuleBean();
+
+ String oldName = rule.getKey();
+ String[] nodes = oldName.split("\\|");
+ data.setFrom(nodes[0]);
+ data.setTo(nodes[1]);
+
+ String oldSpecs = rule.getValue();
+ String[] specs = oldSpecs.split(",");
+ data.setLabel(specs[LABEL]);
+ data.setDirection(specs[DIRECTION]);
+ data.setMultiplicity(specs[MULTIPLICITY]);
+ data.setParent(specs[ISPARENT]);
+ data.setUsesResource(specs[USESRESOURCE]);
+ data.setHasDelTarget(specs[HASDELTARGET]);
+ data.setSvcInfra(specs[SVCINFRA]);
+
+ return data;
+ }
+
+ private Multimap<String, String> getEdgeRules(Version v) {
+ try {
+ Class <?> dbEdgeRules;
+ //use reflection to get the corresponding DbEdgeRules class
+ //need this weird if-else bc current version doesn't sit in a v.gen subdirectory
+ if (Version.isLatest(v)) {
+ dbEdgeRules = Class.forName("org.openecomp.aai.dbmodel.DbEdgeRules");
+ } else {
+ dbEdgeRules = Class.forName("org.openecomp.aai.dbmodel." + v + ".gen.DbEdgeRules");
+ }
+
+ @SuppressWarnings("unchecked")
+ Multimap<String, String> rules = (Multimap<String,String>)dbEdgeRules.getDeclaredField("EdgeRules").get(null);
+
+ return rules;
+ } catch (ClassNotFoundException e) {
+ System.out.println("could not find DbEdgeRules class for version " + v);
+ e.printStackTrace();
+ return null;
+ } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
+ System.out.println("Something went wrong trying to retrieve the rules");
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ private Writer buildOutputWriter(Version v) {
+ try {
+ File output = new File(destDirectory + "DbEdgeRules_" + v + ".json");
+ writeStream = new FileOutputStream(output);
+ return new OutputStreamWriter(writeStream);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ /**
+ * Runs all the conversion steps for the specified version.
+ *
+ * @param v
+ */
+ public void convertVersion(Version v) {
+ try {
+ Multimap<String, String> rules = getEdgeRules(v);
+ if (rules == null) { //something went wrong, we've already logged it in the helper so just stop execution
+ return;
+ }
+
+ Writer writer = buildOutputWriter(v);
+ if (writer == null) { //something went wrong, we've already logged it in the helper so just stop execution
+ return;
+ }
+ convert(rules, writer);
+
+ writer.close();
+ writeStream.close();
+ } catch (IOException e) {
+ System.out.println("Something went wrong closing the writer/writestream");
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Runs the converter for each DbEdgeRules version currently supported (2, 7, 8, 9, and 10)
+ *
+ * @param args - none actually
+ */
+ public static void main(String[] args) {
+ String destDirectory = "src/main/resources/dbedgerules/";
+ DbEdgeRulesConverter dberConverter = new DbEdgeRulesConverter(destDirectory);
+
+ for (Version v : Version.values()) {
+ dberConverter.convertVersion(v);
+ }
+ }
+}
diff --git a/aai-core/src/main/java/org/openecomp/aai/dbmodel/EdgeRuleBean.java b/aai-core/src/main/java/org/openecomp/aai/dbmodel/EdgeRuleBean.java
new file mode 100644
index 00000000..f80bbca9
--- /dev/null
+++ b/aai-core/src/main/java/org/openecomp/aai/dbmodel/EdgeRuleBean.java
@@ -0,0 +1,88 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * org.openecomp.aai
+ * ================================================================================
+ * 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.aai.dbmodel;
+
+public class EdgeRuleBean {
+ private String from;
+ private String to;
+ private String label;
+ private String direction;
+ private String multiplicity;
+ private String isParent;
+ private String usesResource;
+ private String hasDelTarget;
+ private String svcInfra;
+
+ public String getFrom() {
+ return from;
+ }
+ public void setFrom(String from) {
+ this.from = from;
+ }
+ public String getTo() {
+ return to;
+ }
+ public void setTo(String to) {
+ this.to = to;
+ }
+ public String getLabel() {
+ return label;
+ }
+ public void setLabel(String label) {
+ this.label = label;
+ }
+ public String getDirection() {
+ return direction;
+ }
+ public void setDirection(String direction) {
+ this.direction = direction;
+ }
+ public String getMultiplicity() {
+ return multiplicity;
+ }
+ public void setMultiplicity(String multiplicity) {
+ this.multiplicity = multiplicity;
+ }
+ public String getIsParent() {
+ return isParent;
+ }
+ public void setParent(String isParent) {
+ this.isParent = isParent;
+ }
+ public String getUsesResource() {
+ return usesResource;
+ }
+ public void setUsesResource(String usesResource) {
+ this.usesResource = usesResource;
+ }
+ public String getHasDelTarget() {
+ return hasDelTarget;
+ }
+ public void setHasDelTarget(String hasDelTarget) {
+ this.hasDelTarget = hasDelTarget;
+ }
+ public String getSvcInfra() {
+ return svcInfra;
+ }
+ public void setSvcInfra(String svcInfra) {
+ this.svcInfra = svcInfra;
+ }
+}
diff --git a/aai-core/src/main/java/org/openecomp/aai/introspection/Version.java b/aai-core/src/main/java/org/openecomp/aai/introspection/Version.java
index b0f6f55d..8c7998b5 100644
--- a/aai-core/src/main/java/org/openecomp/aai/introspection/Version.java
+++ b/aai-core/src/main/java/org/openecomp/aai/introspection/Version.java
@@ -25,4 +25,12 @@ public enum Version {
v9,
v10,
v11;
+
+ public static boolean isLatest(Version v) {
+ return (Version.v11.equals(v)); //TODO update when we increment the version, or find a better way of doing this
+ }
+
+ public static Version getLatest(){
+ return Version.v11; //TODO update when we increment the version, or find a better way of doing this
+ }
}
diff --git a/aai-core/src/main/java/org/openecomp/aai/serialization/db/EdgeRule.java b/aai-core/src/main/java/org/openecomp/aai/serialization/db/EdgeRule.java
index 6d0acc6a..12548f9c 100644
--- a/aai-core/src/main/java/org/openecomp/aai/serialization/db/EdgeRule.java
+++ b/aai-core/src/main/java/org/openecomp/aai/serialization/db/EdgeRule.java
@@ -70,6 +70,18 @@ public class EdgeRule {
return multiplicityRule;
}
+ public void setMultiplicityRule(String multiplicity){
+ if ("Many2Many".equalsIgnoreCase(multiplicity)) {
+ this.multiplicityRule = MultiplicityRule.MANY2MANY;
+ } else if ("One2Many".equalsIgnoreCase(multiplicity)) {
+ this.multiplicityRule = MultiplicityRule.ONE2MANY;
+ } else if ("One2One".equalsIgnoreCase(multiplicity)) {
+ this.multiplicityRule = MultiplicityRule.ONE2ONE;
+ } else { //should be "Many2One"
+ this.multiplicityRule = MultiplicityRule.MANY2ONE;
+ }
+ }
+
/**
* Sets the multiplicity rule.
*
@@ -88,6 +100,16 @@ public class EdgeRule {
return direction;
}
+ public void setDirection(String direction){
+ if ("OUT".equalsIgnoreCase(direction)) {
+ this.direction = Direction.OUT;
+ } else if ("IN".equalsIgnoreCase(direction)) {
+ this.direction = Direction.IN;
+ } else {
+ this.direction = Direction.BOTH;
+ }
+ }
+
/**
* Sets the direction.
*
diff --git a/aai-core/src/main/java/org/openecomp/aai/serialization/db/EdgeRules.java b/aai-core/src/main/java/org/openecomp/aai/serialization/db/EdgeRules.java
index 9e4e8396..7f925a16 100644
--- a/aai-core/src/main/java/org/openecomp/aai/serialization/db/EdgeRules.java
+++ b/aai-core/src/main/java/org/openecomp/aai/serialization/db/EdgeRules.java
@@ -20,13 +20,16 @@
package org.openecomp.aai.serialization.db;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.Collection;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.structure.Direction;
@@ -36,32 +39,49 @@ import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.openecomp.aai.db.props.AAIProperties;
import org.openecomp.aai.dbmodel.DbEdgeRules;
import org.openecomp.aai.exceptions.AAIException;
+import org.openecomp.aai.introspection.Version;
import org.openecomp.aai.serialization.db.exceptions.EdgeMultiplicityException;
import org.openecomp.aai.serialization.db.exceptions.NoEdgeRuleFoundException;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
+import com.jayway.jsonpath.JsonPath;
-public class EdgeRules {
+import static com.jayway.jsonpath.Filter.filter;
+import static com.jayway.jsonpath.Criteria.where;
+
+import com.jayway.jsonpath.DocumentContext;
+import com.jayway.jsonpath.Filter;
+
+import java.util.Scanner;
- private Multimap<String, String> rules = DbEdgeRules.EdgeRules;
+public class EdgeRules {
+
+ private EELFLogger logger = EELFManager.getInstance().getLogger(EdgeRules.class);
+
private Multimap<String, String> deleteScope = DbEdgeRules.DefaultDeleteScope;
- private final int EDGE_NAME = 0;
- private final int DIRECTION = 1;
- private final int MULTIPLICITY_RULE = 2;
- private final int IS_PARENT = 3;
- private final int USES_RESOURCE = 4;
- private final int HAS_DEL_TARGET = 5;
- private final int SVC_INFRA = 6;
+
+ private DocumentContext rulesDoc;
/**
- * Instantiates a new edge rules.
+ * Loads the most recent DbEdgeRules json file for later parsing.
+ * Only need most recent version for actual A&AI operations that call this class;
+ * the old ones are only used in tests.
*/
private EdgeRules() {
-
+
+ InputStream is = getClass().getResourceAsStream("/dbedgerules/DbEdgeRules_" + Version.getLatest().toString() + ".json");
+
+ Scanner scanner = new Scanner(is);
+ String json = scanner.useDelimiter("\\Z").next();
+ scanner.close();
+ rulesDoc = JsonPath.parse(json);
}
+
private static class Helper {
private static final EdgeRules INSTANCE = new EdgeRules();
-
}
/**
@@ -81,7 +101,6 @@ public class EdgeRules {
* @param bVertex the in vertex
* @return the edge
* @throws AAIException the AAI exception
- * @throws NoEdgeRuleFoundException
*/
public Edge addTreeEdge(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex) throws AAIException {
return this.addEdge(EdgeType.TREE, traversalSource, aVertex, bVertex, false);
@@ -94,7 +113,6 @@ public class EdgeRules {
* @param bVertex the in vertex
* @return the edge
* @throws AAIException the AAI exception
- * @throws NoEdgeRuleFoundException
*/
public Edge addEdge(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex) throws AAIException {
return this.addEdge(EdgeType.COUSIN, traversalSource, aVertex, bVertex, false);
@@ -107,7 +125,6 @@ public class EdgeRules {
* @param bVertex the in vertex
* @return the edge
* @throws AAIException the AAI exception
- * @throws NoEdgeRuleFoundException
*/
public Edge addTreeEdgeIfPossible(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex) throws AAIException {
return this.addEdge(EdgeType.TREE, traversalSource, aVertex, bVertex, true);
@@ -120,7 +137,6 @@ public class EdgeRules {
* @param bVertex the in vertex
* @return the edge
* @throws AAIException the AAI exception
- * @throws NoEdgeRuleFoundException
*/
public Edge addEdgeIfPossible(GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex) throws AAIException {
return this.addEdge(EdgeType.COUSIN, traversalSource, aVertex, bVertex, true);
@@ -134,9 +150,8 @@ public class EdgeRules {
* @param bVertex the in vertex
* @return the edge
* @throws AAIException the AAI exception
- * @throws NoEdgeRuleFoundException
*/
- private Edge addEdge(EdgeType type, GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex, boolean isBestEffort) throws AAIException, NoEdgeRuleFoundException {
+ private Edge addEdge(EdgeType type, GraphTraversalSource traversalSource, Vertex aVertex, Vertex bVertex, boolean isBestEffort) throws AAIException {
EdgeRule rule = this.getEdgeRule(type, aVertex, bVertex);
@@ -192,35 +207,53 @@ public class EdgeRules {
}
/**
- * Checks for edge rule.
+ * Checks if any edge rules exist between the two given nodes, in either A|B or B|A order.
*
- * @param outType the out type
- * @param inType the in type
- * @return true, if successful
+ * @param nodeA - node at one end of the edge
+ * @param nodeB - node at the other end
+ * @return true, if any such rules exist
*/
- public boolean hasEdgeRule(String outType, String inType) {
+ public boolean hasEdgeRule(String nodeA, String nodeB) {
+ Filter aToB = filter(
+ where("from").is(nodeA).and("to").is(nodeB)
+ );
+ Filter bToA = filter(
+ where("from").is(nodeB).and("to").is(nodeA)
+ );
- Collection<String> collection = rules.get(outType + "|" + inType);
+ List<Object> results = rulesDoc.read("$.rules.[?]", aToB);
+ results.addAll(rulesDoc.read("$.rules.[?]", bToA));
- return !collection.isEmpty();
+ return !results.isEmpty();
}
/**
- * Checks for edge rule.
+ * Checks if any edge rules exist between the two given nodes, in either A|B or B|A order.
*
- * @param aVertex the out vertex
- * @param bVertex the in vertex
- * @return true, if successful
+ * @param aVertex - node at one end of the edge
+ * @param bVertex - node at the other end
+ * @return true, if any such rules exist
*/
public boolean hasEdgeRule(Vertex aVertex, Vertex bVertex) {
- String outType = (String)aVertex.<String>property("aai-node-type").orElse(null);
- String inType = (String)bVertex.<String>property("aai-node-type").orElse(null);
+ String outType = aVertex.<String>property("aai-node-type").orElse(null);
+ String inType = bVertex.<String>property("aai-node-type").orElse(null);
return this.hasEdgeRule(outType, inType);
}
+ /**
+ * Gets all the edge rules that exist between the given node types.
+ * The rules will be phrased in terms of out|in, though this will
+ * also find rules defined as in|out (it will flip the direction in
+ * the EdgeRule object returned accordingly to match out|in).
+ *
+ * @param outType
+ * @param inType
+ * @return Map<String edgeLabel, EdgeRule rule> where edgeLabel is the label name
+ * @throws AAIException
+ */
public Map<String, EdgeRule> getEdgeRules(String outType, String inType) throws AAIException {
Map<String, EdgeRule> result = new HashMap<>();
EdgeRule rule = null;
@@ -235,95 +268,113 @@ public class EdgeRules {
return result;
}
+
/**
- * Gets the edge rule.
+ * Gets the edge rule of the given type that exists between A and B.
+ * Will check B|A as well, and flips the direction accordingly if that succeeds
+ * to match the expected A|B return.
*
- * @param outType the out type
- * @param inType the in type
- * @return the edge rule
- * @throws AAIException the AAI exception
+ * @param type - the type of edge you're looking for
+ * @param nodeA - first node type
+ * @param nodeB - second node type
+ * @return EdgeRule describing the rule in terms of A|B, if there is any such rule
+ * @throws AAIException if no such edge exists
*/
- public EdgeRule getEdgeRule(EdgeType type, String outType, String inType) throws AAIException {
- EdgeRule rule = new EdgeRule();
- Collection<String> collection = null;
- boolean isFlipped = false;
- if (this.hasEdgeRule(outType, inType) || this.hasEdgeRule(inType, outType)) {
- } else {
- String detail = "No EdgeRule found for passed nodeTypes: " + outType + ", " + inType + ".";
- throw new AAIException("AAI_6120", detail);
- }
- String key = outType + "|" + inType;
- collection = rules.get(key);
-
- String[] info = null;
- Iterator<String> iterator = collection.iterator();
- info = this.findRuleForContext(type, key, iterator);
- if (info == null) { //didn't find anything in that order, look again
- key = inType + "|" + outType;
- collection = rules.get(key);
- iterator = collection.iterator();
- info = this.findRuleForContext(type, key, iterator);
- isFlipped = true;
- }
- if (info == null) {
- throw new NoEdgeRuleFoundException("No EdgeRule found for EdgeType: " + type + " and node types: " + outType + " " + inType);
- }
- rule.setLabel(info[this.EDGE_NAME]);
- rule.setMultiplicityRule(MultiplicityRule.valueOf(info[this.MULTIPLICITY_RULE].toUpperCase()));
- rule.setHasDelTarget(info[this.HAS_DEL_TARGET]);
- rule.setUsesResource(info[this.USES_RESOURCE]);
- rule.setIsParent(info[this.IS_PARENT]);
- rule.setServiceInfrastructure(info[this.SVC_INFRA]);
- Direction direction = Direction.valueOf(info[this.DIRECTION]);
- if (isFlipped && direction.equals(Direction.OUT)) {
- rule.setDirection(Direction.IN);
- } else if (isFlipped && direction.equals(Direction.IN)){
- rule.setDirection(Direction.OUT);
- } else {
- rule.setDirection(direction);
- }
-
- return rule;
- }
-
- private String[] findRuleForContext (EdgeType type, String key, Iterator<String> itr) {
- String[] result = null;
- String s = "";
- String isParent = "";
- String[] info = new String[10];
- while (itr.hasNext()) {
- s = itr.next();
- info = s.split(",");
- isParent = info[this.IS_PARENT];
+ public EdgeRule getEdgeRule(EdgeType type, String nodeA, String nodeB) throws AAIException {
+ //try A to B
+ List<Map<String, String>> aToBEdges = rulesDoc.read("$.rules.[?]", buildFilter(type, nodeA, nodeB));
+ if (!aToBEdges.isEmpty()) {
//lazily stop iterating if we find a match
//should there be a mismatch between type and isParent,
//the caller will receive something.
//this operates on the assumption that there are at most two rules
//for a given vertex pair
- if (type.equals(EdgeType.TREE) && (isParent.equals("true") || isParent.equals("reverse"))) {
- result = info;
- break;
- } else if (type.equals(EdgeType.COUSIN) && isParent.equals("false")) {
- result = info;
- break;
- }
+ return buildRule(aToBEdges.get(0));
}
+ //we get here if there was nothing for A to B, so let's try B to A
+ List<Map<String, String>> bToAEdges = rulesDoc.read("$.rules.[?]", buildFilter(type, nodeB, nodeA));
+ if (!bToAEdges.isEmpty()) {
+ return flipDirection(buildRule(bToAEdges.get(0))); //bc we need to return as A|B, so flip the direction to match
+ }
- return result;
+ //found none
+ throw new NoEdgeRuleFoundException("no " + type.toString() + " edge between " + nodeA + " and " + nodeB);
+ }
+
+ /**
+ * Builds a JsonPath filter to search for an edge from nodeA to nodeB with the given edge type (cousin or parent/child)
+ *
+ * @param type
+ * @param nodeA - start node
+ * @param nodeB - end node
+ * @return
+ */
+ private Filter buildFilter(EdgeType type, String nodeA, String nodeB) {
+ if (EdgeType.COUSIN.equals(type)) {
+ return filter(
+ where("from").is(nodeA).and("to").is(nodeB).and("isParent").is("false")
+ );
+ } else {
+ return filter(
+ where("from").is(nodeA).and("to").is(nodeB).and("isParent").is("true")).or(
+ where("from").is(nodeA).and("to").is(nodeB).and("isParent").is("reverse")
+ );
+ }
+ }
+
+ /**
+ * Puts the give edge rule information into an EdgeRule object.
+ *
+ * @param edge - the edge information returned from JsonPath
+ * @return EdgeRule containing that information
+ */
+ private EdgeRule buildRule(Map<String, String> edge) {
+ EdgeRule rule = new EdgeRule();
+ rule.setLabel(edge.get("label"));
+ rule.setDirection(edge.get("direction"));
+ rule.setMultiplicityRule(edge.get("multiplicity"));
+ rule.setIsParent(edge.get("isParent"));
+ rule.setUsesResource(edge.get("usesResource"));
+ rule.setHasDelTarget(edge.get("hasDelTarget"));
+ rule.setServiceInfrastructure(edge.get("SVC-INFRA"));
+ return rule;
+ }
+
+ /**
+ * If getEdgeRule gets a request for A|B, and it finds something as B|A, the caller still expects
+ * the returned EdgeRule to reflect A|B directionality. This helper method flips B|A direction to
+ * match this expectation.
+ *
+ * @param rule whose direction needs flipped
+ * @return the updated rule
+ */
+ private EdgeRule flipDirection(EdgeRule rule) {
+ if (Direction.IN.equals(rule.getDirection())) {
+ rule.setDirection(Direction.OUT);
+ return rule;
+ } else if (Direction.OUT.equals(rule.getDirection())) {
+ rule.setDirection(Direction.IN);
+ return rule;
+ } else { //direction is BOTH, flipping both is still both
+ return rule;
+ }
}
+
/**
- * Gets the edge rule.
+ * Gets the edge rule of the given type that exists between A and B.
+ * Will check B|A as well, and flips the direction accordingly if that succeeds
+ * to match the expected A|B return.
*
- * @param aVertex the out vertex
- * @param bVertex the in vertex
- * @return the edge rule
- * @throws AAIException the AAI exception
- * @throws NoEdgeRuleFoundException
+ * @param type - the type of edge you're looking for
+ * @param aVertex - first node type
+ * @param bVertex - second node type
+ * @return EdgeRule describing the rule in terms of A|B, if there is any such rule
+ * @throws AAIException if no such edge exists
*/
- public EdgeRule getEdgeRule(EdgeType type, Vertex aVertex, Vertex bVertex) throws AAIException, NoEdgeRuleFoundException {
- String outType = (String)aVertex.<String>property(AAIProperties.NODE_TYPE).orElse(null);
- String inType = (String)bVertex.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+ public EdgeRule getEdgeRule(EdgeType type, Vertex aVertex, Vertex bVertex) throws AAIException {
+ String outType = aVertex.<String>property(AAIProperties.NODE_TYPE).orElse(null);
+ String inType = bVertex.<String>property(AAIProperties.NODE_TYPE).orElse(null);
return this.getEdgeRule(type, outType, inType);
@@ -386,7 +437,7 @@ public class EdgeRules {
}
- if (!detail.equals("")) {
+ if (!"".equals(detail)) {
return Optional.of(detail);
} else {
return Optional.empty();
@@ -395,17 +446,19 @@ public class EdgeRules {
}
- public Multimap<String, EdgeRule> getAllRules() throws AAIException {
-
+ /**
+ * Gets all the edge rules we define.
+ *
+ * @return Multimap<String "from|to", EdgeRule rule>
+ */
+ public Multimap<String, EdgeRule> getAllRules() {
Multimap<String, EdgeRule> result = ArrayListMultimap.create();
- for (String key : this.rules.keySet()) {
- String outType = "";
- String inType = "";
- String[] split = key.split("\\|");
- outType = split[0];
- inType = split[1];
- result.putAll(key,this.getEdgeRules(outType, inType).values());
+ List<Map<String, String>> rules = rulesDoc.read("$.rules.*");
+ for (Map<String, String> rule : rules) {
+ EdgeRule er = buildRule(rule);
+ String name = rule.get("from") + "|" + rule.get("to");
+ result.put(name, er);
}
return result;