diff options
Diffstat (limited to 'aai-schema-ingest')
6 files changed, 381 insertions, 155 deletions
diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeIngestor.java b/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeIngestor.java index dfcd0db3..c2c58d5f 100644 --- a/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeIngestor.java +++ b/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeIngestor.java @@ -1,4 +1,4 @@ -/** +/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -20,11 +20,16 @@ package org.onap.aai.edges; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; +import com.google.common.cache.Cache; +import com.google.common.cache.CacheBuilder; +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; import org.apache.tinkerpop.gremlin.structure.Direction; import org.onap.aai.edges.enums.DirectionNotation; import org.onap.aai.edges.enums.EdgeField; @@ -34,6 +39,8 @@ import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException; import org.onap.aai.setup.ConfigTranslator; import org.onap.aai.setup.SchemaVersion; import org.onap.aai.setup.SchemaVersions; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @@ -51,15 +58,25 @@ import static com.jayway.jsonpath.Criteria.where; */ @Component public class EdgeIngestor { - private Map<SchemaVersion, List<DocumentContext>> versionJsonFilesMap; + + private static final Logger LOG = LoggerFactory.getLogger(EdgeIngestor.class); + + private Map<SchemaVersion, List<DocumentContext>> versionJsonFilesMap; private static final String READ_START = "$.rules.[?]"; private static final String READ_ALL_START = "$.rules.*"; private SchemaVersions schemaVersions; + + private Set<String> multipleLabelKeys; + + private final LoadingCache<SchemaFilter,Multimap<String,EdgeRule>> cacheFilterStore; + + private final LoadingCache<String, String[]> cousinLabelStore; + //-----ingest-----// /** * Instantiates the EdgeIngestor bean. - * + * * @param translator - ConfigTranslator autowired in by Spring framework which * contains the configuration information needed to ingest the desired files. */ @@ -69,20 +86,41 @@ public class EdgeIngestor { JsonIngestor ji = new JsonIngestor(); this.schemaVersions = schemaVersions; versionJsonFilesMap = ji.ingest(filesToIngest); + this.cacheFilterStore = CacheBuilder.newBuilder() + .maximumSize(2000) + .build( + new CacheLoader<SchemaFilter, Multimap<String, EdgeRule>>() { + @Override + public Multimap<String, EdgeRule> load(SchemaFilter key) { + return extractRules(key); + } + } + ); + + this.cousinLabelStore = CacheBuilder.newBuilder() + .maximumSize(50) + .build( + new CacheLoader<String, String[]>() { + @Override + public String[] load(String key) throws Exception { + return retrieveCousinLabels(key); + } + } + ); } - + //-----methods for getting rule info-----// - + /** * Gets list of all edge rules defined in the latest version's schema - * + * * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules associated with those types - * where the key takes the form of + * where the key takes the form of * {alphabetically first nodetype}|{alphabetically second nodetype}. Map will be empty if * no rules are found. * ex: buildAlphabetizedKey("l-interface", "logical-link") -> "l-interface|logical-link" * buildAlphabetizedKey("logical-link", "l-interface") -> "l-interface|logical-link" - * + * * This is alphabetical order to normalize the keys, as sometimes there will be multiple * rules for a pair of node types but the from/to value in the json is flipped for some of them. * @throws EdgeRuleNotFoundException if none found @@ -90,17 +128,47 @@ public class EdgeIngestor { public Multimap<String, EdgeRule> getAllCurrentRules() throws EdgeRuleNotFoundException { return getAllRules(schemaVersions.getDefaultVersion()); } - + + /** + * Retrieves all the nodes that contain multiple edge labels + * + * A lazy instantiation to retrieve all this info on first call + * + * @return a set containing a list of strings where each string is + * concatenated by a pipe (|) character such as aNodeType|bNodeType + */ + public Set<String> getMultipleLabelKeys(){ + + if(multipleLabelKeys == null){ + multipleLabelKeys = new HashSet<>(); + try { + final Multimap<String, EdgeRule> edges = this.getAllCurrentRules(); + if(edges == null || edges.isEmpty()){ + LOG.warn("Unable to find any edge rules for the latest version"); + } + edges.keySet().forEach((key) -> { + Collection<EdgeRule> rules = edges.get(key); + if(rules.size() > 1){ + multipleLabelKeys.add(key); + } + }); + } catch (EdgeRuleNotFoundException e) { + LOG.info("For the latest schema version, unable to find any edges with multiple keys"); + } + } + + return multipleLabelKeys; + } /** * Gets list of all edge rules defined in the given version's schema - * + * * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules associated with those types - * where the key takes the form of + * where the key takes the form of * {alphabetically first nodetype}|{alphabetically second nodetype}. Map will be empty if * no rules are found. * ex: buildAlphabetizedKey("l-interface", "logical-link") -> "l-interface|logical-link" * buildAlphabetizedKey("logical-link", "l-interface") -> "l-interface|logical-link" - * + * * This is alphabetical order to normalize the keys, as sometimes there will be multiple * rules for a pair of node types but the from/to value in the json is flipped for some of them. * @throws EdgeRuleNotFoundException if none found @@ -113,19 +181,19 @@ public class EdgeIngestor { return found; } } - + /** * Finds the rules (if any) matching the given query criteria. If none, the returned Multimap * will be empty. - * + * * @param q - EdgeRuleQuery with filter criteria set - * - * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of + * + * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of * {alphabetically first nodetype}|{alphabetically second nodetype}. Map will be empty if * no rules are found. * ex: buildAlphabetizedKey("l-interface", "logical-link") -> "l-interface|logical-link" * buildAlphabetizedKey("logical-link", "l-interface") -> "l-interface|logical-link" - * + * * This is alphabetical order to normalize the keys, as sometimes there will be multiple * rules for a pair of node types but the from/to value in the json is flipped for some of them. * @throws EdgeRuleNotFoundException if none found @@ -140,36 +208,40 @@ public class EdgeIngestor { if (found.isEmpty()) { throw new EdgeRuleNotFoundException("No rules found for " + q.toString()); } else { - for (EdgeRule rule : found.values()) { - if (!q.getFromType().equals(rule.getFrom())) { - /* To maintain backwards compatibility with old EdgeRules API, - * where the direction of the returned EdgeRule would be - * flipped (if necessary) to match the directionality of - * the input params. - * ie, If the rule is from=A,to=B,direction=OUT, - * if the user asked (A,B) the direction would be OUT, - * if they asked (B,A), it would be IN to match. - */ - rule.flipDirection(); - } - } - return found; + Multimap<String, EdgeRule> copy = ArrayListMultimap.create(); + found.entries().stream().forEach((entry) -> { + EdgeRule rule = new EdgeRule(entry.getValue()); + if(!q.getFromType().equals(rule.getFrom())){ + /* To maintain backwards compatibility with old EdgeRules API, + * where the direction of the returned EdgeRule would be + * flipped (if necessary) to match the directionality of + * the input params. + * ie, If the rule is from=A,to=B,direction=OUT, + * if the user asked (A,B) the direction would be OUT, + * if they asked (B,A), it would be IN to match. + */ + rule.flipDirection(); + } + copy.put(entry.getKey(), rule); + }); + + return copy; } } - + /** * Gets the rule satisfying the given filter criteria. If there are more than one - * that match, return the default rule. If there is no clear default to return, or + * that match, return the default rule. If there is no clear default to return, or * no rules match at all, error. - * + * * @param q - EdgeRuleQuery with filter criteria set * @return EdgeRule satisfying given criteria * @throws EdgeRuleNotFoundException if none found that match * @throws AmbiguousRuleChoiceException if multiple match but no way to choice one from them - * Specifically, if multiple node type pairs come back (ie bar|foo and asdf|foo, + * Specifically, if multiple node type pairs come back (ie bar|foo and asdf|foo, * no way to know which is appropriate over the others), * or if there is a mix of Tree and Cousin edges because again there is no way to - * know which is "defaulter" than the other. + * know which is "defaulter" than the other. * The default property only clarifies among multiple cousin edges of the same node pair, * ex: which l-interface|logical-link rule to default to. */ @@ -184,7 +256,7 @@ public class EdgeIngestor { if (found.isEmpty()) { throw new EdgeRuleNotFoundException("No rule found for " + q.toString() + "."); } - + EdgeRule rule = null; if (found.keys().size() == 1) { //only one found, cool we're done for (Entry<String, EdgeRule> e : found.entries()) { @@ -193,10 +265,12 @@ public class EdgeIngestor { } else { rule = getDefaultRule(found); } - + + if (rule == null) { //should never get here though throw new EdgeRuleNotFoundException("No rule found for " + q.toString() + "."); } else { + rule = new EdgeRule(rule); if (!q.getFromType().equals(rule.getFrom())) { /* To maintain backwards compatibility with old EdgeRules API, * where the direction of the returned EdgeRule would be @@ -211,7 +285,9 @@ public class EdgeIngestor { return rule; } } - + + + private EdgeRule getDefaultRule(Multimap<String, EdgeRule> found) throws AmbiguousRuleChoiceException { if (found.keySet().size() > 1) { //ie multiple node pairs (a|c and b|c not just all a|c) case StringBuilder sb = new StringBuilder(); @@ -220,7 +296,7 @@ public class EdgeIngestor { } throw new AmbiguousRuleChoiceException("No way to select single rule from these pairs: " + sb.toString() + "."); } - + int defaultCount = 0; EdgeRule defRule = null; for (Entry<String, EdgeRule> e : found.entries()) { @@ -235,13 +311,13 @@ public class EdgeIngestor { } else if (defaultCount == 0) { throw new AmbiguousRuleChoiceException("No default found."); } - + return defRule; } - + /** * Checks if there exists any rule that satisfies the given filter criteria. - * + * * @param q - EdgeRuleQuery with filter criteria set * @return boolean */ @@ -252,42 +328,59 @@ public class EdgeIngestor { return !extractRules(q.getFilter(), schemaVersions.getDefaultVersion()).isEmpty(); } } - + /** * Gets all cousin rules for the given node type in the latest schema version. - * + * * @param nodeType - * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of + * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of * {alphabetically first nodetype}|{alphabetically second nodetype}. Map will be empty if * no rules are found. * ex: buildAlphabetizedKey("l-interface", "logical-link") -> "l-interface|logical-link" * buildAlphabetizedKey("logical-link", "l-interface") -> "l-interface|logical-link" - * + * * This is alphabetical order to normalize the keys, as sometimes there will be multiple * rules for a pair of node types but the from/to value in the json is flipped for some of them. */ public Multimap<String, EdgeRule> getCousinRules(String nodeType) { return getCousinRules(nodeType, schemaVersions.getDefaultVersion()); //default to latest } - + + + public String[] retrieveCousinLabels(String nodeType){ + + Multimap<String, EdgeRule> cousinRules = getCousinRules(nodeType); + String[] cousinLabels = new String[cousinRules.size()]; + + return cousinRules.entries() + .stream() + .map((entry) -> entry.getValue().getLabel()) + .collect(Collectors.toList()) + .toArray(cousinLabels); + } + + public String[] retrieveCachedCousinLabels(String nodeType) throws ExecutionException { + return cousinLabelStore.get(nodeType); + } + /** * Gets all cousin rules for the given node type in the given schema version. - * + * * @param nodeType * @param v - the version of the edge rules to query - * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of + * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of * {alphabetically first nodetype}|{alphabetically second nodetype}. Map will be empty if * no rules are found. * ex: buildAlphabetizedKey("l-interface", "logical-link") -> "l-interface|logical-link" * buildAlphabetizedKey("logical-link", "l-interface") -> "l-interface|logical-link" - * + * * This is alphabetical order to normalize the keys, as sometimes there will be multiple - * rules for a pair of node types but the from/to value in the json is flipped for some of them. + * rules for a pair of node types but the from/to value in the json is flipped for some of them. */ public Multimap<String, EdgeRule> getCousinRules(String nodeType, SchemaVersion v) { return extractRules(new EdgeRuleQuery.Builder(nodeType).edgeType(EdgeType.COUSIN).build().getFilter(), v); } - + /** * Returns if the given node type has any cousin relationships in the current version. * @param nodeType @@ -296,7 +389,7 @@ public class EdgeIngestor { public boolean hasCousinRule(String nodeType) { return hasCousinRule(nodeType, schemaVersions.getDefaultVersion()); } - + /** * Returns if the given node type has any cousin relationships in the given version. * @param nodeType @@ -305,45 +398,45 @@ public class EdgeIngestor { public boolean hasCousinRule(String nodeType, SchemaVersion v) { return !getCousinRules(nodeType, v).isEmpty(); } - + /** * Gets all rules where "{given nodeType} contains {otherType}" in the latest schema version. - * + * * @param nodeType - node type that is the container in the returned relationships - * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of + * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of * {alphabetically first nodetype}|{alphabetically second nodetype}. Map will be empty if * no rules are found. * ex: buildAlphabetizedKey("l-interface", "logical-link") -> "l-interface|logical-link" * buildAlphabetizedKey("logical-link", "l-interface") -> "l-interface|logical-link" - * + * * This is alphabetical order to normalize the keys, as sometimes there will be multiple - * rules for a pair of node types but the from/to value in the json is flipped for some of them. + * rules for a pair of node types but the from/to value in the json is flipped for some of them. */ public Multimap<String, EdgeRule> getChildRules(String nodeType) { return getChildRules(nodeType, schemaVersions.getDefaultVersion()); } - + /** * Gets all rules where "{given nodeType} contains {otherType}" in the given schema version. - * + * * @param nodeType - node type that is the container in the returned relationships - * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of + * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of * {alphabetically first nodetype}|{alphabetically second nodetype}. Map will be empty if * no rules are found. * ex: buildAlphabetizedKey("l-interface", "logical-link") -> "l-interface|logical-link" * buildAlphabetizedKey("logical-link", "l-interface") -> "l-interface|logical-link" - * + * * This is alphabetical order to normalize the keys, as sometimes there will be multiple - * rules for a pair of node types but the from/to value in the json is flipped for some of them. + * rules for a pair of node types but the from/to value in the json is flipped for some of them. */ public Multimap<String, EdgeRule> getChildRules(String nodeType, SchemaVersion v) { Filter from = assembleFilterSegments(where(EdgeField.FROM.toString()).is(nodeType), getSameDirectionContainmentCriteria()); Filter to = assembleFilterSegments(where(EdgeField.TO.toString()).is(nodeType), getOppositeDirectionContainmentCriteria()); Filter total = from.or(to); - + return extractRules(total, v); } - + /** * Returns if the given node type has any child relationships (ie it contains another node type) in the current version. * @param nodeType @@ -352,7 +445,7 @@ public class EdgeIngestor { public boolean hasChildRule(String nodeType) { return hasChildRule(nodeType, schemaVersions.getDefaultVersion()); } - + /** * Returns if the given node type has any child relationships (ie it contains another node type) in the given version. * @param nodeType @@ -361,45 +454,45 @@ public class EdgeIngestor { public boolean hasChildRule(String nodeType, SchemaVersion v) { return !getChildRules(nodeType, v).isEmpty(); } - + /** * Gets all rules where "{given nodeType} is contained by {otherType}" in the latest schema version. - * + * * @param nodeType - node type that is the containee in the returned relationships - * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of + * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of * {alphabetically first nodetype}|{alphabetically second nodetype}. Map will be empty if * no rules are found. * ex: buildAlphabetizedKey("l-interface", "logical-link") -> "l-interface|logical-link" * buildAlphabetizedKey("logical-link", "l-interface") -> "l-interface|logical-link" - * + * * This is alphabetical order to normalize the keys, as sometimes there will be multiple * rules for a pair of node types but the from/to value in the json is flipped for some of them. */ public Multimap<String, EdgeRule> getParentRules(String nodeType) { return getParentRules(nodeType, schemaVersions.getDefaultVersion()); } - + /** * Gets all rules where "{given nodeType} is contained by {otherType}" in the given schema version. - * + * * @param nodeType - node type that is the containee in the returned relationships - * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of + * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of * {alphabetically first nodetype}|{alphabetically second nodetype}. Map will be empty if * no rules are found. * ex: buildAlphabetizedKey("l-interface", "logical-link") -> "l-interface|logical-link" * buildAlphabetizedKey("logical-link", "l-interface") -> "l-interface|logical-link" - * + * * This is alphabetical order to normalize the keys, as sometimes there will be multiple - * rules for a pair of node types but the from/to value in the json is flipped for some of them. + * rules for a pair of node types but the from/to value in the json is flipped for some of them. */ public Multimap<String, EdgeRule> getParentRules(String nodeType, SchemaVersion v) { Filter from = assembleFilterSegments(where(EdgeField.FROM.toString()).is(nodeType), getOppositeDirectionContainmentCriteria()); Filter to = assembleFilterSegments(where(EdgeField.TO.toString()).is(nodeType), getSameDirectionContainmentCriteria()); Filter total = from.or(to); - + return extractRules(total, v); } - + /** * Returns if the given node type has any parent relationships (ie it is contained by another node type) in the current version. * @param nodeType @@ -408,7 +501,7 @@ public class EdgeIngestor { public boolean hasParentRule(String nodeType) { return hasParentRule(nodeType, schemaVersions.getDefaultVersion()); } - + /** * Returns if the given node type has any parent relationships (ie it is contained by another node type) in the given version. * @param nodeType @@ -417,47 +510,57 @@ public class EdgeIngestor { public boolean hasParentRule(String nodeType, SchemaVersion v) { return !getParentRules(nodeType, v).isEmpty(); } - + /** * Applies the given filter to the DocumentContext(s) for the given version to extract * edge rules, and converts this extracted information into the Multimap form - * + * * @param filter - JsonPath filter to read the DocumentContexts with. May be null * to denote no filter, ie get all. * @param v - The schema version to extract from - * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of + * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of * {alphabetically first nodetype}|{alphabetically second nodetype}. Map will be empty if * no rules are found. * ex: buildAlphabetizedKey("l-interface", "logical-link") -> "l-interface|logical-link" * buildAlphabetizedKey("logical-link", "l-interface") -> "l-interface|logical-link" - * + * * This is alphabetical order to normalize the keys, as sometimes there will be multiple - * rules for a pair of node types but the from/to value in the json is flipped for some of them. + * rules for a pair of node types but the from/to value in the json is flipped for some of them. */ private Multimap<String, EdgeRule> extractRules(Filter filter, SchemaVersion v) { - List<Map<String, String>> foundRules = new ArrayList<>(); - List<DocumentContext> docs = versionJsonFilesMap.get(v); - if (docs != null) { - for (DocumentContext doc : docs) { - if (filter == null) { - foundRules.addAll(doc.read(READ_ALL_START)); - } else { - foundRules.addAll(doc.read(READ_START, filter)); - } - } - } - - return convertToEdgeRules(foundRules); - } - + SchemaFilter schemaFilter = new SchemaFilter(filter, v); + try { + return cacheFilterStore.get(schemaFilter); + } catch (ExecutionException e) { + LOG.info("Encountered exception during the retrieval of the rules"); + return ArrayListMultimap.create(); + } + } + + public Multimap<String, EdgeRule> extractRules(SchemaFilter schemaFilter){ + List<Map<String, String>> foundRules = new ArrayList<>(); + List<DocumentContext> docs = versionJsonFilesMap.get(schemaFilter.getSchemaVersion()); + if (docs != null) { + for (DocumentContext doc : docs) { + if (schemaFilter.getFilter() == null) { + foundRules.addAll(doc.read(READ_ALL_START)); + } else { + foundRules.addAll(doc.read(READ_START, Filter.parse(schemaFilter.getFilter()))); + } + } + } + + return convertToEdgeRules(foundRules); + } + //-----filter building helpers-----// /** * ANDs together the given start criteria with each criteria in the pieces list, and * then ORs together these segments into one filter. - * + * * JsonPath doesn't have an OR method on Criteria, only on Filters, so assembling * a complete filter requires this sort of roundabout construction. - * + * * @param start - Criteria of the form where(from/to).is(nodeType) * (ie the start of any A&AI edge rule query) * @param pieces - Other Criteria to be applied @@ -474,91 +577,91 @@ public class EdgeIngestor { } return assembled; } - + /** * Builds the sub-Criteria for a containment edge rule query where the direction * and containment fields must match. - * + * * Used for getChildRules() where the container node type is in the "from" position and * for getParentRules() where the containee type is in the "to" position. - * + * * @return List<Criteria> covering property permutations defined with either notation or explicit direction */ private List<Criteria> getSameDirectionContainmentCriteria() { List<Criteria> crits = new ArrayList<>(); - + crits.add(where(EdgeField.CONTAINS.toString()).is(DirectionNotation.DIRECTION.toString())); - + crits.add(where(EdgeField.DIRECTION.toString()).is(Direction.OUT.toString()) .and(EdgeField.CONTAINS.toString()).is(Direction.OUT.toString())); - + crits.add(where(EdgeField.DIRECTION.toString()).is(Direction.IN.toString()) .and(EdgeField.CONTAINS.toString()).is(Direction.IN.toString())); - + return crits; } - + /** * Builds the sub-Criteria for a containment edge rule query where the direction * and containment fields must not match. - * + * * Used for getChildRules() where the container node type is in the "to" position and * for getParentRules() where the containee type is in the "from" position. - * + * * @return List<Criteria> covering property permutations defined with either notation or explicit direction */ private List<Criteria> getOppositeDirectionContainmentCriteria() { List<Criteria> crits = new ArrayList<>(); - + crits.add(where(EdgeField.CONTAINS.toString()).is(DirectionNotation.OPPOSITE.toString())); - + crits.add(where(EdgeField.DIRECTION.toString()).is(Direction.OUT.toString()) .and(EdgeField.CONTAINS.toString()).is(Direction.IN.toString())); - + crits.add(where(EdgeField.DIRECTION.toString()).is(Direction.IN.toString()) .and(EdgeField.CONTAINS.toString()).is(Direction.OUT.toString())); - + return crits; } - + //-----rule packaging helpers-----// /** * Converts the raw output from reading the json file to the Multimap<String key, EdgeRule> format - * + * * @param allFound - raw edge rule output read from json file(s) * (could be empty if none found) - * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of + * @return Multimap<String, EdgeRule> of node names keys to the EdgeRules where the key takes the form of * {alphabetically first nodetype}|{alphabetically second nodetype}. Will be empty if input * was empty. * ex: buildAlphabetizedKey("l-interface", "logical-link") -> "l-interface|logical-link" * buildAlphabetizedKey("logical-link", "l-interface") -> "l-interface|logical-link" - * + * * This is alphabetical order to normalize the keys, as sometimes there will be multiple - * rules for a pair of node types but the from/to value in the json is flipped for some of them. + * rules for a pair of node types but the from/to value in the json is flipped for some of them. */ private Multimap<String, EdgeRule> convertToEdgeRules(List<Map<String, String>> allFound) { Multimap<String, EdgeRule> rules = ArrayListMultimap.create(); - + TypeAlphabetizer alpher = new TypeAlphabetizer(); - + for (Map<String, String> raw : allFound) { EdgeRule converted = new EdgeRule(raw); if (converted.getFrom().equals(converted.getTo())) { - /* the way the code worked in the past was with outs and - * when we switched it to in the same-node-type to - * same-node-type parent child edges were failing because all - * of the calling code would pass the parent as the left argument, - * so it was either in that method swap the parent/child, - * flip the edge rule or make all callers swap. the last seemed - * like a bad idea. and felt like the edge flip was the better + /* the way the code worked in the past was with outs and + * when we switched it to in the same-node-type to + * same-node-type parent child edges were failing because all + * of the calling code would pass the parent as the left argument, + * so it was either in that method swap the parent/child, + * flip the edge rule or make all callers swap. the last seemed + * like a bad idea. and felt like the edge flip was the better * of the remaining 2 */ converted.flipDirection(); } String alphabetizedKey = alpher.buildAlphabetizedKey(raw.get(EdgeField.FROM.toString()), raw.get(EdgeField.TO.toString())); rules.put(alphabetizedKey, converted); } - + return rules; } - + } diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeRule.java b/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeRule.java index e1cb240e..f914f6cb 100644 --- a/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeRule.java +++ b/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeRule.java @@ -26,7 +26,9 @@ import org.onap.aai.edges.enums.EdgeField; import org.onap.aai.edges.enums.EdgeProperty; import org.onap.aai.edges.enums.MultiplicityRule; +import java.util.Collections; import java.util.EnumMap; +import java.util.HashMap; import java.util.Map; /** @@ -43,16 +45,16 @@ public class EdgeRule { private String description; private boolean isPrivateEdge = false; - /** + /** * Instantiates a new edge rule. - * + * * @param fieldVals - Map<String, String> where first string is - * an EdgeField value and second string is the + * an EdgeField value and second string is the * value of that field */ public EdgeRule(Map<String, String> fieldVals) { edgeFields = new EnumMap<>(EdgeProperty.class); - + from = fieldVals.get(EdgeField.FROM.toString()); to = fieldVals.get(EdgeField.TO.toString()); label = fieldVals.get(EdgeField.LABEL.toString()); @@ -63,19 +65,32 @@ public class EdgeRule { String rawVal = fieldVals.get(prop.toString()); edgeFields.put(prop, convertNotation(direction, rawVal)); } - + isDefaultEdge = Boolean.valueOf(fieldVals.get(EdgeField.DEFAULT.toString())); - + description = fieldVals.get(EdgeField.DESCRIPTION.toString()); if (description == null) { //bc description is optional and not in v12 and earlier description = ""; } } + // Copy Constructor + public EdgeRule(EdgeRule edgeRule){ + this.from = edgeRule.from; + this.to = edgeRule.to; + this.label = edgeRule.label; + this.direction = Direction.valueOf(edgeRule.direction.toString()); + this.multiplicityRule = MultiplicityRule.valueOf(edgeRule.multiplicityRule.toString()); + this.edgeFields = new HashMap<>(edgeRule.edgeFields); + this.isDefaultEdge = edgeRule.isDefaultEdge; + this.description = edgeRule.description; + this.isPrivateEdge = edgeRule.isPrivateEdge; + } + /** * Converts whatever string was in the json for an edge property value into * the appropriate AAIDirection - * + * * @param Direction dir - the edge direction * @param String rawVal - property value from the json, may be * IN, OUT, BOTH, NONE, ${direction}, or !${direction} @@ -92,7 +107,7 @@ public class EdgeRule { } else if (AAIDirection.IN.toString().equalsIgnoreCase(rawVal)) { return AAIDirection.IN; } - + DirectionNotation rawDN = DirectionNotation.getValue(rawVal); if (DirectionNotation.DIRECTION.equals(rawDN)) { return AAIDirection.getValue(dir); @@ -100,7 +115,7 @@ public class EdgeRule { return AAIDirection.getValue(dir.opposite()); } } - + /** * Gets the name of the node type in the "from" field * @return String nodetype @@ -125,7 +140,7 @@ public class EdgeRule { public String getLabel() { return label; } - + /** * Gets the multiplicity rule. * @@ -134,7 +149,7 @@ public class EdgeRule { public MultiplicityRule getMultiplicityRule() { return multiplicityRule; } - + /** * Gets the edge direction * @@ -143,7 +158,7 @@ public class EdgeRule { public Direction getDirection() { return direction; } - + /** * Gets the value of contains-other-v * @@ -152,7 +167,7 @@ public class EdgeRule { public String getContains() { return edgeFields.get(EdgeProperty.CONTAINS).toString(); } - + /** * Gets the value of delete-other-v * @@ -161,10 +176,10 @@ public class EdgeRule { public String getDeleteOtherV() { return edgeFields.get(EdgeProperty.DELETE_OTHER_V).toString(); } - + /** * Gets the value of the prevent-delete property - * + * * @return String prevent-delete property value */ public String getPreventDelete() { @@ -173,13 +188,13 @@ public class EdgeRule { /** * Returns if this rule is a default or not - * + * * @return boolean */ public boolean isDefault() { return isDefaultEdge; } - + /** * Gets the description on the edge rule (if there is one) * @return String description @@ -187,7 +202,7 @@ public class EdgeRule { public String getDescription() { return this.description; } - + /** * Flips the direction value * IN -> OUT diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeRuleQuery.java b/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeRuleQuery.java index 5801e816..58c8c546 100644 --- a/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeRuleQuery.java +++ b/aai-schema-ingest/src/main/java/org/onap/aai/edges/EdgeRuleQuery.java @@ -1,4 +1,4 @@ -/** +/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -36,6 +36,7 @@ import static com.jayway.jsonpath.Filter.filter; import java.util.ArrayList; import java.util.List; +import java.util.Objects; import java.util.Optional; import static com.jayway.jsonpath.Criteria.where; @@ -90,6 +91,12 @@ public class EdgeRuleQuery { private String getSecondNodeType() { return nodeB; } + + public Builder to(String nodeB){ + this.nodeB = nodeB; + return this; + } + public Builder toOnly() { //Allows this to be used with single parameter constructor Builder(String nodeA) if(StringUtils.isEmpty(this.nodeB) && StringUtils.isNotEmpty(this.nodeA) ) { @@ -312,6 +319,30 @@ public class EdgeRuleQuery { } return sb.toString(); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + EdgeRuleQuery ruleQuery = (EdgeRuleQuery) o; + return isPrivate == ruleQuery.isPrivate && + Objects.equals(v, ruleQuery.v) && + Objects.equals(nodeA, ruleQuery.nodeA) && + Objects.equals(nodeB, ruleQuery.nodeB) && + Objects.equals(label, ruleQuery.label) && + direction == ruleQuery.direction && + type == ruleQuery.type; + } + + @Override + public int hashCode() { + if(v.isPresent()){ + return Objects.hash(v.get(), nodeA, nodeB, label, direction, type, isPrivate); + } else { + return Objects.hash(nodeA, nodeB, label, direction, type, isPrivate); + } + } + } diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/edges/SchemaFilter.java b/aai-schema-ingest/src/main/java/org/onap/aai/edges/SchemaFilter.java new file mode 100644 index 00000000..792e3c51 --- /dev/null +++ b/aai-schema-ingest/src/main/java/org/onap/aai/edges/SchemaFilter.java @@ -0,0 +1,69 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-18 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.onap.aai.edges; + +import com.jayway.jsonpath.Filter; +import org.onap.aai.setup.SchemaVersion; + +import java.util.Objects; + +public class SchemaFilter { + + private String filter; + + private SchemaVersion schemaVersion; + + public SchemaFilter(Filter filter, SchemaVersion schemaVersion){ + if(filter != null){ + this.filter = filter.toString(); + } + this.schemaVersion = schemaVersion; + } + + public SchemaVersion getSchemaVersion() { + return schemaVersion; + } + + public String getFilter() { + return filter; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + SchemaFilter that = (SchemaFilter) o; + return Objects.equals(filter, that.filter) && + Objects.equals(schemaVersion, that.schemaVersion); + } + + @Override + public int hashCode() { + return Objects.hash(filter, schemaVersion); + } + + @Override + public String toString() { + return "SchemaFilter{" + + "filter='" + filter + '\'' + + ", schemaVersion=" + schemaVersion + + '}'; + } +} diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/edges/exceptions/AmbiguousRuleChoiceException.java b/aai-schema-ingest/src/main/java/org/onap/aai/edges/exceptions/AmbiguousRuleChoiceException.java index b218cecd..3ddced9a 100644 --- a/aai-schema-ingest/src/main/java/org/onap/aai/edges/exceptions/AmbiguousRuleChoiceException.java +++ b/aai-schema-ingest/src/main/java/org/onap/aai/edges/exceptions/AmbiguousRuleChoiceException.java @@ -1,4 +1,4 @@ -/** +/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -24,4 +24,8 @@ public class AmbiguousRuleChoiceException extends Exception { public AmbiguousRuleChoiceException(String msg) { super(msg); } + + public AmbiguousRuleChoiceException(Throwable throwable){ + super(throwable); + } } diff --git a/aai-schema-ingest/src/main/java/org/onap/aai/edges/exceptions/EdgeRuleNotFoundException.java b/aai-schema-ingest/src/main/java/org/onap/aai/edges/exceptions/EdgeRuleNotFoundException.java index 4d339de2..de022bc5 100644 --- a/aai-schema-ingest/src/main/java/org/onap/aai/edges/exceptions/EdgeRuleNotFoundException.java +++ b/aai-schema-ingest/src/main/java/org/onap/aai/edges/exceptions/EdgeRuleNotFoundException.java @@ -1,4 +1,4 @@ -/** +/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ @@ -24,4 +24,8 @@ public class EdgeRuleNotFoundException extends Exception { public EdgeRuleNotFoundException(String msg) { super(msg); } + + public EdgeRuleNotFoundException(Throwable throwable){ + super(throwable); + } } |