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();