X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=aai-schema-ingest%2Fsrc%2Fmain%2Fjava%2Forg%2Fonap%2Faai%2Fedges%2FEdgeRuleQuery.java;h=fc58dbb61189de146ffcb9096be9e6e044b5d406;hb=dd41187b272341b8250ad4e09a03462107bc8847;hp=3029685f4e3cf917ad13b24f524c6a4f125bec2b;hpb=1fc5ce5b48f8c270d5d044356843b8a8566bdccc;p=aai%2Faai-common.git 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 3029685f..fc58dbb6 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,8 +1,10 @@ -/** +/** * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-18 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Modifications Copyright © 2018 IBM. * ================================================================================ * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,199 +18,328 @@ * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ package org.onap.aai.edges; -import org.onap.aai.edges.enums.AAIDirection; -import org.onap.aai.edges.enums.EdgeField; -import org.onap.aai.edges.enums.EdgeProperty; -import org.onap.aai.edges.enums.EdgeType; -import org.onap.aai.setup.Version; +import static com.jayway.jsonpath.Criteria.where; +import static com.jayway.jsonpath.Filter.filter; import com.jayway.jsonpath.Filter; import com.jayway.jsonpath.Predicate; -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; +import org.apache.commons.lang.StringUtils; +import org.onap.aai.edges.enums.AAIDirection; +import org.onap.aai.edges.enums.EdgeField; +import org.onap.aai.edges.enums.EdgeProperty; +import org.onap.aai.edges.enums.EdgeType; +import org.onap.aai.setup.SchemaVersion; /** * For querying the edge rules schema (not the database) * */ public class EdgeRuleQuery { - private Filter filter; - private Version v; - private String nodeA; - private String nodeB; - private String label; - private EdgeType type; - - public static class Builder { - //required - private String nodeA; - - //optional - null will translate to any value of the param - private String nodeB = null; - private String label = null; - private EdgeType type = null; - private Version version = Version.getLatest(); //default - - public Builder(String nodeA) { - this.nodeA = nodeA; - } - - public Builder(String nodeA, String nodeB) { - this.nodeA = nodeA; - this.nodeB = nodeB; - } - - private String getFirstNodeType() { - return nodeA; - } - - private String getSecondNodeType() { - return nodeB; - } - - public Builder label(String label) { - this.label = label; - return this; - } - - private String getLabel() { - return label; - } - - public Builder edgeType(EdgeType type) { - this.type = type; - return this; - } - - private EdgeType getEdgeType() { - return type; - } - - public Builder version(Version version) { - this.version = version; - return this; - } - private Version getVersion() { - return version; - } - - public EdgeRuleQuery build() { - return new EdgeRuleQuery(this); - } - } - - private EdgeRuleQuery(Builder builder) { - this.v = builder.getVersion(); - this.nodeA = builder.getFirstNodeType(); - this.nodeB = builder.getSecondNodeType(); - this.label = builder.getLabel(); - this.type = builder.getEdgeType(); - - //will cover from A to B case - List criteriaFromTo = new ArrayList<>(); - criteriaFromTo.add(buildToFromPart(builder.getFirstNodeType(), builder.getSecondNodeType())); - //will cover from B to A case - must be separate bc jsonpath won't let me OR predicates >:C - List criteriaToFrom = new ArrayList<>(); - criteriaToFrom.add(buildToFromPart(builder.getSecondNodeType(), builder.getFirstNodeType())); - - - - if (builder.getLabel() != null) { - Predicate labelPred = addLabel(builder.getLabel()); - criteriaFromTo.add(labelPred); - criteriaToFrom.add(labelPred); - } - - if (builder.getEdgeType() != null) { - Predicate typePred = addType(builder.getEdgeType()); - criteriaFromTo.add(typePred); - criteriaToFrom.add(typePred); - } - - - - this.filter = filter(criteriaFromTo).or(filter(criteriaToFrom)); - } - - private Predicate buildToFromPart(String from, String to) { - if (from == null && to == null) { //shouldn't ever happen though - throw new IllegalStateException("must have at least one node defined"); - } - - Predicate p; - - if (to == null) { - p = where(EdgeField.FROM.toString()).is(from); - } else if (from == null) { - p = where(EdgeField.TO.toString()).is(to); - } else { - p = where(EdgeField.FROM.toString()).is(from).and(EdgeField.TO.toString()).is(to); - } - - return p; - } - - private Predicate addLabel(String label) { - return where(EdgeField.LABEL.toString()).is(label); - } - - private Predicate addType(EdgeType type) { - if (type == EdgeType.COUSIN) { - return where(EdgeProperty.CONTAINS.toString()).is(AAIDirection.NONE.toString()); - } else { //equals TREE - return where(EdgeProperty.CONTAINS.toString()).ne(AAIDirection.NONE.toString()); - } - } - - /** - * Provides the JsonPath filter for actually querying the edge rule schema files - * @return Filter - */ - public Filter getFilter() { - return this.filter; - } - - /** - * So the Ingestor knows which version of the rules to search - * @return the Version - */ - public Version getVersion() { - return this.v; - } - - @Override - public String toString() { - StringBuilder sb = new StringBuilder(); - - sb.append("EdgeRuleQuery with filter params node type: ").append(nodeA); - - if (nodeB != null) { - sb.append(", node type: ").append(nodeB); - } - - if (label != null) { - sb.append(", label: ").append(label); - } - - sb.append(", type: "); - if (type != null) { - sb.append(type.toString()); - } else { - sb.append("any"); - } - - sb.append(", for version: ").append(v.toString()).append("."); - return sb.toString(); - } + private Filter filter; + private Optional v; + private String nodeA; + private String nodeB; + private String label; + private AAIDirection direction; + private EdgeType type; + private boolean isPrivate; + + public static class Builder { + private static final String TO_ONLY = "ToOnly"; + + private static final String FROM_ONLY = "FromOnly"; + + // required + private String nodeA; + + // optional - null will translate to any value of the param + private String nodeB = null; + private String label = null; + private EdgeType type = null; + private AAIDirection direction = null; + private boolean isPrivate = false; + private SchemaVersion version = null; + + public Builder(String nodeA) { + this.nodeA = nodeA; + } + + public Builder(String nodeA, String nodeB) { + this.nodeA = nodeA; + this.nodeB = nodeB; + } + + private String getFirstNodeType() { + return nodeA; + } + + public Builder fromOnly() { + this.nodeB = FROM_ONLY; + return this; + } + + 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)) { + this.nodeB = this.nodeA; + } + this.nodeA = TO_ONLY; + return this; + } + + public Builder label(String label) { + this.label = label; + return this; + } + + private String getLabel() { + return label; + } + + public Builder edgeType(EdgeType type) { + this.type = type; + return this; + } + + private EdgeType getEdgeType() { + return type; + } + + public Builder direction(AAIDirection direction) { + this.direction = direction; + return this; + } + + private AAIDirection getDirection() { + return direction; + } + + public Builder version(SchemaVersion version) { + this.version = version; + return this; + } + + public Builder setPrivate(boolean isPrivate) { + this.isPrivate = isPrivate; + return this; + } + + public boolean isPrivate() { + return isPrivate; + } + + private Optional getSchemaVersion() { + return Optional.ofNullable(version); + } + + public EdgeRuleQuery build() { + return new EdgeRuleQuery(this); + } + } + + private EdgeRuleQuery(Builder builder) { + this.v = builder.getSchemaVersion(); + this.nodeA = builder.getFirstNodeType(); + this.nodeB = builder.getSecondNodeType(); + this.label = builder.getLabel(); + this.type = builder.getEdgeType(); + this.direction = builder.getDirection(); + this.isPrivate = builder.isPrivate(); + + // will cover from A to B case + List criteriaFromTo = new ArrayList<>(); + // Special logic to allow for A to B case only + if (("FromOnly").equals(builder.getSecondNodeType())) { + criteriaFromTo.add(buildToFromPart(builder.getFirstNodeType(), null)); + } else { + criteriaFromTo.add(buildToFromPart(builder.getFirstNodeType(), builder.getSecondNodeType())); + } + // will cover from B to A case - must be separate bc jsonpath won't let me OR predicates >:C + List criteriaToFrom = new ArrayList<>(); + // Special logic to allow for B to A case only + if (("ToOnly").equals(builder.getFirstNodeType())) { + criteriaToFrom.add(buildToFromPart(null, builder.getSecondNodeType())); + } else { + criteriaToFrom.add(buildToFromPart(builder.getSecondNodeType(), builder.getFirstNodeType())); + } + if (builder.getLabel() != null) { + Predicate labelPred = addLabel(builder.getLabel()); + criteriaFromTo.add(labelPred); + criteriaToFrom.add(labelPred); + } + + if (builder.getEdgeType() != null && builder.getEdgeType() != EdgeType.ALL) { + Predicate typePred = addType(builder.getEdgeType()); + criteriaFromTo.add(typePred); + criteriaToFrom.add(typePred); + } + Predicate privatePredicate = where("private").is(String.valueOf(isPrivate)); + + if (isPrivate) { + criteriaFromTo.add(privatePredicate); + criteriaToFrom.add(privatePredicate); + } + + if (builder.getDirection() != null) { + Predicate directionPred = addDirection(builder.getDirection()); + criteriaFromTo.add(directionPred); + criteriaToFrom.add(directionPred); + } + if (("ToOnly").equals(builder.getFirstNodeType())) { + this.filter = filter(criteriaToFrom); + } else if (("FromOnly").equals(builder.getSecondNodeType())) { + this.filter = filter(criteriaFromTo); + } else { + this.filter = filter(criteriaFromTo).or(filter(criteriaToFrom)); + } + } + + private Predicate buildToFromPart(String from, String to) { + if (from == null && to == null) { // shouldn't ever happen though + throw new IllegalStateException("must have at least one node defined"); + } + + Predicate p; + + if (to == null) { + p = where(EdgeField.FROM.toString()).is(from); + } else if (from == null) { + p = where(EdgeField.TO.toString()).is(to); + } else { + p = where(EdgeField.FROM.toString()).is(from).and(EdgeField.TO.toString()).is(to); + } + + return p; + } + + private Predicate addLabel(String label) { + return where(EdgeField.LABEL.toString()).is(label); + } + + private Predicate addType(EdgeType type) { + if (type == EdgeType.COUSIN) { + return where(EdgeProperty.CONTAINS.toString()).is(AAIDirection.NONE.toString()); + } else { // equals TREE + return where(EdgeProperty.CONTAINS.toString()).ne(AAIDirection.NONE.toString()); + } + } + + private Predicate addDirection(AAIDirection direction) { + if (direction == AAIDirection.OUT) { + return where(EdgeField.DIRECTION.toString()).in(AAIDirection.OUT.toString(), AAIDirection.BOTH.toString()); + } else if (direction == AAIDirection.IN) { + return where(EdgeField.DIRECTION.toString()).in(AAIDirection.IN.toString(), AAIDirection.BOTH.toString()); + } else if (direction == AAIDirection.BOTH) { + return where(EdgeField.DIRECTION.toString()).is(AAIDirection.BOTH.toString()); + } else if (direction == AAIDirection.NONE) { + return where(EdgeField.DIRECTION.toString()).is(AAIDirection.NONE.toString()); + } + return where(EdgeField.DIRECTION.toString()).is(AAIDirection.NONE.toString()); + } + + /** + * Provides the JsonPath filter for actually querying the edge rule schema files + * + * @return Filter + */ + public Filter getFilter() { + return this.filter; + } + + /** + * Gets the first node type given for the query. + * + * ie, If you called Builder(A,B) this would return A, + * if you called Builder(B,A), it would return B, + * if you called Builder(A), it would return A. + * + * This is to maintain backwards compatibility with the + * EdgeRules API which flipped the direction of + * the result EdgeRule to match the input directionality. + * + * @return String first node type of the query + */ + public String getFromType() { + return this.nodeA; + } + + /** + * So the Ingestor knows which version of the rules to search + * + * @return the Version + */ + public Optional getVersion() { + return this.v; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + + sb.append("EdgeRuleQuery with filter params node type: ").append(nodeA); + + if (nodeB != null) { + sb.append(", node type: ").append(nodeB); + } + + if (label != null) { + sb.append(", label: ").append(label); + } + + sb.append(", type: "); + if (type != null) { + sb.append(type.toString()); + } else { + sb.append("any"); + } + + sb.append(", isPrivate: "); + sb.append(isPrivate); + + if (v.isPresent()) { + sb.append(", for version: ").append(v.get().toString()).append("."); + } + 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); + } + } + }