2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 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=========================================================
20 package org.onap.aai.query.builder;
22 import org.apache.tinkerpop.gremlin.process.traversal.Step;
23 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
24 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
25 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
26 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
27 import org.apache.tinkerpop.gremlin.structure.Vertex;
28 import org.onap.aai.db.props.AAIProperties;
29 import org.onap.aai.introspection.Introspector;
30 import org.onap.aai.introspection.Loader;
31 import org.onap.aai.schema.enums.ObjectMetadata;
33 import java.util.HashMap;
34 import java.util.List;
36 import java.util.Optional;
37 import java.util.stream.Collectors;
39 public class TraversalURIOptimizedQuery<E> extends TraversalQuery {
41 protected Map<Integer, String> stepToAaiUri = new HashMap<>();
43 public TraversalURIOptimizedQuery(Loader loader, GraphTraversalSource source) {
44 super(loader, source);
48 public TraversalURIOptimizedQuery(Loader loader, GraphTraversalSource source, Vertex start) {
49 super(loader, source, start);
53 protected TraversalURIOptimizedQuery(GraphTraversal traversal, Loader loader, GraphTraversalSource source, GraphTraversalBuilder gtb) {
54 super(traversal, loader, source, gtb);
58 protected TraversalURIOptimizedQuery(GraphTraversal traversal, Loader loader, GraphTraversalSource source, GraphTraversalBuilder gtb, Map<Integer, String> stepToAaiUri) {
59 super(traversal, loader, source, gtb);
60 optimize = gtb.optimize;
61 this.stepToAaiUri = stepToAaiUri;
65 protected void executeQuery() {
67 this.completeTraversal = this.traversal.asAdmin().clone();
70 this.completeTraversal = this.pivotTraversal(this.completeTraversal);
74 Traversal.Admin admin = source.V().asAdmin();
75 TraversalHelper.insertTraversal(admin.getEndStep(), completeTraversal, admin);
77 this.completeTraversal = (Traversal.Admin<Vertex, E>) admin;
83 private Traversal.Admin<Vertex,E> pivotTraversal(Traversal.Admin<Vertex, E> traversalAdmin) {
85 List<Step> steps = traversalAdmin.getSteps();
87 Traversal.Admin<Vertex, E> traversalAdminStart = traversalAdmin.clone();
89 //if we do not have an index or other conditions do no optimization
90 if (stepToAaiUri.isEmpty()) {
91 return traversalAdmin;
94 int lastURIStepKey = getLastURIStepKey();
96 //clean up traversal steps
97 for (int i = 0; i < steps.size(); i++) {
98 traversalAdminStart.removeStep(0);
101 ((GraphTraversal<Vertex, E>)traversalAdminStart).has(AAIProperties.AAI_URI, stepToAaiUri.get(lastURIStepKey));
102 for (int i = lastURIStepKey; i < steps.size(); i++) {
103 traversalAdminStart.addStep(steps.get(i));
106 return traversalAdminStart;
110 public QueryBuilder<Vertex> createKeyQuery(Introspector obj) {
111 super.createKeyQuery(obj);
113 if (shouldAddStepUri(obj)) {
114 Optional<String> uri = getStepUriFromIntrospector(obj);
115 if (uri.isPresent()) {
116 if (stepToAaiUri.isEmpty()) {
117 stepToAaiUri.put(stepIndex + 1, uri.get());
119 stepToAaiUri.put(stepIndex, uri.get());
124 stepToAaiUri = new HashMap<>();
126 return (QueryBuilder<Vertex>) this;
129 private boolean shouldAddStepUri(Introspector obj) {
130 boolean shouldOptimize = optimize;
132 if (shouldOptimize && start != null) {
133 shouldOptimize = false;
136 if (shouldOptimize && stepToAaiUri.isEmpty() && !obj.isTopLevel()) {
137 shouldOptimize = false;
140 if (shouldOptimize && obj.getMetadata(ObjectMetadata.ABSTRACT) != null) {
141 shouldOptimize = false;
144 return shouldOptimize;
148 private Optional<String> getStepUriFromIntrospector(Introspector obj) {
152 } catch (Exception e) {
155 if ("".equals(uri)) {
156 return Optional.empty();
159 if (!stepToAaiUri.isEmpty()) {
160 uri = stepToAaiUri.get(getLastURIStepKey()) + uri;
163 return Optional.of(uri);
166 private int getLastURIStepKey() {
167 return stepToAaiUri.keySet().stream().mapToInt(Integer::intValue).max().getAsInt();
170 private Map<Integer, String> getStepToAaiUriWithoutStepGreaterThan(final int index) {
171 return stepToAaiUri.entrySet().stream().filter(kv -> kv.getKey() <= index).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
175 protected QueryBuilder<E> cloneQueryAtStep(int index) {
176 GraphTraversal.Admin<Vertex, E> cloneAdmin = getCloneAdmin(index);
177 return new TraversalURIOptimizedQuery<>(cloneAdmin, loader, source, this, getStepToAaiUriWithoutStepGreaterThan(index));