From c97cd7981fe0c68477623af9e1268a50d6f279d6 Mon Sep 17 00:00:00 2001 From: "Maharajh, Robby (rx2202)" Date: Fri, 11 Aug 2017 17:29:16 -0400 Subject: [AAI-162 Amsterdam] Convert custom queries to not use gremlin Signed-off-by: Maharajh, Robby (rx2202) Change-Id: I83892630687c7c274b9fa63942954a26397a8361 --- .../java/org/openecomp/aai/rest/QueryConsumer.java | 4 +- .../aai/rest/search/GenericQueryProcessor.java | 7 +- .../rest/search/GroovyQueryBuilderSingleton.java | 96 ++++++++++++++++++++++ 3 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 aai-traversal/src/main/java/org/openecomp/aai/rest/search/GroovyQueryBuilderSingleton.java (limited to 'aai-traversal/src/main') diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/QueryConsumer.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/QueryConsumer.java index e5f7aad..a5f476a 100644 --- a/aai-traversal/src/main/java/org/openecomp/aai/rest/QueryConsumer.java +++ b/aai-traversal/src/main/java/org/openecomp/aai/rest/QueryConsumer.java @@ -43,7 +43,6 @@ import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.UriInfo; import org.apache.tinkerpop.gremlin.structure.Vertex; - import org.openecomp.aai.dbmap.DBConnectionType; import org.openecomp.aai.exceptions.AAIException; import org.openecomp.aai.introspection.ModelType; @@ -62,6 +61,7 @@ import org.openecomp.aai.serialization.queryformats.Format; import org.openecomp.aai.serialization.queryformats.FormatFactory; import org.openecomp.aai.serialization.queryformats.Formatter; import org.openecomp.aai.serialization.queryformats.SubGraphStyle; + import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; @@ -72,7 +72,7 @@ public class QueryConsumer extends RESTAPI { /** The introspector factory type. */ private ModelType introspectorFactoryType = ModelType.MOXY; - private QueryProcessorType processorType = QueryProcessorType.GREMLIN_SERVER; + private QueryProcessorType processorType = QueryProcessorType.LOCAL_GROOVY; /** The query style. */ private QueryStyle queryStyle = QueryStyle.TRAVERSAL; @PUT diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GenericQueryProcessor.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GenericQueryProcessor.java index 2e9e6a5..e05ec7d 100644 --- a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GenericQueryProcessor.java +++ b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GenericQueryProcessor.java @@ -41,7 +41,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; import org.apache.tinkerpop.gremlin.structure.Graph; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.javatuples.Pair; - import org.openecomp.aai.restcore.util.URITools; import org.openecomp.aai.serialization.engines.TransactionalGraphEngine; import org.openecomp.aai.serialization.queryformats.SubGraphStyle; @@ -57,6 +56,7 @@ public abstract class GenericQueryProcessor { protected Optional gremlin; protected final TransactionalGraphEngine dbEngine; protected static GremlinServerSingleton gremlinServerSingleton = GremlinServerSingleton.getInstance(); + protected static GroovyQueryBuilderSingleton queryBuilderSingleton = GroovyQueryBuilderSingleton.getInstance(); protected final boolean isGremlin; protected GenericQueryProcessor(Builder builder) { @@ -127,8 +127,11 @@ public abstract class GenericQueryProcessor { query = gremlinServerSingleton.getStoredQuery(queryName); if (query == null) { query = ""; + } else { + query = queryBuilderSingleton.executeTraversal(dbEngine, query, params); } + List ids = new ArrayList<>(); if (vertices.isPresent() && !vertices.get().isEmpty()) { @@ -141,7 +144,7 @@ public abstract class GenericQueryProcessor { sb.append("]"); String startPrefix = "aaiStartQuery = " + sb.toString() + " as Object[];g.V(aaiStartQuery)"; if (!"".equals(query)) { - query = startPrefix + "." + query; + query = startPrefix + query; } else { query = startPrefix; } diff --git a/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GroovyQueryBuilderSingleton.java b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GroovyQueryBuilderSingleton.java new file mode 100644 index 0000000..7e5909c --- /dev/null +++ b/aai-traversal/src/main/java/org/openecomp/aai/rest/search/GroovyQueryBuilderSingleton.java @@ -0,0 +1,96 @@ +/*- + * ============LICENSE_START======================================================= + * org.openecomp.aai + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.aai.rest.search; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.codehaus.groovy.ast.ClassHelper; +import org.codehaus.groovy.ast.expr.ClassExpression; +import org.codehaus.groovy.ast.expr.PropertyExpression; +import org.codehaus.groovy.control.CompilerConfiguration; +import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer; +import org.codehaus.groovy.control.customizers.ImportCustomizer; +import org.openecomp.aai.query.builder.QueryBuilder; +import org.openecomp.aai.serialization.engines.QueryStyle; +import org.openecomp.aai.serialization.engines.TransactionalGraphEngine; + +import groovy.lang.Binding; +import groovy.lang.GroovyShell; +import groovy.lang.Script; +import groovy.transform.TimedInterrupt; + +/** + * Creates and returns a groovy shell with the + * configuration to statically import graph classes + * + */ +public class GroovyQueryBuilderSingleton { + + private final GroovyShell shell; + private GroovyQueryBuilderSingleton() { + Map parameters = new HashMap<>(); + parameters.put("value", 30000); + parameters.put("unit", new PropertyExpression(new ClassExpression(ClassHelper.make(TimeUnit.class)),"MILLISECONDS")); + + ASTTransformationCustomizer custom = new ASTTransformationCustomizer(parameters, TimedInterrupt.class); + ImportCustomizer imports = new ImportCustomizer(); + imports.addStaticStars( + "org.apache.tinkerpop.gremlin.process.traversal.P" + ); + imports.addImports( + "org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__", + "org.apache.tinkerpop.gremlin.structure.T", + "org.apache.tinkerpop.gremlin.process.traversal.P", + "org.openecomp.aai.serialization.db.EdgeType"); + CompilerConfiguration config = new CompilerConfiguration(); + config.addCompilationCustomizers(custom, imports); + + this.shell = new GroovyShell(config); + } + + private static class Helper { + private static final GroovyQueryBuilderSingleton INSTANCE = new GroovyQueryBuilderSingleton(); + } + + public static GroovyQueryBuilderSingleton getInstance() { + + return Helper.INSTANCE; + } + + /** + * @param traversal + * @param params + * @return result of graph traversal + */ + public String executeTraversal (TransactionalGraphEngine engine, String traversal, Map params) { + QueryBuilder builder = engine.getQueryBuilder(QueryStyle.GREMLIN_TRAVERSAL); + Binding binding = new Binding(params); + binding.setVariable("builder", builder); + Script script = shell.parse(traversal); + script.setBinding(binding); + script.run(); + + return builder.getQuery(); + } +} -- cgit 1.2.3-korg