summaryrefslogtreecommitdiffstats
path: root/aai-traversal/src/main/java
diff options
context:
space:
mode:
authorLaMont, William (wl2432) <wl2432@att.com>2019-01-11 15:21:39 -0500
committerLaMont, William (wl2432) <wl2432@us.att.com>2019-01-16 11:56:04 -0500
commit16b48ab05e63fca707585b4ecee466b8b7721a1b (patch)
treebca44c248860f73d65031162a6f5581c4fef649b /aai-traversal/src/main/java
parentc0365f15a25aed95f7e812dc1d7e7ac588ebbed5 (diff)
Update traversal to support v15
Issue-ID: AAI-2073 Change-Id: I1c3df218d1333bdebc984947edc100607958ab60 Signed-off-by: LaMont, William (wl2432) <wl2432@us.att.com>
Diffstat (limited to 'aai-traversal/src/main/java')
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/TraversalApp.java66
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/config/DslConfiguration.java6
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/config/SearchConfiguration.java26
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/dbgraphmap/SearchGraph.java3
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java42
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java82
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/RecentAPIConsumer.java17
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslContext.java38
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslListener.java46
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java72
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java21
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/CQConfig.java28
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/GenericQueryProcessor.java9
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/GremlinServerSingleton.java47
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/GroovyShellImpl.java4
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/LocalCQConfig.java85
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/NodeQueryProcessor.java6
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/SchemaServiceCQConfig.java64
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/util/TraversalConstants.java2
19 files changed, 557 insertions, 107 deletions
diff --git a/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java b/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java
index 2797545..64a3b44 100644
--- a/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java
+++ b/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java
@@ -21,10 +21,12 @@ package org.onap.aai;
import com.att.eelf.configuration.EELFLogger;
import com.att.eelf.configuration.EELFManager;
+import org.apache.commons.lang3.exception.ExceptionUtils;
import org.onap.aai.config.PropertyPasswordConfiguration;
import org.onap.aai.config.SpringContextAware;
import org.onap.aai.dbmap.AAIGraph;
import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.logging.ErrorLogHelper;
import org.onap.aai.logging.LoggingContext;
import org.onap.aai.logging.LoggingContext.StatusCode;
import org.onap.aai.nodes.NodeIngestor;
@@ -56,7 +58,8 @@ import java.util.Map;
"org.onap.aai.setup",
"org.onap.aai.tasks",
"org.onap.aai.service",
- "org.onap.aai.rest"
+ "org.onap.aai.rest",
+ "org.onap.aai.rest-client"
})
@EnableAutoConfiguration(exclude = {
@@ -122,14 +125,40 @@ public class TraversalApp {
AAIGraph.getInstance().graphShutdown();
}
- public static void main(String[] args) {
+ public static void main(String[] args) throws AAIException{
+
+ setDefaultProps();
+
+ LoggingContext.save();
+ LoggingContext.component("init");
+ LoggingContext.partnerName("NA");
+ LoggingContext.targetEntity(APP_NAME);
+ LoggingContext.requestId(UUID.randomUUID().toString());
+ LoggingContext.serviceName(APP_NAME);
+ LoggingContext.targetServiceName("contextInitialized");
+ LoggingContext.statusCode(StatusCode.COMPLETE);
+ Environment env =null;
+ AAIConfig.init();
+
+ try{
+ SpringApplication app = new SpringApplication(TraversalApp.class);
+ app.setLogStartupInfo(false);
+ app.setRegisterShutdownHook(true);
+ app.addInitializers(new PropertyPasswordConfiguration());
+ env = app.run(args).getEnvironment();
+ }
+ catch(Exception ex){
+ AAIException aai = schemaServiceExceptionTranslator(ex);
+ LoggingContext.statusCode(LoggingContext.StatusCode.ERROR);
+ LoggingContext.responseCode(LoggingContext.DATA_ERROR);
+ logger.error("Problems starting Traversal "+aai.getMessage());
+ ErrorLogHelper.logException(aai);
+ ErrorLogHelper.logError(aai.getCode(), ex.getMessage() + ", resolve and restart Traversal");
+ //ErrorLogHelper.logError(aai.getCode(), aai.getMessage() + aai.getCause().toString());
+ throw aai;
+ }
+
- setDefaultProps();
- SpringApplication app = new SpringApplication(TraversalApp.class);
- app.setLogStartupInfo(false);
- app.setRegisterShutdownHook(true);
- app.addInitializers(new PropertyPasswordConfiguration());
- Environment env = app.run(args).getEnvironment();
MDC.setContextMap (contextMap);
logger.info(
"Application '{}' is running on {}!" ,
@@ -166,4 +195,25 @@ public class TraversalApp {
}
}
+ private static AAIException schemaServiceExceptionTranslator(Exception ex) {
+ AAIException aai = null;
+ logger.info("Error Message is "+ ExceptionUtils.getRootCause(ex).toString() + " details - "+ExceptionUtils.getRootCause(ex).getMessage());
+ if(ExceptionUtils.getRootCause(ex).getMessage().contains("NodeIngestor")){
+ aai = new AAIException("AAI_3026","Error reading OXM from SchemaService - Investigate");
+ }
+ else if(ExceptionUtils.getRootCause(ex).getMessage().contains("EdgeIngestor")){
+ aai = new AAIException("AAI_3027","Error reading EdgeRules from SchemaService - Investigate");
+ }
+ else if(ExceptionUtils.getRootCause(ex).getMessage().contains("stored-queries")){
+ aai = new AAIException("AAI_3027","Error reading EdgeRules from SchemaService - Investigate");
+ }
+ else if(ExceptionUtils.getRootCause(ex).getMessage().contains("Connection refused")){
+ aai = new AAIException("AAI_3025","Error connecting to SchemaService - Investigate");
+ }
+ else {
+ aai = new AAIException("AAI_3025","Error connecting to SchemaService - Please Investigate");
+ }
+
+ return aai;
+ }
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/config/DslConfiguration.java b/aai-traversal/src/main/java/org/onap/aai/config/DslConfiguration.java
index 74bc046..311dd99 100644
--- a/aai-traversal/src/main/java/org/onap/aai/config/DslConfiguration.java
+++ b/aai-traversal/src/main/java/org/onap/aai/config/DslConfiguration.java
@@ -20,8 +20,10 @@
package org.onap.aai.config;
import org.onap.aai.edges.EdgeIngestor;
+import org.onap.aai.introspection.LoaderFactory;
import org.onap.aai.rest.dsl.DslListener;
import org.onap.aai.rest.dsl.DslQueryProcessor;
+import org.onap.aai.setup.SchemaVersions;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -32,8 +34,8 @@ public class DslConfiguration {
@Bean
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
- public DslListener dslListener(EdgeIngestor edgeIngestor){
- return new DslListener(edgeIngestor);
+ public DslListener dslListener(EdgeIngestor edgeIngestor, SchemaVersions schemaVersions, LoaderFactory loaderFactory){
+ return new DslListener(edgeIngestor, schemaVersions, loaderFactory);
}
@Bean
diff --git a/aai-traversal/src/main/java/org/onap/aai/config/SearchConfiguration.java b/aai-traversal/src/main/java/org/onap/aai/config/SearchConfiguration.java
index bef10d0..0b8238b 100644
--- a/aai-traversal/src/main/java/org/onap/aai/config/SearchConfiguration.java
+++ b/aai-traversal/src/main/java/org/onap/aai/config/SearchConfiguration.java
@@ -25,17 +25,30 @@ import org.onap.aai.edges.EdgeIngestor;
import org.onap.aai.introspection.LoaderFactory;
import org.onap.aai.rest.dsl.DslListener;
import org.onap.aai.rest.dsl.DslQueryProcessor;
+import org.onap.aai.rest.search.CQConfig;
import org.onap.aai.rest.search.GremlinServerSingleton;
+import org.onap.aai.rest.search.LocalCQConfig;
+import org.onap.aai.rest.search.SchemaServiceCQConfig;
import org.onap.aai.setup.SchemaVersions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.Scope;
@Configuration
+@PropertySource(value = "classpath:schema-ingest.properties", ignoreResourceNotFound = true)
+@PropertySource(value = "file:${schema.ingest.file}", ignoreResourceNotFound = true)
+
public class SearchConfiguration {
+ private static final String CONFIG_TRANSLATOR = "config";
+ private static final String SCHEMA_SERVICE_TRANSLATOR = "schema-service";
+
+ @Value("${schema.translator.list}")
+ private String translator;
+
@Bean
public SearchGraph searchGraph(LoaderFactory loaderFactory, EdgeIngestor edgeIngestor, SchemaVersions schemaVersions) {
SearchGraph searchGraph = new SearchGraph(loaderFactory, edgeIngestor, schemaVersions);
@@ -44,7 +57,18 @@ public class SearchConfiguration {
@Bean
public GremlinServerSingleton gremlinServerSingleton(){
- return new GremlinServerSingleton();
+ return new GremlinServerSingleton(getCustomQueryConfig());
}
+
+ @Bean
+ public CQConfig getCustomQueryConfig(){
+ if(translator.equals(SCHEMA_SERVICE_TRANSLATOR)) {
+ return new SchemaServiceCQConfig();
+ }
+ return new LocalCQConfig();
+ }
+
+
+
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/dbgraphmap/SearchGraph.java b/aai-traversal/src/main/java/org/onap/aai/dbgraphmap/SearchGraph.java
index 0725802..0221d8a 100644
--- a/aai-traversal/src/main/java/org/onap/aai/dbgraphmap/SearchGraph.java
+++ b/aai-traversal/src/main/java/org/onap/aai/dbgraphmap/SearchGraph.java
@@ -28,6 +28,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.ws.rs.core.HttpHeaders;
@@ -520,7 +521,7 @@ public class SearchGraph {
edgeRules = edgeIngestor.getRules(query);
//Map<String, EdgeRule> rules = EdgeRules.getInstance().getEdgeRules(targetNodeType, nodeType);
- String[] results = edgeRules.keySet().toArray(new String[0]);
+ String[] results = edgeRules.values().stream().map(rule -> rule.getLabel()).collect(Collectors.toList()).toArray(new String[0]);
return results;
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java b/aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java
index bdca63b..ad5fffb 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java
@@ -59,6 +59,7 @@ import org.onap.aai.serialization.queryformats.Formatter;
import org.onap.aai.serialization.queryformats.SubGraphStyle;
import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.setup.SchemaVersions;
+import org.onap.aai.util.AAIConfig;
import org.onap.aai.util.TraversalConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
@@ -104,14 +105,14 @@ public class DslConsumer extends RESTAPI {
public Response executeQuery(String content, @PathParam("version") String versionParam,
@PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat,
@DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers,
- @Context UriInfo info, @Context HttpServletRequest req) {
+ @Context UriInfo info, @Context HttpServletRequest req, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize) {
return runner(TraversalConstants.AAI_TRAVERSAL_DSL_TIMEOUT_ENABLED,
TraversalConstants.AAI_TRAVERSAL_DSL_TIMEOUT_APP, TraversalConstants.AAI_TRAVERSAL_DSL_TIMEOUT_LIMIT,
headers, info, HttpMethod.PUT, new AaiCallable<Response>() {
@Override
public Response process() {
return processExecuteQuery(content, versionParam, uri, queryFormat, subgraph, headers, info,
- req);
+ req, resultIndex, resultSize);
}
});
}
@@ -119,10 +120,11 @@ public class DslConsumer extends RESTAPI {
public Response processExecuteQuery(String content, @PathParam("version") String versionParam,
@PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat,
@DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers,
- @Context UriInfo info, @Context HttpServletRequest req) {
+ @Context UriInfo info, @Context HttpServletRequest req, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize) {
String methodName = "executeDslQuery";
String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
+ String dslOverride = headers.getRequestHeaders().getFirst("X-DslOverride");
String realTime = headers.getRequestHeaders().getFirst("Real-Time");
Response response;
SchemaVersion version = new SchemaVersion(versionParam);
@@ -132,6 +134,7 @@ public class DslConsumer extends RESTAPI {
LoggingContext.save();
DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime);
traversalUriHttpEntry.setHttpEntryProperties(version, type);
+ traversalUriHttpEntry.setPaginationParameters(resultIndex, resultSize);
dbEngine = traversalUriHttpEntry.getDbEngine();
JsonObject input = new JsonParser().parse(content).getAsJsonObject();
JsonElement dslElement = input.get("dsl");
@@ -145,29 +148,46 @@ public class DslConsumer extends RESTAPI {
LoggingContext.startTime();
StopWatch.conditionalStart();
+ boolean isDslOverride = dslOverride != null && !AAIConfig.get(TraversalConstants.DSL_OVERRIDE).equals("false")
+ && dslOverride.equals(AAIConfig.get(TraversalConstants.DSL_OVERRIDE));
+
+ if(isDslOverride)
+ dslQueryProcessor.setValidationFlag(false);
+
GenericQueryProcessor processor = new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton)
.queryFrom(dsl, "dsl").queryProcessor(dslQueryProcessor).processWith(processorType).create();
-
+
String result = "";
SubGraphStyle subGraphStyle = SubGraphStyle.valueOf(subgraph);
- List<Object> vertices = processor.execute(subGraphStyle);
-
+ List<Object> vertTemp = processor.execute(subGraphStyle);
+ List<Object> vertices = traversalUriHttpEntry.getPaginatedVertexList(vertTemp);
DBSerializer serializer = new DBSerializer(version, dbEngine, ModelType.MOXY, sourceOfTruth);
Format format = Format.getFormat(queryFormat);
FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, schemaVersions,
this.basePath);
-
+
Formatter formater = ff.get(format, info.getQueryParameters());
result = formater.output(vertices).toString();
-
+
double msecs = StopWatch.stopIfStarted();
LoggingContext.elapsedTime((long) msecs, TimeUnit.MILLISECONDS);
LoggingContext.successStatusFields();
LOGGER.info("Completed");
-
- response = Response.status(Status.OK).type(MediaType.APPLICATION_JSON).entity(result).build();
-
+
+ if(traversalUriHttpEntry.isPaginated()){
+ response = Response.status(Status.OK)
+ .type(MediaType.APPLICATION_JSON)
+ .header("total-results", traversalUriHttpEntry.getTotalVertices())
+ .header("total-pages", traversalUriHttpEntry.getTotalPaginationBuckets())
+ .entity(result)
+ .build();
+ }else {
+ response = Response.status(Status.OK)
+ .type(MediaType.APPLICATION_JSON)
+ .entity(result).build();
+ }
+
} catch (AAIException e) {
response = consumerExceptionResponseGenerator(headers, info, HttpMethod.PUT, e);
} catch (Exception e) {
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java b/aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java
index 7ce61e3..633bc9c 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java
@@ -23,8 +23,10 @@ import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
@@ -118,7 +120,7 @@ public class QueryConsumer extends RESTAPI {
@PUT
@Consumes({ MediaType.APPLICATION_JSON})
@Produces({ MediaType.APPLICATION_JSON})
- public Response executeQuery(String content, @PathParam("version")String versionParam, @PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat,@DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req){
+ public Response executeQuery(String content, @PathParam("version")String versionParam, @PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat,@DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize){
return runner(TraversalConstants.AAI_TRAVERSAL_TIMEOUT_ENABLED,
TraversalConstants.AAI_TRAVERSAL_TIMEOUT_APP,
TraversalConstants.AAI_TRAVERSAL_TIMEOUT_LIMIT,
@@ -128,14 +130,13 @@ public class QueryConsumer extends RESTAPI {
new AaiCallable<Response>() {
@Override
public Response process() {
- return processExecuteQuery(content, versionParam, uri, queryFormat, subgraph, headers, info, req);
+ return processExecuteQuery(content, versionParam, uri, queryFormat, subgraph, headers, info, req, resultIndex, resultSize);
}
}
);
}
- public Response processExecuteQuery(String content, @PathParam("version")String versionParam, @PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat,@DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req) {
-
+ public Response processExecuteQuery(String content, @PathParam("version")String versionParam, @PathParam("uri") @Encoded String uri, @DefaultValue("graphson") @QueryParam("format") String queryFormat,@DefaultValue("no_op") @QueryParam("subgraph") String subgraph, @Context HttpHeaders headers, @Context UriInfo info, @Context HttpServletRequest req, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize) {
String methodName = "executeQuery";
String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
String realTime = headers.getRequestHeaders().getFirst("Real-Time");
@@ -165,6 +166,11 @@ public class QueryConsumer extends RESTAPI {
SchemaVersion version = new SchemaVersion(versionParam);
DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime);
traversalUriHttpEntry.setHttpEntryProperties(version, type);
+ /*
+ * Changes for Pagination
+ */
+
+ traversalUriHttpEntry.setPaginationParameters(resultIndex, resultSize);
dbEngine = traversalUriHttpEntry.getDbEngine();
if (startElement != null) {
@@ -188,9 +194,17 @@ public class QueryConsumer extends RESTAPI {
CustomQueryConfig customQueryConfig = getCustomQueryConfig(queryURIObj);
if ( customQueryConfig != null ) {
List<String> missingRequiredQueryParameters = checkForMissingQueryParameters( customQueryConfig.getQueryRequiredProperties(), URITools.getQueryMap(queryURIObj));
+
if ( !missingRequiredQueryParameters.isEmpty() ) {
return( createMessageMissingQueryRequiredParameters( missingRequiredQueryParameters, headers, info, req));
}
+
+ List<String> invalidQueryParameters = checkForInvalidQueryParameters( customQueryConfig, URITools.getQueryMap(queryURIObj));
+
+ if ( !invalidQueryParameters.isEmpty() ) {
+ return( createMessageInvalidQueryParameters( invalidQueryParameters, headers, info, req));
+ }
+
} else if ( queryElement != null ) {
return( createMessageInvalidQuerySection( queryURI, headers, info, req));
}
@@ -227,8 +241,9 @@ public class QueryConsumer extends RESTAPI {
.processWith(processorType).create();
}
String result = "";
- List<Object> vertices = processor.execute(subGraphStyle);
-
+ List<Object> vertTemp = processor.execute(subGraphStyle);
+ List<Object> vertices = traversalUriHttpEntry.getPaginatedVertexList(vertTemp);
+
DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth);
FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, schemaVersions, this.basePath);
@@ -240,12 +255,19 @@ public class QueryConsumer extends RESTAPI {
LoggingContext.elapsedTime((long)msecs,TimeUnit.MILLISECONDS);
LoggingContext.successStatusFields();
LOGGER.info ("Completed");
-
-
- response = Response.status(Status.OK)
- .type(MediaType.APPLICATION_JSON)
- .entity(result).build();
+ if(traversalUriHttpEntry.isPaginated()){
+ response = Response.status(Status.OK)
+ .type(MediaType.APPLICATION_JSON)
+ .header("total-results", traversalUriHttpEntry.getTotalVertices())
+ .header("total-pages", traversalUriHttpEntry.getTotalPaginationBuckets())
+ .entity(result)
+ .build();
+ }else {
+ response = Response.status(Status.OK)
+ .type(MediaType.APPLICATION_JSON)
+ .entity(result).build();
+ }
} catch (AAIException e) {
response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, e);
} catch (Exception e ) {
@@ -340,6 +362,44 @@ public class QueryConsumer extends RESTAPI {
return response;
}
+
+
+ public List<String> checkForInvalidQueryParameters( CustomQueryConfig customQueryConfig, MultivaluedMap<String, String> queryParams) {
+
+ List<String> allParameters = new ArrayList<String>();
+ /*
+ * Add potential Required and Optional to allParameters
+ */
+ Optional.ofNullable(customQueryConfig.getQueryOptionalProperties()).ifPresent(allParameters::addAll);
+ Optional.ofNullable(customQueryConfig.getQueryRequiredProperties()).ifPresent(allParameters::addAll);
+
+ if(queryParams.isEmpty())
+ return new ArrayList<>();
+ List<String> invalidParameters = queryParams.keySet().stream()
+ .filter(param -> !allParameters.contains(param))
+ .collect(Collectors.toList());
+
+ return invalidParameters;
+
+ }
+
+ private Response createMessageInvalidQueryParameters(List<String> invalidQueryParams, HttpHeaders headers, UriInfo info, HttpServletRequest req) {
+ AAIException e = new AAIException("AAI_3022");
+
+ ArrayList<String> templateVars = new ArrayList<>();
+
+ if (templateVars.isEmpty()) {
+ templateVars.add(invalidQueryParams.toString());
+ }
+
+ Response response = Response
+ .status(e.getErrorObject().getHTTPResponseCode())
+ .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e,
+ templateVars)).build();
+
+ return response;
+ }
+
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/RecentAPIConsumer.java b/aai-traversal/src/main/java/org/onap/aai/rest/RecentAPIConsumer.java
index 46bccdf..3154087 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/RecentAPIConsumer.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/RecentAPIConsumer.java
@@ -224,8 +224,13 @@ public class RecentAPIConsumer extends RESTAPI {
if (params != null && params.containsKey("hours") && params.getFirst("hours").matches("-?\\d+")) {
isHoursParameter = true;
-
- Long hours = Long.parseLong(params.getFirst("hours"));
+ Long hours = 0L;
+ try{
+ hours = Long.parseLong(params.getFirst("hours"));
+ }
+ catch(NumberFormatException ex){
+ throw new AAIException("AAI_3021", " Invalid Hours. Valid values for hours are 1 to " + AAIConstants.HISTORY_MAX_HOURS);
+ }
if (hours < 1 || hours > AAIConstants.HISTORY_MAX_HOURS) {
throw new AAIException("AAI_3021", " Valid values for hours are 1 to " + AAIConstants.HISTORY_MAX_HOURS);
}
@@ -233,7 +238,13 @@ public class RecentAPIConsumer extends RESTAPI {
if (params != null && params.containsKey("date-time") && params.getFirst("date-time").matches("-?\\d+")) {
isDateTimeParameter = true;
Long minStartTime = System.currentTimeMillis() - TimeUnit.HOURS.toMillis(AAIConstants.HISTORY_MAX_HOURS);
- Long startTime = Long.parseLong(params.getFirst("date-time"));
+ Long startTime = 0L;
+ try{
+ startTime = Long.parseLong(params.getFirst("date-time"));
+ }
+ catch(NumberFormatException ex){
+ throw new AAIException("AAI_3021", " Invalid Data-time. Valid values for date-time are "+minStartTime+" to " + System.currentTimeMillis() );
+ }
if (startTime < minStartTime) {
throw new AAIException("AAI_3021", " Valid values for date-time are "+minStartTime+" to " + System.currentTimeMillis() );
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslContext.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslContext.java
index 3a3cc96..9ffa69b 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslContext.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslContext.java
@@ -19,8 +19,10 @@
*/
package org.onap.aai.rest.dsl;
+import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
+import java.util.List;
import org.antlr.v4.runtime.ParserRuleContext;
@@ -28,8 +30,12 @@ public class DslContext {
private ParserRuleContext ctx;
+ private boolean validationFlag = true;
+ private boolean isStartNode = false;
+ private String startNode = "";
+ private List<String> startNodeKeys = new ArrayList<String>();
+
private String currentNode;
-
private String previousNode;
private boolean isTraversal = false;
@@ -38,7 +44,7 @@ public class DslContext {
private boolean isUnionStart = false;
private String whereStartNode = "";
-
+
private Deque<String> unionStartNodes = new LinkedList<String>();
/*
@@ -55,6 +61,26 @@ public class DslContext {
this.ctx = ctx;
}
+ public boolean isStartNode() {
+ return isStartNode;
+ }
+
+ public void setStartNodeFlag(boolean isStartNode) {
+ this.isStartNode = isStartNode;
+ }
+
+ public String getStartNode() {
+ return startNode;
+ }
+
+ public void setStartNode(String startNode) {
+ this.startNode = startNode;
+ }
+
+ public List<String> getStartNodeKeys() {
+ return startNodeKeys;
+ }
+
public String getCurrentNode() {
return currentNode;
}
@@ -126,5 +152,13 @@ public class DslContext {
public void setLimitQuery(StringBuilder limitQuery) {
this.limitQuery = limitQuery;
}
+
+ public boolean isValidationFlag() {
+ return validationFlag;
+ }
+
+ public void setValidationFlag(boolean validationFlag) {
+ this.validationFlag = validationFlag;
+ }
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslListener.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslListener.java
index ecd04ac..a6be24c 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslListener.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslListener.java
@@ -29,9 +29,17 @@ import java.util.List;
import org.antlr.v4.runtime.tree.TerminalNode;
import org.onap.aai.AAIDslParser;
+import org.onap.aai.config.SpringContextAware;
import org.onap.aai.edges.EdgeRuleQuery;
import org.onap.aai.edges.enums.EdgeType;
import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.LoaderFactory;
+import org.onap.aai.introspection.ModelType;
+import org.onap.aai.logging.LogFormatTools;
+import org.onap.aai.setup.SchemaVersion;
+import org.onap.aai.setup.SchemaVersions;
import org.springframework.beans.factory.annotation.Autowired;
import org.onap.aai.AAIDslBaseListener;
import org.onap.aai.edges.EdgeIngestor;
@@ -54,18 +62,32 @@ public class DslListener extends AAIDslBaseListener {
* Instantiates a new DslListener.
*/
@Autowired
- public DslListener(EdgeIngestor edgeIngestor) {
+ public DslListener(EdgeIngestor edgeIngestor, SchemaVersions schemaVersions, LoaderFactory loaderFactory) {
this.edgeRules = edgeIngestor;
context = new DslContext();
- dslBuilder = new DslQueryBuilder(edgeIngestor);
+
+ Loader loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion());
+ dslBuilder = new DslQueryBuilder(edgeIngestor, loader);
}
- public String getQuery() {
+ public String getQuery() throws AAIException {
+ if (!getException().isEmpty()) {
+ LOGGER.error("Exception in the DSL Query" + getException());
+ throw new AAIException("AAI_6149", getException());
+ }
return dslBuilder.getQuery().toString();
}
+ public String getException() {
+ return dslBuilder.getQueryException().toString();
+ }
+
@Override
public void enterAaiquery(AAIDslParser.AaiqueryContext ctx) {
+ /*
+ * This is my start-node, have some validations here
+ */
+ context.setStartNodeFlag(true);
dslBuilder.start();
}
@@ -131,6 +153,14 @@ public class DslListener extends AAIDslBaseListener {
@Override
public void exitSingleNodeStep(AAIDslParser.SingleNodeStepContext ctx) {
+ if (context.isStartNode() && isValidationFlag()) {
+ try {
+ dslBuilder.validateFilter(context);
+ } catch (AAIException e) {
+ LOGGER.error("AAIException in DslListener" + LogFormatTools.getStackTop(e));
+ }
+ }
+ context.setStartNodeFlag(false);
context.setCtx(ctx);
dslBuilder.store(context);
}
@@ -186,6 +216,7 @@ public class DslListener extends AAIDslBaseListener {
@Override
public void enterFilterStep(AAIDslParser.FilterStepContext ctx) {
+
context.setCtx(ctx);
dslBuilder.filter(context);
}
@@ -210,4 +241,13 @@ public class DslListener extends AAIDslBaseListener {
context.setCtx(ctx);
dslBuilder.limit(context);
}
+
+ public void setValidationFlag(boolean validationFlag) {
+ this.context.setValidationFlag(validationFlag);
+ }
+
+ public boolean isValidationFlag() {
+ return this.context.isValidationFlag();
+ }
+
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java
index 59f4443..fce8a98 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java
@@ -21,6 +21,7 @@ package org.onap.aai.rest.dsl;
import java.util.ArrayList;
import java.util.List;
+import java.util.Set;
import java.util.stream.Collectors;
import org.antlr.v4.runtime.tree.TerminalNode;
@@ -32,15 +33,24 @@ import org.onap.aai.edges.EdgeIngestor;
import org.onap.aai.edges.EdgeRuleQuery;
import org.onap.aai.edges.enums.EdgeType;
import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Introspector;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
+
+import com.jcabi.log.Logger;
public class DslQueryBuilder {
private StringBuilder query;
+ private StringBuilder queryException;
private final EdgeIngestor edgeRules;
+ private final Loader loader;
- public DslQueryBuilder(EdgeIngestor edgeIngestor) {
+ public DslQueryBuilder(EdgeIngestor edgeIngestor, Loader loader) {
this.edgeRules = edgeIngestor;
+ this.loader = loader;
query = new StringBuilder();
+ queryException = new StringBuilder();
}
public StringBuilder getQuery() {
@@ -51,6 +61,14 @@ public class DslQueryBuilder {
this.query = query;
}
+ public StringBuilder getQueryException() {
+ return queryException;
+ }
+
+ public void setQueryException(StringBuilder queryException) {
+ this.queryException = queryException;
+ }
+
public DslQueryBuilder start() {
query.append("builder");
return this;
@@ -68,6 +86,8 @@ public class DslQueryBuilder {
public DslQueryBuilder nodeQuery(DslContext context) {
query.append(".getVerticesByProperty('aai-node-type', '").append(context.getCurrentNode()).append("')");
+ if(context.isStartNode() && context.getStartNode().isEmpty())
+ context.setStartNode(context.getCurrentNode());
return this;
}
@@ -76,7 +96,7 @@ public class DslQueryBuilder {
String edgeType = "";
if (!edgeRules.hasRule(baseQ.build())) {
throw new AAIException("AAI_6120", "No EdgeRule found for passed nodeTypes: " + context.getPreviousNode()
- + ", " + context.getCurrentNode());
+ + ", " + context.getCurrentNode());
} else if (edgeRules.hasRule(baseQ.edgeType(EdgeType.TREE).build())) {
edgeType = "EdgeType.TREE";
} else if (edgeRules.hasRule(baseQ.edgeType(EdgeType.COUSIN).build())) {
@@ -85,7 +105,7 @@ public class DslQueryBuilder {
edgeType = "EdgeType.COUSIN";
query.append(".createEdgeTraversal(").append(edgeType).append(", '").append(context.getPreviousNode())
- .append("','").append(context.getCurrentNode()).append("')");
+ .append("','").append(context.getCurrentNode()).append("')");
return this;
}
@@ -142,21 +162,53 @@ public class DslQueryBuilder {
}
+ public DslQueryBuilder validateFilter(DslContext context) throws AAIException {
+ Introspector obj = loader.introspectorFromName(context.getStartNode());
+ if(context.getStartNodeKeys().isEmpty()){
+ queryException.append("No keys sent. Valid keys for " + context.getStartNode() + " are "
+ + String.join(",", obj.getIndexedProperties()));
+ return this;
+ }
+ boolean notIndexed = context.getStartNodeKeys().stream()
+ .filter((prop) -> obj.getIndexedProperties().contains(prop)).collect(Collectors.toList()).isEmpty();
+ if (notIndexed)
+ queryException.append("Non indexed keys sent. Valid keys for " + context.getStartNode() + " "
+ + String.join(",", obj.getIndexedProperties()));
+
+ return this;
+ }
+
public DslQueryBuilder filterPropertyKeys(DslContext context) {
AAIDslParser.FilterStepContext ctx = (AAIDslParser.FilterStepContext) context.getCtx();
final String key = ctx.KEY(0).getText();
-
- query.append(key);
+ /*
+ * This key should be indexed if it is start node
+ */
+ if (context.isStartNode() && context.getStartNodeKeys().isEmpty()) {
+ // check if key is not indexed, then throw exception
+ context.getStartNodeKeys().add(key.replaceAll("'", ""));
+ }
+ query.append(key);
List<TerminalNode> nodes = ctx.KEY();
+ List<TerminalNode> numberValues = ctx.NODE();
+ /*
+ * Add all String values
+ */
List<String> valuesArray = nodes.stream().filter((node) -> !key.equals(node.getText()))
- .map((node) -> "'" + node.getText().replace("'", "").trim() + "'")
- .collect(Collectors.toList());
+ .map((node) -> "'" + node.getText().replace("'", "").trim() + "'").collect(Collectors.toList());
+
+ /*
+ * Add all numeric values
+ */
+ valuesArray.addAll(numberValues.stream().filter((node) -> !key.equals(node.getText()) )
+ .map((node) -> node.getText()).collect(Collectors.toList()));
+
/*
- * The whole point of doing this to separate P.within from key-value search
- * For a list of values QB uses P.within
- * For just a single value QB uses key,value check
+ * The whole point of doing this to separate P.within from key-value
+ * search For a list of values QB uses P.within For just a single value
+ * QB uses key,value check
*/
if (nodes.size() > 2) {
String values = String.join(",", valuesArray);
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java
index b2be402..d9ce63e 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java
@@ -30,7 +30,7 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
import org.onap.aai.AAIDslLexer;
import org.onap.aai.AAIDslParser;
-
+import org.onap.aai.exceptions.AAIException;
import org.onap.aai.rest.dsl.DslListener;
import org.antlr.v4.runtime.Token;
@@ -46,13 +46,14 @@ public class DslQueryProcessor {
private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(DslQueryProcessor.class);
private DslListener dslListener;
+ private boolean validationFlag = true;
@Autowired
- public DslQueryProcessor(DslListener dslListener){
+ public DslQueryProcessor(DslListener dslListener) {
this.dslListener = dslListener;
}
- public String parseAaiQuery(String aaiQuery) {
+ public String parseAaiQuery(String aaiQuery) throws AAIException {
try {
// Create a input stream that reads our string
InputStream stream = new ByteArrayInputStream(aaiQuery.getBytes(StandardCharsets.UTF_8));
@@ -63,10 +64,10 @@ public class DslQueryProcessor {
// Get a list of tokens pulled from the lexer
CommonTokenStream tokens = new CommonTokenStream(lexer);
-
// Parser that feeds off of the tokens buffer
AAIDslParser parser = new AAIDslParser(tokens);
+ dslListener.setValidationFlag(isValidationFlag());
// Specify our entry point
ParseTree ptree = parser.aaiquery();
LOGGER.info("QUERY-interim" + ptree.toStringTree(parser));
@@ -82,9 +83,17 @@ public class DslQueryProcessor {
*
*/
return dslListener.getQuery();
+ } catch (AAIException e) {
+ throw new AAIException("AAI_6149", "Error while processing the query :" + e.getMessage());
} catch (Exception e) {
- LOGGER.error("Error while processing the query"+e.getMessage());
+ throw new AAIException("AAI_6149","Error while processing the query :" + e.getMessage());
}
- return "";
+ }
+ public boolean isValidationFlag() {
+ return validationFlag;
+ }
+
+ public void setValidationFlag(boolean validationFlag) {
+ this.validationFlag = validationFlag;
}
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/CQConfig.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/CQConfig.java
new file mode 100644
index 0000000..d17fb2b
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/CQConfig.java
@@ -0,0 +1,28 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.onap.aai.rest.search;
+
+public abstract class CQConfig {
+ protected GetCustomQueryConfig queryConfig;
+
+ public GetCustomQueryConfig getCustomQueryConfig(){
+ return queryConfig;
+ }
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/GenericQueryProcessor.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/GenericQueryProcessor.java
index fd9d53b..56b748c 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/search/GenericQueryProcessor.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/GenericQueryProcessor.java
@@ -27,11 +27,10 @@ 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.onap.aai.config.SpringContextAware;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.query.builder.MissingOptionalParameter;
import org.onap.aai.rest.dsl.DslQueryProcessor;
-import org.onap.aai.restcore.search.GroovyQueryBuilderSingleton;
+import org.onap.aai.restcore.search.GroovyQueryBuilder;
import org.onap.aai.restcore.util.URITools;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
import org.onap.aai.serialization.queryformats.SubGraphStyle;
@@ -55,7 +54,7 @@ public abstract class GenericQueryProcessor {
protected Optional<String> gremlin;
protected final TransactionalGraphEngine dbEngine;
protected GremlinServerSingleton gremlinServerSingleton;
- protected static GroovyQueryBuilderSingleton queryBuilderSingleton = GroovyQueryBuilderSingleton.getInstance();
+ protected GroovyQueryBuilder groovyQueryBuilder = new GroovyQueryBuilder();
protected final boolean isGremlin;
protected Optional<DslQueryProcessor> dslQueryProcessorOptional;
/* dsl parameters to store dsl query and to check
@@ -130,7 +129,7 @@ public abstract class GenericQueryProcessor {
String dslUserQuery = dsl.get();
if(dslQueryProcessorOptional.isPresent()){
String dslQuery = dslQueryProcessorOptional.get().parseAaiQuery(dslUserQuery);
- query = queryBuilderSingleton.executeTraversal(dbEngine, dslQuery, params);
+ query = groovyQueryBuilder.executeTraversal(dbEngine, dslQuery, params);
String startPrefix = "g.V()";
query = startPrefix + query;
}
@@ -179,7 +178,7 @@ public abstract class GenericQueryProcessor {
if (query == null) {
query = "";
} else {
- query = queryBuilderSingleton.executeTraversal(dbEngine, query, params);
+ query = groovyQueryBuilder.executeTraversal(dbEngine, query, params);
}
String startPrefix = "g.V(startVertexes)";
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/GremlinServerSingleton.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/GremlinServerSingleton.java
index 20a18d9..9ae3dec 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/search/GremlinServerSingleton.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/GremlinServerSingleton.java
@@ -25,6 +25,7 @@ import org.onap.aai.util.FileWatcher;
import com.att.eelf.configuration.EELFLogger;
import com.att.eelf.configuration.EELFManager;
import org.apache.tinkerpop.gremlin.driver.Cluster;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import javax.annotation.PostConstruct;
@@ -47,11 +48,8 @@ public class GremlinServerSingleton {
private boolean timerSet;
private Timer timer;
- private GetCustomQueryConfig queryConfig;
-
- @Value("${schema.queries.location}")
- private String storedQueriesLocation;
+ CQConfig customQueryInfo;
/**
* Initializes the gremlin server singleton
* Loads the configuration of the gremlin server and creates a cluster
@@ -61,41 +59,9 @@ public class GremlinServerSingleton {
* the properties object
*
*/
- @PostConstruct
- public void init() {
-
- try {
- String filepath = storedQueriesLocation + AAIConstants.AAI_FILESEP + "stored-queries.json";
- Path path = Paths.get(filepath);
- String customQueryConfigJson = new String(Files.readAllBytes(path));
-
-
- queryConfig = new GetCustomQueryConfig(customQueryConfigJson);
- } catch (IOException e) {
- logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e));
- }
-
-
- TimerTask task = new FileWatcher(new File(storedQueriesLocation)) {
- @Override
- protected void onChange(File file) {
- try {
- String filepath = storedQueriesLocation;
- Path path = Paths.get(filepath);
- String customQueryConfigJson = new String(Files.readAllBytes(path));
- queryConfig = new GetCustomQueryConfig(customQueryConfigJson);
- } catch (IOException e) {
- logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e));
- }
- }
- };
-
- if (!timerSet) {
- timerSet = true;
- timer = new Timer();
- timer.schedule( task , new Date(), 10000 );
- }
-
+ @Autowired
+ public GremlinServerSingleton(CQConfig customQueryInfo){
+ this.customQueryInfo = customQueryInfo;
}
/**
@@ -104,6 +70,8 @@ public class GremlinServerSingleton {
* @return
*/
public String getStoredQueryFromConfig(String key){
+ GetCustomQueryConfig queryConfig = customQueryInfo.getCustomQueryConfig();
+
CustomQueryConfig customQueryConfig = queryConfig.getStoredQuery(key);
if ( customQueryConfig == null ) {
return null;
@@ -112,6 +80,7 @@ public class GremlinServerSingleton {
}
public CustomQueryConfig getCustomQueryConfig(String key) {
+ GetCustomQueryConfig queryConfig = customQueryInfo.getCustomQueryConfig();
return queryConfig.getStoredQuery(key);
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/GroovyShellImpl.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/GroovyShellImpl.java
index de59262..712d7f0 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/search/GroovyShellImpl.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/GroovyShellImpl.java
@@ -23,7 +23,7 @@ import java.util.Map;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
-import org.onap.aai.restcore.search.GremlinGroovyShellSingleton;
+import org.onap.aai.restcore.search.GremlinGroovyShell;
public class GroovyShellImpl extends GenericQueryProcessor {
@@ -36,7 +36,7 @@ public class GroovyShellImpl extends GenericQueryProcessor {
params.put("g", this.dbEngine.asAdmin().getTraversalSource());
- GremlinGroovyShellSingleton shell = GremlinGroovyShellSingleton.getInstance();
+ GremlinGroovyShell shell = new GremlinGroovyShell();
return shell.executeTraversal(query, params);
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/LocalCQConfig.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/LocalCQConfig.java
new file mode 100644
index 0000000..bcd4c4e
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/LocalCQConfig.java
@@ -0,0 +1,85 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.onap.aai.rest.search;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.onap.aai.logging.LogFormatTools;
+import org.onap.aai.util.AAIConstants;
+import org.onap.aai.util.FileWatcher;
+import org.springframework.beans.factory.annotation.Value;
+
+import javax.annotation.PostConstruct;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Date;
+import java.util.Timer;
+import java.util.TimerTask;
+
+public class LocalCQConfig extends CQConfig {
+ private static EELFLogger logger = EELFManager.getInstance().getLogger(LocalCQConfig.class);
+
+ @Value("${schema.queries.location}")
+ private String storedQueriesLocation;
+
+ private boolean timerSet;
+ private Timer timer;
+
+ @PostConstruct
+ public void init() {
+
+ try {
+ String filepath = storedQueriesLocation + AAIConstants.AAI_FILESEP + "stored-queries.json";
+ logger.info("Using the Local stored queries");
+ Path path = Paths.get(filepath);
+ String customQueryConfigJson = new String(Files.readAllBytes(path));
+ queryConfig = new GetCustomQueryConfig(customQueryConfigJson);
+
+ } catch (IOException e) {
+ logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e));
+ }
+
+ TimerTask task = new FileWatcher(new File(storedQueriesLocation)) {
+ @Override
+ protected void onChange(File file) {
+ try {
+ String filepath = storedQueriesLocation;
+ Path path = Paths.get(filepath);
+ String customQueryConfigJson = new String(Files.readAllBytes(path));
+ queryConfig = new GetCustomQueryConfig(customQueryConfigJson);
+
+ } catch (IOException e) {
+ logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e));
+ }
+ }
+ };
+
+ if (!timerSet) {
+ timerSet = true;
+ timer = new Timer();
+ timer.schedule(task, new Date(), 10000);
+ }
+
+ }
+
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/NodeQueryProcessor.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/NodeQueryProcessor.java
index 0126162..6421f67 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/search/NodeQueryProcessor.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/NodeQueryProcessor.java
@@ -28,7 +28,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.javatuples.Pair;
import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.restcore.search.GroovyQueryBuilderSingleton;
+import org.onap.aai.restcore.search.GroovyQueryBuilder;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
import org.onap.aai.serialization.queryformats.SubGraphStyle;
@@ -49,7 +49,7 @@ public class NodeQueryProcessor extends GroovyShellImpl {
protected static Pattern p = Pattern.compile("query/(.*+)");
protected Optional<String> gremlin;
protected final TransactionalGraphEngine dbEngine;
- protected static GroovyQueryBuilderSingleton queryBuilderSingleton = GroovyQueryBuilderSingleton.getInstance();;
+ protected GroovyQueryBuilder queryBuilder = new GroovyQueryBuilder();;
protected NodeQueryProcessor(Builder builder) {
super(builder);
@@ -82,7 +82,7 @@ public class NodeQueryProcessor extends GroovyShellImpl {
params.put("startTime", startTime);
params.put("nodeType", nodeType);
- query = queryBuilderSingleton.executeTraversal(dbEngine, query, params);
+ query = queryBuilder.executeTraversal(dbEngine, query, params);
String startPrefix = "g.V()";
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/SchemaServiceCQConfig.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/SchemaServiceCQConfig.java
new file mode 100644
index 0000000..6e55246
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/SchemaServiceCQConfig.java
@@ -0,0 +1,64 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2017-2018 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.onap.aai.rest.search;
+
+import com.att.eelf.configuration.EELFLogger;
+import com.att.eelf.configuration.EELFManager;
+import org.onap.aai.restclient.RestClient;
+import org.onap.aai.restclient.RestClientFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.ResponseEntity;
+
+import javax.annotation.PostConstruct;
+import java.util.HashMap;
+import java.util.Map;
+
+public class SchemaServiceCQConfig extends CQConfig {
+
+ private static EELFLogger logger = EELFManager.getInstance().getLogger(SchemaServiceCQConfig.class);
+ private static final String SCHEMA_SERVICE = "schema-service";
+
+ @Value("${schema.service.custom.queries.endpoint}")
+ private String customQueriesUri;
+
+ @Autowired
+ private RestClientFactory restClientFactory;
+
+ @PostConstruct
+ public void initialize() {
+ //Call SchemaService to get custom queries
+ retrieveCustomQueries();
+ }
+
+ public void retrieveCustomQueries() {
+ /*
+ Call Schema MS to get custom queries using RestTemplate
+ */
+ logger.info("Calling the SchemaService to retrieve stored queries");
+ String content = "";
+ Map<String, String> headersMap = new HashMap<>();
+ RestClient restClient = restClientFactory
+ .getRestClient(SCHEMA_SERVICE);
+
+ ResponseEntity<String> schemaResponse = restClient.getGetRequest(content, customQueriesUri, headersMap);
+ queryConfig = new GetCustomQueryConfig(schemaResponse.getBody());
+ }
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/util/TraversalConstants.java b/aai-traversal/src/main/java/org/onap/aai/util/TraversalConstants.java
index 69e1e9f..4b5ebfe 100644
--- a/aai-traversal/src/main/java/org/onap/aai/util/TraversalConstants.java
+++ b/aai-traversal/src/main/java/org/onap/aai/util/TraversalConstants.java
@@ -29,6 +29,8 @@ public final class TraversalConstants {
public static final String AAI_TRAVERSAL_DSL_TIMEOUT_LIMIT = "aai.traversal.dsl.timeoutlimit";
public static final String AAI_TRAVERSAL_DSL_TIMEOUT_ENABLED = "aai.traversal.dsl.timeoutenabled";
public static final String AAI_TRAVERSAL_DSL_TIMEOUT_APP = "aai.traversal.dsl.timeout.appspecific";
+ public static final String DSL_NOVALIDATION_CLIENTS = "aai.traversal.dsl.novalidation.clients";
+ public static final String DSL_OVERRIDE = "aai.dsl.override";
public static final long HISTORY_MAX_HOURS = 192;