2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 you may not use this file except in compliance with the License.
9 You may obtain a copy of the License at
11 http://www.apache.org/licenses/LICENSE-2.0
13 Unless required by applicable law or agreed to in writing, software
14 distributed under the License is distributed on an "AS IS" BASIS,
15 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 See the License for the specific language governing permissions and
17 limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.openecomp.aai.query.builder;
23 import java.util.ArrayList;
24 import java.util.HashMap;
25 import java.util.LinkedHashMap;
26 import java.util.List;
30 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
31 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
32 import org.apache.tinkerpop.gremlin.structure.Direction;
33 import org.apache.tinkerpop.gremlin.structure.Vertex;
35 import org.openecomp.aai.db.props.AAIProperties;
36 import org.openecomp.aai.exceptions.AAIException;
37 import org.openecomp.aai.introspection.Introspector;
38 import org.openecomp.aai.introspection.Loader;
39 import org.openecomp.aai.restcore.search.GremlinGroovyShellSingleton;
40 import org.openecomp.aai.schema.enums.ObjectMetadata;
41 import org.openecomp.aai.serialization.db.EdgeRule;
42 import org.openecomp.aai.serialization.db.EdgeRules;
43 import org.openecomp.aai.serialization.db.EdgeType;
44 import org.openecomp.aai.serialization.db.exceptions.NoEdgeRuleFoundException;
45 import com.google.common.base.Joiner;
48 * The Class GremlinQueryBuilder.
50 public abstract class GremlinQueryBuilder extends QueryBuilder {
52 private EdgeRules edgeRules = EdgeRules.getInstance();
53 private GremlinGroovyShellSingleton gremlinGroovy = GremlinGroovyShellSingleton.getInstance();
54 private GraphTraversal<?, ?> completeTraversal = null;
55 protected List<String> list = null;
57 protected int parentStepIndex = 0;
58 protected int containerStepIndex = 0;
59 protected int stepIndex = 0;
62 * Instantiates a new gremlin query builder.
64 * @param loader the loader
66 public GremlinQueryBuilder(Loader loader, GraphTraversalSource source) {
67 super(loader, source);
68 list = new ArrayList<String>();
72 * Instantiates a new gremlin query builder.
74 * @param loader the loader
75 * @param start the start
77 public GremlinQueryBuilder(Loader loader, GraphTraversalSource source, Vertex start) {
78 super(loader, source, start);
79 list = new ArrayList<String>();
86 public QueryBuilder createDBQuery(Introspector obj) {
87 this.createKeyQuery(obj);
88 this.createContainerQuery(obj);
93 public QueryBuilder exactMatchQuery(Introspector obj) {
94 // TODO not implemented because this is implementation is no longer used
95 this.createKeyQuery(obj);
96 //allPropertiesQuery(obj);
97 this.createContainerQuery(obj);
105 public QueryBuilder getVerticesByIndexedProperty(String key, Object value) {
106 return this.getVerticesByProperty(key, value);
113 public QueryBuilder getVerticesByIndexedProperty(String key, List<?> values) {
114 return this.getVerticesByProperty(key, values);
121 public QueryBuilder getVerticesByProperty(String key, Object value) {
124 if (value != null && !value.getClass().getName().equals("java.lang.String")) {
125 term = value.toString();
127 term = "'" + value + "'";
129 list.add(".has('" + key + "', " + term + ")");
138 public QueryBuilder getVerticesByProperty(String key, List<?> values) {
141 String predicate = "P.within(#!#argument#!#)";
142 List<String> arguments = new ArrayList<>();
143 for (Object item : values) {
144 if (item != null && !item.getClass().getName().equals("java.lang.String")) {
145 arguments.add(item.toString());
147 arguments.add("'" + item + "'");
150 String argument = Joiner.on(",").join(arguments);
151 predicate = predicate.replace("#!#argument#!#", argument);
152 list.add(".has('" + key + "', " + predicate + ")");
162 public QueryBuilder getChildVerticesFromParent(String parentKey, String parentValue, String childType) {
164 String query = ".has('aai-node-type', '" + childType + "')";
166 return this.processGremlinQuery(parentKey, parentValue, query);
176 public QueryBuilder getTypedVerticesByMap(String type, LinkedHashMap<String, String> map) {
178 for (String key : map.keySet()) {
179 list.add(".has('" + key + "', '" + map.get(key) + "')");
182 list.add(".has('aai-node-type', '" + type + "')");
191 public QueryBuilder createKeyQuery(Introspector obj) {
192 Set<String> keys = obj.getKeys();
194 for (String key : keys) {
196 this.getVerticesByProperty(key, obj.<Object>getValue(key));
203 * @throws NoEdgeRuleFoundException
204 * @throws AAIException
208 public QueryBuilder createEdgeTraversal(EdgeType type, Introspector parent, Introspector child) throws AAIException, NoEdgeRuleFoundException {
209 String parentName = parent.getDbName();
210 String childName = child.getDbName();
211 if (parent.isContainer()) {
212 parentName = parent.getChildDBName();
214 if (child.isContainer()) {
215 childName = child.getChildDBName();
217 this.edgeQuery(type, parentName, childName);
223 * @throws NoEdgeRuleFoundException
224 * @throws AAIException
228 public QueryBuilder createEdgeTraversal(EdgeType type, Vertex parent, Introspector child) throws AAIException, NoEdgeRuleFoundException {
229 String nodeType = parent.<String>property(AAIProperties.NODE_TYPE).orElse(null);
230 this.edgeQuery(type, nodeType, child.getDbName());
239 * @param outType the out type
240 * @param inType the in type
241 * @throws NoEdgeRuleFoundException
242 * @throws AAIException
244 private void edgeQuery(EdgeType type, String outType, String inType) throws AAIException, NoEdgeRuleFoundException {
245 markParentBoundary();
246 EdgeRule rule = edgeRules.getEdgeRule(type, outType, inType);
247 if (rule.getDirection().equals(Direction.OUT)) {
248 list.add(".out('" + rule.getLabel() + "')");
250 list.add(".in('" + rule.getLabel() + "')");
252 list.add(".has('" + AAIProperties.NODE_TYPE + "', '" + inType + "')");
256 public QueryBuilder limit(long amount) {
257 list.add(".limit(" + amount + ")");
264 public QueryBuilder createContainerQuery(Introspector obj) {
265 String type = obj.getChildDBName();
266 String abstractType = obj.getMetadata(ObjectMetadata.ABSTRACT);
267 if (abstractType != null) {
268 String[] inheritors = obj.getMetadata(ObjectMetadata.INHERITORS).split(",");
269 String[] wrapped = new String[inheritors.length];
270 StringBuilder command = new StringBuilder();
271 command.append("P.within(");
272 for (int i = 0; i < inheritors.length; i++) {
273 wrapped[i] = "'" + inheritors[i] + "'";
275 command.append(Joiner.on(",").join(wrapped));
277 list.add(".has('aai-node-type', " + command + ")");
280 list.add(".has('aai-node-type', '" + type + "')");
283 this.markContainer();
288 public QueryBuilder union(QueryBuilder... builder) {
289 markParentBoundary();
290 String[] traversals = new String[builder.length];
291 StringBuilder command = new StringBuilder();
292 for (int i = 0; i < builder.length; i++) {
293 traversals[i] = "__" + (String)builder[i].getQuery();
295 command.append(".union(");
296 command.append(Joiner.on(",").join(traversals));
298 list.add(command.toString());
305 public QueryBuilder where(QueryBuilder... builder) {
306 markParentBoundary();
307 List<String> traversals = new ArrayList<>();
308 for (int i = 0; i < builder.length; i++) {
309 traversals.add(".where(__" + (String)builder[i].getQuery() + ")");
312 list.addAll(traversals);
322 public QueryBuilder getParentQuery() {
323 return cloneQueryAtStep(parentStepIndex);
327 public QueryBuilder getContainerQuery() {
328 return cloneQueryAtStep(containerStepIndex);
335 public <T> T getQuery() {
336 StringBuilder sb = new StringBuilder();
338 for (String piece : this.list) {
342 return (T)sb.toString();
349 public void markParentBoundary() {
350 parentStepIndex = stepIndex;
354 public void markContainer() {
355 this.containerStepIndex = stepIndex;
358 protected abstract QueryBuilder cloneQueryAtStep(int index);
363 public Vertex getStart() {
367 protected int getParentStepIndex() {
368 return parentStepIndex;
371 protected int getContainerStepIndex() {
372 return containerStepIndex;
375 protected int getStepIndex() {
379 private void executeQuery() {
380 String queryString = "g" + Joiner.on("").join(list);
381 Map<String, Object> params = new HashMap<>();
382 if (this.start == null) {
383 params.put("g", source.V());
385 params.put("g", source.V(this.start));
387 this.completeTraversal = this.gremlinGroovy.executeTraversal(queryString, params);
390 public boolean hasNext() {
391 if (this.completeTraversal == null) {
395 return this.completeTraversal.hasNext();
399 public Vertex next() {
400 if (this.completeTraversal == null) {
404 return (Vertex)this.completeTraversal.next();
408 public List<Vertex> toList() {
409 if (this.completeTraversal == null) {
413 return (List<Vertex>)this.completeTraversal.toList();