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=========================================================
21 package org.onap.aai.query.builder;
23 import java.util.HashMap;
24 import java.util.List;
26 import java.util.Optional;
27 import java.util.stream.Collectors;
29 import org.apache.tinkerpop.gremlin.process.traversal.Step;
30 import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
31 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
32 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
33 import org.apache.tinkerpop.gremlin.process.traversal.util.TraversalHelper;
34 import org.apache.tinkerpop.gremlin.structure.Vertex;
35 import org.onap.aai.db.props.AAIProperties;
36 import org.onap.aai.introspection.Introspector;
37 import org.onap.aai.introspection.Loader;
38 import org.onap.aai.schema.enums.ObjectMetadata;
40 public class TraversalURIOptimizedQuery<E> extends TraversalQuery {
42 protected Map<Integer, String> stepToAaiUri = new HashMap<>();
44 public TraversalURIOptimizedQuery(Loader loader, GraphTraversalSource source) {
45 super(loader, source);
49 public TraversalURIOptimizedQuery(Loader loader, GraphTraversalSource source, Vertex start) {
50 super(loader, source, start);
54 protected TraversalURIOptimizedQuery(GraphTraversal traversal, Loader loader, GraphTraversalSource source,
55 GraphTraversalBuilder gtb) {
56 super(traversal, loader, source, gtb);
60 protected TraversalURIOptimizedQuery(GraphTraversal traversal, Loader loader, GraphTraversalSource source,
61 GraphTraversalBuilder gtb, Map<Integer, String> stepToAaiUri) {
62 super(traversal, loader, source, gtb);
63 optimize = gtb.optimize;
64 this.stepToAaiUri = stepToAaiUri;
68 protected void executeQuery() {
70 this.completeTraversal = this.traversal.asAdmin().clone();
73 this.completeTraversal = this.pivotTraversal(this.completeTraversal);
77 Traversal.Admin admin = source.V().asAdmin();
78 TraversalHelper.insertTraversal(admin.getEndStep(), completeTraversal, admin);
80 this.completeTraversal = (Traversal.Admin<Vertex, E>) admin;
86 private Traversal.Admin<Vertex, E> pivotTraversal(Traversal.Admin<Vertex, E> traversalAdmin) {
88 List<Step> steps = traversalAdmin.getSteps();
90 Traversal.Admin<Vertex, E> traversalAdminStart = traversalAdmin.clone();
92 // if we do not have an index or other conditions do no optimization
93 if (stepToAaiUri.isEmpty()) {
94 return traversalAdmin;
97 int lastURIStepKey = getLastURIStepKey();
99 // clean up traversal steps
100 for (int i = 0; i < steps.size(); i++) {
101 traversalAdminStart.removeStep(0);
104 ((GraphTraversal<Vertex, E>) traversalAdminStart).has(AAIProperties.AAI_URI, stepToAaiUri.get(lastURIStepKey));
105 for (int i = lastURIStepKey; i < steps.size(); i++) {
106 traversalAdminStart.addStep(steps.get(i));
109 return traversalAdminStart;
113 public QueryBuilder<Vertex> createKeyQuery(Introspector obj) {
114 super.createKeyQuery(obj);
116 if (shouldAddStepUri(obj)) {
117 Optional<String> uri = getStepUriFromIntrospector(obj);
118 if (uri.isPresent()) {
119 if (stepToAaiUri.isEmpty()) {
120 stepToAaiUri.put(stepIndex + 1, uri.get());
122 stepToAaiUri.put(stepIndex, uri.get());
127 stepToAaiUri = new HashMap<>();
129 return (QueryBuilder<Vertex>) this;
132 private boolean shouldAddStepUri(Introspector obj) {
133 boolean shouldOptimize = optimize;
135 if (shouldOptimize && start != null) {
136 shouldOptimize = false;
139 if (shouldOptimize && stepToAaiUri.isEmpty() && !obj.isTopLevel()) {
140 shouldOptimize = false;
143 if (shouldOptimize && obj.getMetadata(ObjectMetadata.ABSTRACT) != null) {
144 shouldOptimize = false;
147 return shouldOptimize;
151 private Optional<String> getStepUriFromIntrospector(Introspector obj) {
155 } catch (Exception e) {
158 if ("".equals(uri)) {
159 return Optional.empty();
162 if (!stepToAaiUri.isEmpty()) {
163 uri = stepToAaiUri.get(getLastURIStepKey()) + uri;
166 return Optional.of(uri);
169 private int getLastURIStepKey() {
170 return stepToAaiUri.keySet().stream().mapToInt(Integer::intValue).max().getAsInt();
173 private Map<Integer, String> getStepToAaiUriWithoutStepGreaterThan(final int index) {
174 return stepToAaiUri.entrySet().stream().filter(kv -> kv.getKey() <= index)
175 .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
179 protected QueryBuilder<E> cloneQueryAtStep(int index) {
180 GraphTraversal.Admin<Vertex, E> cloneAdmin = getCloneAdmin(index);
181 return new TraversalURIOptimizedQuery<>(cloneAdmin, loader, source, this,
182 getStepToAaiUriWithoutStepGreaterThan(index));