summaryrefslogtreecommitdiffstats
path: root/aai-traversal/src/main/java/org
diff options
context:
space:
mode:
authorLaMont, William(wl2432) <wl2432@att.com>2020-04-17 16:46:13 -0400
committerLaMont, William(wl2432) <wl2432@att.com>2020-04-20 09:10:49 -0400
commit87f84fdb2df41aa7c00de94018fe606939d4d6f7 (patch)
tree0badd3a0d4bde6c899b3ea51286d0799dda05487 /aai-traversal/src/main/java/org
parent5cf32ed7941231f55819a6f5e39e7f674d174009 (diff)
update traversal processing for v19
Issue-ID: AAI-2866 Change-Id: I344e095e6f1d3b117971c1c78e50ae58bebf27e4 Signed-off-by: LaMont, William(wl2432) <wl2432@att.com>
Diffstat (limited to 'aai-traversal/src/main/java/org')
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/Profiles.java3
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/TraversalApp.java100
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/aailog/logs/AaiDBTraversalMetricLog.java115
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/config/DslConfiguration.java17
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java15
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/config/SearchConfiguration.java2
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/dbgraphgen/ModelBasedProcessing.java17
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/dbgraphmap/SearchGraph.java116
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java4
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResetLoggingContext.java98
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseTransactionLogging.java68
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java2
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/interceptors/pre/HeaderValidation.java64
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java18
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/interceptors/pre/SetLoggingContext.java69
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java2
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/CQ2Gremlin.java30
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/CQ2GremlinTest.java68
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java168
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java253
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/RecentAPIConsumer.java91
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/TraversalConsumer.java232
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslContext.java10
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryBuilder.java128
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java145
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/Edge.java59
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/EdgeLabel.java48
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/v1/DslListener.java (renamed from aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslListener.java)121
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/v2/DslListener.java353
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslQueryValidator.java62
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslSchemaValidator.java32
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslValidator.java58
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslValidatorRule.java141
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/enums/EdgeDirection.java48
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/enums/QueryVersion.java25
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/GenericQueryProcessor.java143
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/GremlinServerSingleton.java6
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/GroovyShellImpl.java20
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/LocalCQConfig.java17
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/ModelAndNamedQueryRestProvider.java130
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/NodeQueryProcessor.java7
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/SchemaServiceCQConfig.java12
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/search/SearchProvider.java114
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/util/AAIExtensionMap.java826
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/service/AuthorizationService.java7
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/transforms/MapTraverser.java10
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/util/MakeNamedQuery.java5
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/util/TraversalConstants.java3
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/web/JerseyConfiguration.java194
49 files changed, 3200 insertions, 1076 deletions
diff --git a/aai-traversal/src/main/java/org/onap/aai/Profiles.java b/aai-traversal/src/main/java/org/onap/aai/Profiles.java
index ea65b9a..25f51c3 100644
--- a/aai-traversal/src/main/java/org/onap/aai/Profiles.java
+++ b/aai-traversal/src/main/java/org/onap/aai/Profiles.java
@@ -25,7 +25,10 @@ public final class Profiles {
public static final String DME2 = "dme2";
public static final String ONE_WAY_SSL = "one-way-ssl";
+ // AAF Basic Auth
public static final String AAF_AUTHENTICATION = "aaf-auth";
+ // AAF Auth with Client Certs
+ public static final String AAF_CERT_AUTHENTICATION = "aaf-cert-auth";
public static final String TWO_WAY_SSL = "two-way-ssl";
private Profiles(){}
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 4d8f4a8..64f99b9 100644
--- a/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java
+++ b/aai-traversal/src/main/java/org/onap/aai/TraversalApp.java
@@ -19,35 +19,38 @@
*/
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.aailog.logs.AaiDebugLog;
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.logging.LogFormatTools;
import org.onap.aai.nodes.NodeIngestor;
import org.onap.aai.util.AAIConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
-import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.env.Environment;
-import org.slf4j.MDC;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
-import java.util.UUID;
+
import java.util.Map;
-@SpringBootApplication
+@SpringBootApplication(exclude = {
+ DataSourceAutoConfiguration.class,
+ DataSourceTransactionManagerAutoConfiguration.class,
+ HibernateJpaAutoConfiguration.class
+})
// Component Scan provides a way to look for spring beans
// It only searches beans in the following packages
// Any method annotated with @Bean annotation or any class
@@ -59,17 +62,17 @@ import java.util.Map;
"org.onap.aai.tasks",
"org.onap.aai.service",
"org.onap.aai.rest",
- "org.onap.aai.rest-client"
-})
-
-@EnableAutoConfiguration(exclude = {
- DataSourceAutoConfiguration.class,
- DataSourceTransactionManagerAutoConfiguration.class,
- HibernateJpaAutoConfiguration.class
+ "org.onap.aai.aaf",
+ "org.onap.aai.aailog"
})
public class TraversalApp {
- private static final EELFLogger logger = EELFManager.getInstance().getLogger(TraversalApp.class.getName());
+ private static final Logger logger = LoggerFactory.getLogger(TraversalApp.class.getName());
+
+ private static AaiDebugLog debugLog = new AaiDebugLog();
+ static {
+ debugLog.setupMDC();
+ }
private static final String APP_NAME = "aai-traversal";
private static Map<String,String> contextMap;
@@ -92,26 +95,18 @@ public class TraversalApp {
System.setProperty("org.onap.aai.serverStarted", "false");
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);
contextMap = MDC.getCopyOfContextMap();
- logger.info("AAI Server initialization started...");
+ logger.debug("AAI Server initialization started...");
// Setting this property to allow for encoded slash (/) in the path parameter
// This is only needed for tomcat keeping this as temporary
System.setProperty("org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH", "true");
- logger.info("Starting AAIGraph connections and the NodeInjestor");
+ logger.debug("Starting AAIGraph connections and the NodeInjestor");
if(env.acceptsProfiles(Profiles.TWO_WAY_SSL) && env.acceptsProfiles(Profiles.ONE_WAY_SSL)){
- logger.warn("You have seriously misconfigured your application");
+ logger.debug("You have seriously misconfigured your application");
}
AAIConfig.init();
@@ -121,6 +116,9 @@ public class TraversalApp {
@PreDestroy
public void cleanup(){
+ contextMap = MDC.getCopyOfContextMap();
+ MDC.setContextMap (contextMap);
+ logger.debug("Traversal MicroService stopped");
logger.info("Shutting down both realtime and cached connections");
AAIGraph.getInstance().graphShutdown();
}
@@ -129,14 +127,6 @@ public class TraversalApp {
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();
@@ -149,12 +139,8 @@ public class TraversalApp {
}
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;
}
@@ -166,8 +152,6 @@ public class TraversalApp {
env.getProperty("server.port")
);
- logger.info("Traversal MicroService Started");
- logger.error("Traversal MicroService Started");
logger.debug("Traversal MicroService Started");
System.out.println("Traversal Microservice Started");
}
@@ -198,22 +182,24 @@ 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");
- }
+ logger.info("Error Message is {} details - {}", ExceptionUtils.getRootCause(ex).toString(), ExceptionUtils.getRootCause(ex).getMessage());
+ if ( ExceptionUtils.getRootCause(ex) == null || ExceptionUtils.getRootCause(ex).getMessage() == null ) {
+ aai = new AAIException("AAI_3025","Error parsing exception - Please Investigate" +
+ LogFormatTools.getStackTop(ex));
+ } else {
+ logger.info("Exception is " + ExceptionUtils.getRootCause(ex).getMessage() + "Root cause is"+ ExceptionUtils.getRootCause(ex).toString());
+ 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("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/aailog/logs/AaiDBTraversalMetricLog.java b/aai-traversal/src/main/java/org/onap/aai/aailog/logs/AaiDBTraversalMetricLog.java
new file mode 100644
index 0000000..8afc58b
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/aailog/logs/AaiDBTraversalMetricLog.java
@@ -0,0 +1,115 @@
+/**
+ * ============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.aailog.logs;
+
+import org.onap.aai.util.AAIConstants;
+import org.onap.logging.filter.base.Constants;
+import org.onap.logging.filter.base.MDCSetup;
+import org.onap.logging.filter.base.ONAPComponents;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
+import org.slf4j.*;
+import org.springframework.beans.factory.annotation.Value;
+
+import java.net.URI;
+import java.time.ZoneOffset;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Optional;
+
+public class AaiDBTraversalMetricLog extends MDCSetup {
+
+ protected static final Logger logger = LoggerFactory.getLogger(AaiDBTraversalMetricLog.class);
+ private final String partnerName;
+ private static final Marker INVOKE_RETURN = MarkerFactory.getMarker("INVOKE-RETURN");
+ private static final String TARGET_ENTITY = ONAPComponents.AAI.toString() + ".DB";
+ public AaiDBTraversalMetricLog(String subcomponent) {
+ partnerName = getPartnerName(subcomponent);
+ }
+
+
+ protected String getTargetServiceName(Optional<URI> uri) {
+ return (getServiceName(uri));
+ }
+
+ protected String getServiceName(Optional<URI> uri) {
+ String serviceName = Constants.DefaultValues.UNKNOWN;
+ if (uri.isPresent()) {
+ serviceName = uri.get().getPath();
+ if (serviceName != null && (!serviceName.isEmpty())) {
+ serviceName = serviceName.replaceAll(",", "\\\\,");
+ }
+ }
+ return serviceName;
+ }
+
+
+ protected String getTargetEntity(Optional<URI> uri) {
+ return TARGET_ENTITY;
+ }
+
+ protected String getPartnerName(@Value(AAIConstants.AAI_TRAVERSAL_MS) String subcomponent ) {
+ StringBuilder sb = new StringBuilder(ONAPComponents.AAI.toString()).append(subcomponent);
+ return (sb.toString());
+ }
+
+ public void pre(Optional<URI> uri) {
+ try {
+ setupMDC(uri);
+ setLogTimestamp();
+ logger.info(ONAPLogConstants.Markers.INVOKE, "Invoke");
+ } catch (Exception e) {
+ logger.warn("Error in AaiDBMetricLog pre", e.getMessage());
+ }
+ }
+
+ public void post() {
+ try {
+ setLogTimestamp();
+ setElapsedTimeInvokeTimestamp();
+ setResponseStatusCode(200);
+ setResponseDescription(200);
+ MDC.put(ONAPLogConstants.MDCs.RESPONSE_CODE, "200");
+ logger.info(INVOKE_RETURN, "InvokeReturn");
+ clearClientMDCs();
+ } catch (Exception e) {
+ logger.warn("Error in AaiDBMetricLog post", e.getMessage());
+ }
+ }
+
+ protected void setupMDC(Optional<URI> uri) {
+ MDC.put("InvokeTimestamp", ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT));
+ MDC.put("TargetServiceName", this.getTargetServiceName(uri));
+ MDC.put("StatusCode", ONAPLogConstants.ResponseStatus.INPROGRESS.toString());
+ this.setInvocationIdFromMDC();
+ if (MDC.get("TargetEntity") == null) {
+ String targetEntity = this.getTargetEntity(uri);
+ if (targetEntity != null) {
+ MDC.put("TargetEntity", targetEntity);
+ } else {
+ MDC.put("TargetEntity", "Unknown-Target-Entity");
+ }
+ }
+ if (MDC.get("ServiceName") == null) {
+ MDC.put("ServiceName", this.getServiceName(uri));
+ }
+ this.setServerFQDN();
+ }
+}
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 311dd99..d10d4ac 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
@@ -19,28 +19,35 @@
*/
package org.onap.aai.config;
+import org.antlr.v4.runtime.tree.ParseTreeListener;
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.enums.QueryVersion;
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;
import org.springframework.context.annotation.Scope;
+import java.util.HashMap;
+import java.util.Map;
+
@Configuration
public class DslConfiguration {
@Bean
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
- public DslListener dslListener(EdgeIngestor edgeIngestor, SchemaVersions schemaVersions, LoaderFactory loaderFactory){
- return new DslListener(edgeIngestor, schemaVersions, loaderFactory);
+ public Map<QueryVersion, ParseTreeListener> dslListeners(EdgeIngestor edgeIngestor, SchemaVersions schemaVersions, LoaderFactory loaderFactory){
+ Map<QueryVersion, ParseTreeListener> dslListeners = new HashMap<>();
+ dslListeners.put(QueryVersion.V1,new org.onap.aai.rest.dsl.v1.DslListener(edgeIngestor, schemaVersions, loaderFactory));
+ dslListeners.put(QueryVersion.V2,new org.onap.aai.rest.dsl.v2.DslListener(edgeIngestor, schemaVersions, loaderFactory));
+ return dslListeners;
}
@Bean
@Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
- public DslQueryProcessor dslQueryProcessor(DslListener dslListener){
- return new DslQueryProcessor(dslListener);
+ public DslQueryProcessor dslQueryProcessor(Map<QueryVersion, ParseTreeListener> dslListeners){
+ return new DslQueryProcessor(dslListeners);
}
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java b/aai-traversal/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java
index 0d2ff88..0a76d6d 100644
--- a/aai-traversal/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java
+++ b/aai-traversal/src/main/java/org/onap/aai/config/PropertyPasswordConfiguration.java
@@ -29,7 +29,8 @@ import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import com.att.eelf.configuration.EELFLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.att.eelf.configuration.EELFManager;
import org.apache.commons.io.IOUtils;
import org.springframework.context.ApplicationContextInitializer;
@@ -40,7 +41,7 @@ public class PropertyPasswordConfiguration implements ApplicationContextInitiali
private static final Pattern decodePasswordPattern = Pattern.compile("password\\((.*?)\\)");
private PasswordDecoder passwordDecoder = new JettyPasswordDecoder();
- private static final EELFLogger logger = EELFManager.getInstance().getLogger(PropertyPasswordConfiguration.class.getName());
+ private static final Logger logger = LoggerFactory.getLogger(PropertyPasswordConfiguration.class.getName());
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
@@ -68,10 +69,10 @@ public class PropertyPasswordConfiguration implements ApplicationContextInitiali
sslProps.put("server.ssl.key-store-password", keystorePassword);
sslProps.put("schema.service.ssl.key-store-password", keystorePassword);
} else {
- logger.info("Not using AAF Certman password file");
+ logger.debug("Not using AAF Certman password file");
}
} catch (IOException e) {
- logger.warn("Not using AAF Certman password file, e=" + e.getMessage());
+ logger.debug("Not using AAF Certman password file, e=" + e.getMessage());
} finally {
if (passwordStream != null) {
try {
@@ -95,10 +96,10 @@ public class PropertyPasswordConfiguration implements ApplicationContextInitiali
sslProps.put("server.ssl.trust-store-password", truststorePassword);
sslProps.put("schema.service.ssl.trust-store-password", truststorePassword);
} else {
- logger.info("Not using AAF Certman passphrases file");
+ logger.debug("Not using AAF Certman passphrases file");
}
} catch (IOException e) {
- logger.warn("Not using AAF Certman passphrases file, e=" + e.getMessage());
+ logger.debug("Not using AAF Certman passphrases file, e=" + e.getMessage());
} finally {
if (passphrasesStream != null) {
try {
@@ -118,7 +119,7 @@ public class PropertyPasswordConfiguration implements ApplicationContextInitiali
}
if (!sslProps.isEmpty()) {
- logger.info("Using AAF Certman files");
+ logger.debug("Using AAF Certman files");
PropertySource<?> additionalProperties = new MapPropertySource("additionalProperties", sslProps);
environment.getPropertySources().addFirst(additionalProperties);
}
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 0b8238b..b60a707 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
@@ -23,7 +23,7 @@ import org.onap.aai.dbgraphmap.SearchGraph;
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.v1.DslListener;
import org.onap.aai.rest.dsl.DslQueryProcessor;
import org.onap.aai.rest.search.CQConfig;
import org.onap.aai.rest.search.GremlinServerSingleton;
diff --git a/aai-traversal/src/main/java/org/onap/aai/dbgraphgen/ModelBasedProcessing.java b/aai-traversal/src/main/java/org/onap/aai/dbgraphgen/ModelBasedProcessing.java
index dc42120..f1ffb9f 100644
--- a/aai-traversal/src/main/java/org/onap/aai/dbgraphgen/ModelBasedProcessing.java
+++ b/aai-traversal/src/main/java/org/onap/aai/dbgraphgen/ModelBasedProcessing.java
@@ -19,7 +19,9 @@
*/
package org.onap.aai.dbgraphgen;
-import com.att.eelf.configuration.EELFLogger;
+import org.onap.aai.logging.ErrorLogHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.att.eelf.configuration.EELFManager;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
@@ -58,7 +60,7 @@ import java.util.concurrent.TimeUnit;
*/
public class ModelBasedProcessing {
- private EELFLogger LOGGER = EELFManager.getInstance().getLogger(ModelBasedProcessing.class);
+ private Logger LOGGER = LoggerFactory.getLogger(ModelBasedProcessing.class);
private final int MAX_LEVELS = 50; // max depth allowed for our model - to protect against infinite loop problems
private TransactionalGraphEngine engine;
@@ -842,7 +844,8 @@ public class ModelBasedProcessing {
}
catch (Exception ex) {
// Sometimes things have already been deleted by the time we get to them - just log it.
- LOGGER.warn("Exception when trying to delete: " + thisGuyStr + ". msg = " + ex.getMessage() + LogFormatTools.getStackTop(ex));
+ AAIException aaiException = new AAIException("AAI_6154", thisGuyStr + ". msg = " + ex.getMessage());
+ ErrorLogHelper.logException(aaiException);
}
if( !gotVtxOK ){
@@ -853,7 +856,7 @@ public class ModelBasedProcessing {
}
else {
if( resSet.getNewDataDelFlag() != null && resSet.getNewDataDelFlag().equals("T") ){
- LOGGER.info(">> will try to delete this one >> " + thisGuyStr);
+ LOGGER.debug(">> will try to delete this one >> " + thisGuyStr);
try {
Boolean requireResourceVersion = false;
@@ -870,9 +873,10 @@ public class ModelBasedProcessing {
throw ae;
}
else {
+ ErrorLogHelper.logException(ae);
String errText = ae.getErrorObject().getErrorText();
String errDetail = ae.getMessage();
- LOGGER.warn("Exception when deleting " + thisGuyStr + ". ErrorCode = " + errorCode +
+ LOGGER.debug("Exception when deleting " + thisGuyStr + ". ErrorCode = " + errorCode +
", errorText = " + errText + ", details = " + errDetail);
}
}
@@ -880,7 +884,8 @@ public class ModelBasedProcessing {
// We'd expect to get a "node not found" here sometimes depending on the order that
// the model has us finding / deleting nodes.
// Ignore the exception - but log it so we can see what happened.
- LOGGER.warn("Exception when deleting " + thisGuyStr + e.getMessage() + LogFormatTools.getStackTop(e));
+ AAIException aaiException = new AAIException("AAI_6154", thisGuyStr + ". msg = " + e.getMessage());
+ ErrorLogHelper.logException(aaiException);
}
// We can't depend on a thrown exception to tell us if a node was deleted since it may
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 a8f0153..d0e881d 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
@@ -19,24 +19,10 @@
*/
package org.onap.aai.dbgraphmap;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-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;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriBuilderException;
-import javax.xml.bind.JAXBException;
-
+import com.google.common.base.CaseFormat;
+import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.Multimap;
+import edu.emory.mathcs.backport.java.util.Collections;
import org.apache.commons.lang3.StringUtils;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
@@ -52,42 +38,42 @@ import org.onap.aai.db.props.AAIProperties;
import org.onap.aai.dbgen.PropertyLimitDesc;
import org.onap.aai.dbgraphgen.ModelBasedProcessing;
import org.onap.aai.dbgraphgen.ResultSet;
-import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.edges.EdgeIngestor;
import org.onap.aai.edges.EdgeRule;
import org.onap.aai.edges.EdgeRuleQuery;
import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.extensions.AAIExtensionMap;
-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.introspection.MoxyLoader;
+import org.onap.aai.introspection.*;
import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
+import org.onap.aai.logging.ErrorLogHelper;
import org.onap.aai.parsers.relationship.RelationshipToURI;
import org.onap.aai.query.builder.QueryBuilder;
+import org.onap.aai.rest.util.AAIExtensionMap;
import org.onap.aai.schema.enums.ObjectMetadata;
import org.onap.aai.schema.enums.PropertyMetadata;
import org.onap.aai.serialization.db.DBSerializer;
-import org.onap.aai.serialization.engines.QueryStyle;
import org.onap.aai.serialization.engines.JanusGraphDBEngine;
+import org.onap.aai.serialization.engines.QueryStyle;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
import org.onap.aai.serialization.queryformats.exceptions.AAIFormatVertexException;
import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
import org.onap.aai.setup.SchemaVersions;
+import org.onap.aai.util.GenericQueryBuilder;
import org.onap.aai.util.NodesQueryBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-import com.google.common.base.CaseFormat;
-
-import edu.emory.mathcs.backport.java.util.Collections;
-
-import com.google.common.collect.ArrayListMultimap;
-import com.google.common.collect.Multimap;
-import org.onap.aai.util.GenericQueryBuilder;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.UriBuilderException;
+import javax.xml.bind.JAXBException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
/**
@@ -97,7 +83,7 @@ import org.onap.aai.util.GenericQueryBuilder;
*/
public class SearchGraph {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(SearchGraph.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(SearchGraph.class);
private LoaderFactory loaderFactory;
@@ -145,11 +131,10 @@ public class SearchGraph {
// for now query it directly without attempting to craft a valid URI
if (genericQueryBuilder.getStartNodeType().equalsIgnoreCase("service-instance")
&& genericQueryBuilder.getStartNodeKeyParams().size() == 1) {
- Introspector obj =
- genericQueryBuilder.getLoader().introspectorFromName(genericQueryBuilder.getStartNodeType());
+ genericQueryBuilder.getLoader().introspectorFromName(genericQueryBuilder.getStartNodeType());
// Build a hash with keys to uniquely identify the start Node
- String keyName = null;
- String keyValue = null;
+ String keyName;
+ String keyValue;
QueryBuilder builder = genericQueryBuilder.getDbEngine().getQueryBuilder()
.getVerticesByIndexedProperty(AAIProperties.NODE_TYPE, "service-instance");
@@ -185,7 +170,7 @@ public class SearchGraph {
Vertex startNode = results.get(0);
Collection<Vertex> ver = new HashSet<>();
- List<Vertex> queryResults = new ArrayList<>();
+ List<Vertex> queryResults;
GraphTraversalSource traversalSource =
genericQueryBuilder.getDbEngine().asAdmin().getReadOnlyTraversalSource();
GraphTraversal<Vertex, Vertex> traversal;
@@ -204,7 +189,8 @@ public class SearchGraph {
if (queryResults.isEmpty()) {
- LOGGER.warn("No nodes found - apipe was null/empty");
+ AAIException aaiException = new AAIException("AAI_6114", "No nodes found - apipe was null/empty");
+ ErrorLogHelper.logException(aaiException);
} else {
Introspector searchResults = createSearchResults(genericQueryBuilder.getLoader(),
@@ -218,7 +204,7 @@ public class SearchGraph {
result = searchResults.marshal(properties);
response = Response.ok().entity(result).build();
- LOGGER.debug(ver.size() + " node(s) traversed, " + queryResults.size() + " found");
+ LOGGER.debug("{} node(s) traversed, {} found", ver.size(), queryResults.size());
}
success = true;
} catch (AAIException e) {
@@ -286,8 +272,7 @@ public class SearchGraph {
Introspector target;
- if (StringUtils.isBlank(nodesQuery.getTargetNodeType())
- || StringUtils.isBlank(nodesQuery.getTargetNodeType())) {
+ if (StringUtils.isBlank(nodesQuery.getTargetNodeType())) {
throw new AAIException("AAI_6120", "null or empty target-node-type passed to the node query");
}
@@ -300,13 +285,11 @@ public class SearchGraph {
if (nodesQuery.getFilterParams().isEmpty() && nodesQuery.getEdgeFilterParams().isEmpty()) {
// For now, it's ok to pass no filter params. We'll just return ALL the nodes of the requested type.
- LOGGER.warn("No filters passed to the node query");
+ LOGGER.debug("No filters passed to the node query");
}
- StringBuilder queryStringForMsg = new StringBuilder();
GraphTraversal<Vertex, Vertex> traversal = nodesQuery.getDbEngine().asAdmin().getReadOnlyTraversalSource()
.V().has(AAIProperties.NODE_TYPE, nodesQuery.getTargetNodeType());
- queryStringForMsg.append("has(\"aai-node-type\"," + nodesQuery.getTargetNodeType() + ")");
for (String filter : nodesQuery.getFilterParams()) {
String[] pieces = filter.split(":");
@@ -322,13 +305,12 @@ public class SearchGraph {
String value = "?";
if (pieces.length == 3) {
value = pieces[2];
- } else if (pieces.length > 3) {
+ } else { // length > 3
// When a ipv6 address comes in as a value, it has colons in it which require us to
// pull the "value" off the end of the filter differently
int startPos4Value = propName.length() + filterType.length() + 3;
value = filter.substring(startPos4Value);
}
- queryStringForMsg.append(".has(" + propName + "," + value + ")");
traversal.has(propName, value);
} else if (filterType.equals(DOES_NOT_EQUAL)) {
if (pieces.length < 3) {
@@ -337,19 +319,16 @@ public class SearchGraph {
String value = "?";
if (pieces.length == 3) {
value = pieces[2];
- } else if (pieces.length > 3) {
+ } else { // length > 3
// When a ipv6 address comes in as a value, it has colons in it which require us to
// pull the "value" off the end of the filter differently
int startPos4Value = propName.length() + filterType.length() + 3;
value = filter.substring(startPos4Value);
}
- queryStringForMsg.append(".hasNot(" + propName + "," + value + ")");
traversal.not(__.has(propName, value));
} else if (filterType.equals(EXISTS)) {
- queryStringForMsg.append(".has(" + propName + ")");
traversal.has(propName);
} else if (filterType.equals(DOES_NOT_EXIST)) {
- queryStringForMsg.append(".hasNot(" + propName + ")");
traversal.hasNot(propName);
} else {
throw new AAIException("AAI_6120", "bad filterType passed: [" + filterType + "]");
@@ -400,7 +379,7 @@ public class SearchGraph {
if (filterType.equals(DOES_NOT_EXIST)) {
traversal.where(__.not(edgeSearch));
- } else if (filterType.equals(EXISTS)) {
+ } else {
traversal.where(edgeSearch);
}
}
@@ -521,7 +500,7 @@ public class SearchGraph {
* @throws AAIException the AAI exception
*/
public Response runNamedQuery(String fromAppId, String transId, String queryParameters,
- DBConnectionType connectionType, AAIExtensionMap aaiExtMap) throws JAXBException, AAIException {
+ AAIExtensionMap aaiExtMap) throws AAIException {
Introspector inventoryItems;
boolean success = true;
@@ -531,7 +510,7 @@ public class SearchGraph {
MoxyLoader loader = (MoxyLoader) loaderFactory.createLoaderForVersion(ModelType.MOXY,
schemaVersions.getDefaultVersion());
DynamicJAXBContext jaxbContext = loader.getJAXBContext();
- dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, connectionType, loader);
+ dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, loader);
DBSerializer serializer =
new DBSerializer(schemaVersions.getDefaultVersion(), dbEngine, ModelType.MOXY, fromAppId);
ModelBasedProcessing processor = new ModelBasedProcessing(loader, dbEngine, serializer);
@@ -552,7 +531,7 @@ public class SearchGraph {
if (modelAndNamedQuerySearch == null) {
throw new AAIException("AAI_5105");
}
- HashMap<String, Object> namedQueryLookupHash = new HashMap<String, Object>();
+ Map<String, Object> namedQueryLookupHash = new HashMap<>();
DynamicEntity qp = modelAndNamedQuerySearch.get("queryParameters");
String namedQueryUuid = null;
@@ -590,12 +569,12 @@ public class SearchGraph {
List<Map<String, Object>> startNodeFilterHash = new ArrayList<>();
- mapInstanceFilters((DynamicEntity) modelAndNamedQuerySearch.get("instanceFilters"), startNodeFilterHash,
+ mapInstanceFilters(modelAndNamedQuerySearch.get("instanceFilters"), startNodeFilterHash,
jaxbContext);
Map<String, Object> secondaryFilterHash = new HashMap<>();
- mapSecondaryFilters((DynamicEntity) modelAndNamedQuerySearch.get("secondaryFilts"), secondaryFilterHash,
+ mapSecondaryFilters(modelAndNamedQuerySearch.get("secondaryFilts"), secondaryFilterHash,
jaxbContext);
List<ResultSet> resultSet = processor.queryByNamedQuery(transId, fromAppId, namedQueryUuid,
@@ -641,8 +620,8 @@ public class SearchGraph {
* @throws UnsupportedEncodingException the unsupported encoding exception
*/
public Response executeModelOperation(String fromAppId, String transId, String queryParameters,
- DBConnectionType connectionType, boolean isDelete, AAIExtensionMap aaiExtMap)
- throws JAXBException, AAIException, DynamicException, UnsupportedEncodingException {
+ boolean isDelete, AAIExtensionMap aaiExtMap)
+ throws AAIException, DynamicException {
Response response;
boolean success = true;
TransactionalGraphEngine dbEngine = null;
@@ -651,7 +630,7 @@ public class SearchGraph {
MoxyLoader loader = (MoxyLoader) loaderFactory.createLoaderForVersion(ModelType.MOXY,
schemaVersions.getDefaultVersion());
DynamicJAXBContext jaxbContext = loader.getJAXBContext();
- dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, connectionType, loader);
+ dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, loader);
DBSerializer serializer =
new DBSerializer(schemaVersions.getDefaultVersion(), dbEngine, ModelType.MOXY, fromAppId);
ModelBasedProcessing processor = new ModelBasedProcessing(loader, dbEngine, serializer);
@@ -674,12 +653,10 @@ public class SearchGraph {
throw new AAIException("AAI_5105");
}
- Map<String, Object> modelQueryLookupHash = new HashMap<>();
-
String modelVersionId = null;
String modelName = null;
String modelInvariantId = null;
- String modelVersion = null;
+ String modelVersion;
String topNodeType = null;
if (modelAndNamedQuerySearch.isSet("topNodeType")) {
@@ -698,7 +675,7 @@ public class SearchGraph {
DynamicEntity qp = modelAndNamedQuerySearch.get("queryParameters");
if (qp.isSet("model")) {
- DynamicEntity model = (DynamicEntity) qp.get("model");
+ DynamicEntity model = qp.get("model");
// on an old-style model object, the following 4 attrs were all present
if (model.isSet("modelNameVersionId")) {
@@ -723,7 +700,7 @@ public class SearchGraph {
if (model.isSet("modelVers")) {
// we know that this is new style, because modelVers was not an option
// before v9
- DynamicEntity modelVers = (DynamicEntity) model.get("modelVers");
+ DynamicEntity modelVers = model.get("modelVers");
if (modelVers.isSet("modelVer")) {
List<DynamicEntity> modelVerList = modelVers.get("modelVer");
// if they send more than one, too bad, they get the first one
@@ -752,8 +729,7 @@ public class SearchGraph {
List<ResultSet> resultSet = processor.queryByModel(transId, fromAppId, modelVersionId, modelInvariantId,
modelName, topNodeType, startNodeFilterHash, aaiExtMap.getApiVersion());
- Map<Object, String> objectToVertMap = new HashMap<>();
- List<Object> invItemList = unpackResultSet(resultSet, dbEngine, loader, serializer);
+ unpackResultSet(resultSet, dbEngine, loader, serializer);
ResultSet rs = resultSet.get(0);
diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java
index 146f847..ccf89fc 100644
--- a/aai-traversal/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java
+++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/AAIResponseFilterPriority.java
@@ -22,7 +22,7 @@ package org.onap.aai.interceptors.post;
/**
* Response Filter order is done reverse sorted
* so in the following case the first response filter would be
- * HEADER_MANIPULATION, RESPONSE_TRANS_LOGGING, RESET_LOGGING_CONTEXT,
+ * HEADER_MANIPULATION, RESPONSE_TRANS_LOGGING,
* and INVALID_RESPONSE_STATUS
*/
public final class AAIResponseFilterPriority {
@@ -31,8 +31,6 @@ public final class AAIResponseFilterPriority {
public static final int INVALID_RESPONSE_STATUS = 1000;
- public static final int RESET_LOGGING_CONTEXT = 2000;
-
public static final int RESPONSE_TRANS_LOGGING = 3000;
public static final int HEADER_MANIPULATION = 4000;
diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResetLoggingContext.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResetLoggingContext.java
deleted file mode 100644
index baf28ad..0000000
--- a/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResetLoggingContext.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/**
- * ============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.interceptors.post;
-
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-import org.onap.aai.interceptors.AAIContainerFilter;
-import org.onap.aai.logging.LoggingContext;
-import org.onap.aai.logging.LoggingContext.StatusCode;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import javax.annotation.Priority;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerResponseContext;
-import javax.ws.rs.container.ContainerResponseFilter;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.Response.StatusType;
-import java.io.IOException;
-
-@Priority(AAIResponseFilterPriority.RESET_LOGGING_CONTEXT)
-public class ResetLoggingContext extends AAIContainerFilter implements ContainerResponseFilter {
-
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(ResetLoggingContext.class);
-
- @Autowired
- private HttpServletRequest httpServletRequest;
-
- @Override
- public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext)
- throws IOException {
-
- this.cleanLoggingContext(responseContext);
-
- }
-
- private void cleanLoggingContext(ContainerResponseContext responseContext) {
- //String url = httpServletRequest.getRequestURL().toString();
- boolean success = true;
- String uri = httpServletRequest.getRequestURI();
- String queryString = httpServletRequest.getQueryString();
-
- if(queryString != null && !queryString.isEmpty()){
- uri = uri + "?" + queryString;
- }
- // For now, we use the the HTTP status code,
- // This may change, once the requirements for response codes are defined
-
- int httpStatusCode = responseContext.getStatus();
- if ( httpStatusCode < 100 || httpStatusCode > 599 ) {
- httpStatusCode = Status.INTERNAL_SERVER_ERROR.getStatusCode();
- }
- LoggingContext.responseCode(Integer.toString(httpStatusCode));
-
- StatusType sType = responseContext.getStatusInfo();
- if ( sType != null ) {
- Status.Family sFamily = sType.getFamily();
- if ( ! ( Status.Family.SUCCESSFUL.equals(sFamily) ||
- ( Status.NOT_FOUND.equals(Status.fromStatusCode(httpStatusCode)) ) ) ) {
- success = false;
- }
- }
- else {
- if ( (httpStatusCode < 200 || httpStatusCode > 299) && ( ! ( Status.NOT_FOUND.equals(Status.fromStatusCode(httpStatusCode) ) ) ) ) {
- success = false;
- }
- }
- if (success) {
- LoggingContext.statusCode(StatusCode.COMPLETE);
- LOGGER.info(uri + " call succeeded");
- }
- else {
- LoggingContext.statusCode(StatusCode.ERROR);
- LOGGER.error(uri + " call failed with responseCode=" + httpStatusCode);
- }
- LoggingContext.clear();
-
-
- }
-
-}
diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseTransactionLogging.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseTransactionLogging.java
index 547a7c8..51fe871 100644
--- a/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseTransactionLogging.java
+++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseTransactionLogging.java
@@ -19,14 +19,14 @@
*/
package org.onap.aai.interceptors.post;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
import com.google.gson.JsonObject;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.interceptors.AAIContainerFilter;
import org.onap.aai.interceptors.AAIHeaderProperties;
import org.onap.aai.logging.ErrorLogHelper;
import org.onap.aai.util.AAIConfig;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import javax.annotation.Priority;
@@ -34,14 +34,21 @@ import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
+import javax.ws.rs.core.PathSegment;
import java.io.IOException;
-import java.util.Objects;
-import java.util.Optional;
+import java.util.*;
@Priority(AAIResponseFilterPriority.RESPONSE_TRANS_LOGGING)
public class ResponseTransactionLogging extends AAIContainerFilter implements ContainerResponseFilter {
- private static final EELFLogger TRANSACTION_LOGGER = EELFManager.getInstance().getLogger(ResponseTransactionLogging.class);
+ private static final Logger TRANSACTION_LOGGER = LoggerFactory.getLogger(ResponseTransactionLogging.class);
+
+ private final static String QUERY_API_PATH_SEGMENT = "query";
+ private final static String NODES_QUERY_API_PATH_SEGMENT = "nodes-query";
+ private final static String GENERIC_QUERY_API_PATH_SEGMENT = "generic-query";
+ private final static String DSL_API_PATH_SEGMENT = "dsl";
+ private final static String RECENTS_API_PATH_SEGMENT = "recents";
+ private final static Set<String> READ_ONLY_QUERIES = getReadOnlyQueries();
@Autowired
private HttpServletResponse httpServletResponse;
@@ -57,12 +64,13 @@ public class ResponseTransactionLogging extends AAIContainerFilter implements Co
private void transLogging(ContainerRequestContext requestContext, ContainerResponseContext responseContext) {
String logValue;
- String getValue;
+ String isGetTransactionResponseLoggingEnabled;
String postValue;
-
+
try {
+
logValue = AAIConfig.get("aai.transaction.logging");
- getValue = AAIConfig.get("aai.transaction.logging.get");
+ isGetTransactionResponseLoggingEnabled = AAIConfig.get("aai.transaction.logging.get");
postValue = AAIConfig.get("aai.transaction.logging.post");
} catch (AAIException e) {
return;
@@ -81,7 +89,6 @@ public class ResponseTransactionLogging extends AAIContainerFilter implements Co
String response = this.getResponseString(responseContext);
if (!Boolean.parseBoolean(logValue)) {
- } else if (!Boolean.parseBoolean(getValue) && "GET".equals(httpMethod)) {
} else if (!Boolean.parseBoolean(postValue) && "POST".equals(httpMethod)) {
} else {
@@ -94,12 +101,33 @@ public class ResponseTransactionLogging extends AAIContainerFilter implements Co
logEntry.addProperty("resourceId", fullUri);
logEntry.addProperty("resourceType", httpMethod);
logEntry.addProperty("rqstBuf", Objects.toString(request, ""));
- logEntry.addProperty("respBuf", Objects.toString(response, ""));
-
- try {
- TRANSACTION_LOGGER.debug(logEntry.toString());
- } catch (Exception e) {
- ErrorLogHelper.logError("AAI_4000", "Exception writing transaction log.");
+
+ boolean recordResponse = true;
+ if (!Boolean.parseBoolean(isGetTransactionResponseLoggingEnabled) && "GET".equals(httpMethod)) {
+ recordResponse = false;
+ }
+ else {
+ /**
+ * Parse the uri path and see if it is a read-only query
+ * If it is, do not record the response in the logs
+ */
+
+ List<PathSegment> pathSegmentList = requestContext.getUriInfo().getPathSegments();
+ for (PathSegment queryType : pathSegmentList) {
+ if (READ_ONLY_QUERIES.contains(queryType.toString())) {
+ recordResponse = false;
+ }
+ }
+
+ if (recordResponse) {
+ logEntry.addProperty("respBuf", Objects.toString(response, ""));
+ }
+
+ try {
+ TRANSACTION_LOGGER.debug(logEntry.toString());
+ } catch (Exception e) {
+ ErrorLogHelper.logError("AAI_4000", "Exception writing transaction log.");
+ }
}
}
@@ -120,4 +148,14 @@ public class ResponseTransactionLogging extends AAIContainerFilter implements Co
return response.toString();
}
+ private static Set<String> getReadOnlyQueries() {
+ Set<String> readOnlyQueries = new HashSet<String>();
+ readOnlyQueries.add(NODES_QUERY_API_PATH_SEGMENT);
+ readOnlyQueries.add(GENERIC_QUERY_API_PATH_SEGMENT);
+ readOnlyQueries.add(RECENTS_API_PATH_SEGMENT);
+ readOnlyQueries.add(QUERY_API_PATH_SEGMENT);
+ readOnlyQueries.add(DSL_API_PATH_SEGMENT);
+ return readOnlyQueries;
+ }
+
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java
index c3d9d3b..4af96c5 100644
--- a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java
+++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/AAIRequestFilterPriority.java
@@ -27,8 +27,6 @@ public final class AAIRequestFilterPriority {
public static final int HEADER_VALIDATION = 2000;
- public static final int SET_LOGGING_CONTEXT = 3000;
-
public static final int HTTP_HEADER = 4000;
public static final int LATEST = 4250;
diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/HeaderValidation.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/HeaderValidation.java
index d6b6080..d70cb01 100644
--- a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/HeaderValidation.java
+++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/HeaderValidation.java
@@ -23,6 +23,8 @@ import org.onap.aai.exceptions.AAIException;
import org.onap.aai.interceptors.AAIContainerFilter;
import org.onap.aai.interceptors.AAIHeaderProperties;
import org.onap.aai.logging.ErrorLogHelper;
+import org.onap.logging.filter.base.Constants;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
import javax.annotation.Priority;
import javax.ws.rs.container.ContainerRequestContext;
@@ -34,7 +36,6 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
-import java.util.UUID;
@PreMatching
@Priority(AAIRequestFilterPriority.HEADER_VALIDATION)
@@ -44,36 +45,28 @@ public class HeaderValidation extends AAIContainerFilter implements ContainerReq
public void filter(ContainerRequestContext requestContext) throws IOException {
Optional<Response> oResp;
-
- String transId = requestContext.getHeaderString(AAIHeaderProperties.TRANSACTION_ID);
- String fromAppId = requestContext.getHeaderString(AAIHeaderProperties.FROM_APP_ID);
List<MediaType> acceptHeaderValues = requestContext.getAcceptableMediaTypes();
+ String fromAppId = getPartnerName(requestContext);
oResp = this.validateHeaderValuePresence(fromAppId, "AAI_4009", acceptHeaderValues);
if (oResp.isPresent()) {
requestContext.abortWith(oResp.get());
return;
}
+ String transId = getRequestId(requestContext);
oResp = this.validateHeaderValuePresence(transId, "AAI_4010", acceptHeaderValues);
if (oResp.isPresent()) {
requestContext.abortWith(oResp.get());
return;
}
-
- if (!this.isValidUUID(transId)) {
- transId = UUID.randomUUID().toString();
- requestContext.getHeaders().get(AAIHeaderProperties.TRANSACTION_ID).clear();
- requestContext.getHeaders().add(AAIHeaderProperties.TRANSACTION_ID, transId);
- }
-
}
private Optional<Response> validateHeaderValuePresence(String value, String errorCode,
List<MediaType> acceptHeaderValues) {
Response response = null;
AAIException aaie;
- if (value == null) {
+ if (value == null || value.isEmpty()) {
aaie = new AAIException(errorCode);
return Optional.of(Response.status(aaie.getErrorObject().getHTTPResponseCode())
.entity(ErrorLogHelper.getRESTAPIErrorResponse(acceptHeaderValues, aaie, new ArrayList<>()))
@@ -82,5 +75,52 @@ public class HeaderValidation extends AAIContainerFilter implements ContainerReq
return Optional.ofNullable(response);
}
+ public String getRequestId(ContainerRequestContext requestContext) {
+ String requestId = requestContext.getHeaderString(ONAPLogConstants.Headers.REQUEST_ID);
+ if (requestId == null || requestId.isEmpty()) {
+ requestId = requestContext.getHeaderString(Constants.HttpHeaders.HEADER_REQUEST_ID);
+ if (requestId == null || requestId.isEmpty()) {
+ requestId = requestContext.getHeaderString(Constants.HttpHeaders.TRANSACTION_ID);
+ if (requestId == null || requestId.isEmpty()) {
+ requestId = requestContext.getHeaderString(Constants.HttpHeaders.ECOMP_REQUEST_ID);
+ if (requestId == null || requestId.isEmpty()) {
+ return requestId;
+ }
+ }
+ }
+ }
+ if (requestContext.getHeaders().get(ONAPLogConstants.Headers.REQUEST_ID) != null) {
+ requestContext.getHeaders().get(ONAPLogConstants.Headers.REQUEST_ID).clear();
+ }
+ if (requestContext.getHeaders().get(Constants.HttpHeaders.TRANSACTION_ID) != null) {
+ requestContext.getHeaders().get(Constants.HttpHeaders.TRANSACTION_ID).clear();
+ }
+ if (requestContext.getHeaders().get(Constants.HttpHeaders.HEADER_REQUEST_ID) != null) {
+ requestContext.getHeaders().get(Constants.HttpHeaders.HEADER_REQUEST_ID).clear();
+ }
+ if (requestContext.getHeaders().get(Constants.HttpHeaders.ECOMP_REQUEST_ID) != null) {
+ requestContext.getHeaders().get(Constants.HttpHeaders.ECOMP_REQUEST_ID).clear();
+ }
+ requestContext.getHeaders().add(Constants.HttpHeaders.TRANSACTION_ID, requestId);
+
+ return requestId;
+ }
+ public String getPartnerName(ContainerRequestContext requestContext) {
+ String partnerName = requestContext.getHeaderString(ONAPLogConstants.Headers.PARTNER_NAME);
+ if (partnerName == null || (partnerName.isEmpty())) {
+ partnerName = requestContext.getHeaderString(AAIHeaderProperties.FROM_APP_ID);
+ if (partnerName == null || (partnerName.isEmpty())) {
+ return partnerName;
+ }
+ }
+ if (requestContext.getHeaders().get(ONAPLogConstants.Headers.PARTNER_NAME) != null) {
+ requestContext.getHeaders().get(ONAPLogConstants.Headers.PARTNER_NAME).clear();
+ }
+ if (requestContext.getHeaders().get(AAIHeaderProperties.FROM_APP_ID) != null) {
+ requestContext.getHeaders().get(AAIHeaderProperties.FROM_APP_ID).clear();
+ }
+ requestContext.getHeaders().add(AAIHeaderProperties.FROM_APP_ID, partnerName);
+ return partnerName;
+ }
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java
index 6c86f19..03cac8d 100644
--- a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java
+++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java
@@ -37,6 +37,8 @@ import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriInfo;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
@@ -58,6 +60,8 @@ public class RequestTransactionLogging extends AAIContainerFilter implements Con
private static final String CONTENT_TYPE = "Content-Type";
private static final String ACCEPT = "Accept";
private static final String TEXT_PLAIN = "text/plain";
+ private static final String WILDCARD = "*/*";
+ private static final String APPLICATION_JSON = "application/json";
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
@@ -83,8 +87,18 @@ public class RequestTransactionLogging extends AAIContainerFilter implements Con
requestContext.getHeaders().putSingle(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
}
- if(StringUtils.isEmpty(acceptType) || acceptType.contains(TEXT_PLAIN)){
- requestContext.getHeaders().putSingle(ACCEPT, DEFAULT_RESPONSE_TYPE);
+ if(WILDCARD.equals(acceptType) || StringUtils.isEmpty(acceptType) || acceptType.contains(TEXT_PLAIN)){
+ UriInfo uriInfo = requestContext.getUriInfo();
+ if(uriInfo != null){
+ String path = uriInfo.getPath();
+ if(path.endsWith("/dsl") || path.endsWith("/query") || path.contains("/recents/")){
+ requestContext.getHeaders().putSingle(ACCEPT, APPLICATION_JSON);
+ } else {
+ requestContext.getHeaders().putSingle(ACCEPT, DEFAULT_RESPONSE_TYPE);
+ }
+ } else {
+ requestContext.getHeaders().putSingle(ACCEPT, DEFAULT_RESPONSE_TYPE);
+ }
}
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/SetLoggingContext.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/SetLoggingContext.java
deleted file mode 100644
index 4b0f18a..0000000
--- a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/SetLoggingContext.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * ============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.interceptors.pre;
-
-import org.onap.aai.interceptors.AAIContainerFilter;
-import org.onap.aai.interceptors.AAIHeaderProperties;
-import org.onap.aai.logging.LoggingContext;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.core.env.Environment;
-
-import javax.annotation.Priority;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.container.ContainerRequestContext;
-import javax.ws.rs.container.ContainerRequestFilter;
-import javax.ws.rs.container.PreMatching;
-import java.io.IOException;
-
-@PreMatching
-@Priority(AAIRequestFilterPriority.SET_LOGGING_CONTEXT)
-public class SetLoggingContext extends AAIContainerFilter implements ContainerRequestFilter {
-
- @Autowired
- private Environment environment;
-
- @Autowired
- private HttpServletRequest httpServletRequest;
-
- @Override
- public void filter(ContainerRequestContext requestContext) throws IOException {
-
- String uri = httpServletRequest.getRequestURI();
- String queryString = httpServletRequest.getQueryString();
-
- if(queryString != null && !queryString.isEmpty()){
- uri = uri + "?" + queryString;
- }
-
- String httpMethod = requestContext.getMethod();
- String transId = requestContext.getHeaderString(AAIHeaderProperties.TRANSACTION_ID);
- String fromAppId = requestContext.getHeaderString(AAIHeaderProperties.FROM_APP_ID);
-
- LoggingContext.init();
- LoggingContext.requestId(transId);
- LoggingContext.partnerName(fromAppId);
- LoggingContext.targetEntity(environment.getProperty("spring.application.name"));
- LoggingContext.component(fromAppId);
- LoggingContext.serviceName(httpMethod + " " + uri);
- LoggingContext.targetServiceName(httpMethod + " " + uri);
- LoggingContext.statusCode(LoggingContext.StatusCode.COMPLETE);
- }
-
-}
diff --git a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java
index bc03082..58c7be6 100644
--- a/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java
+++ b/aai-traversal/src/main/java/org/onap/aai/interceptors/pre/TwoWaySslAuthorization.java
@@ -19,7 +19,7 @@
*/
package org.onap.aai.interceptors.pre;
-import org.onap.aai.auth.AAIAuthCore;
+import org.onap.aai.aaf.auth.AAIAuthCore;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.interceptors.AAIContainerFilter;
import org.onap.aai.interceptors.AAIHeaderProperties;
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/CQ2Gremlin.java b/aai-traversal/src/main/java/org/onap/aai/rest/CQ2Gremlin.java
index dcf8418..d075f70 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/CQ2Gremlin.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/CQ2Gremlin.java
@@ -19,23 +19,7 @@
*/
package org.onap.aai.rest;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-
import org.onap.aai.config.SpringContextAware;
-import org.onap.aai.dbmap.DBConnectionType;
-import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.LoaderFactory;
import org.onap.aai.rest.db.HttpEntry;
import org.onap.aai.rest.search.CustomQueryConfigDTO;
@@ -50,6 +34,15 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestBody;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.*;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
@Path("/cq2gremlin")
public class CQ2Gremlin extends RESTAPI {
@@ -86,8 +79,6 @@ public class CQ2Gremlin extends RESTAPI {
protected Response processGremlinQuery(CustomQueryConfigDTO content, UriInfo info,
HttpHeaders headers) {
try{
- String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
- String realTime = headers.getRequestHeaders().getFirst("Real-Time");
LinkedHashMap <String, Object> params;
CustomQueryDTO queryDTO = content.getQueryDTO();
String query = queryDTO.getQuery();
@@ -108,8 +99,7 @@ public class CQ2Gremlin extends RESTAPI {
}
SchemaVersions schemaVersions = SpringContextAware.getBean(SchemaVersions.class);
- DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime);
- traversalUriHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion(), type);
+ traversalUriHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion());
traversalUriHttpEntry.setPaginationParameters("-1", "-1");
TransactionalGraphEngine dbEngine = traversalUriHttpEntry.getDbEngine();
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/CQ2GremlinTest.java b/aai-traversal/src/main/java/org/onap/aai/rest/CQ2GremlinTest.java
index 40538be..e3cfaca 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/CQ2GremlinTest.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/CQ2GremlinTest.java
@@ -20,26 +20,8 @@
package org.onap.aai.rest;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.stream.Collectors;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.UriInfo;
-
+import com.beust.jcommander.internal.Lists;
+import com.beust.jcommander.internal.Maps;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Graph;
@@ -47,7 +29,6 @@ import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
import org.onap.aai.config.SpringContextAware;
-import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Loader;
import org.onap.aai.introspection.LoaderFactory;
@@ -61,21 +42,27 @@ import org.onap.aai.serialization.db.EdgeSerializer;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.setup.SchemaVersions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestBody;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-import com.beust.jcommander.internal.Lists;
-import com.beust.jcommander.internal.Maps;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.*;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
@Path("/cq2gremlintest")
public class CQ2GremlinTest extends RESTAPI {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(CQ2GremlinTest.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(CQ2GremlinTest.class);
private HttpEntry traversalUriHttpEntry;
@@ -110,8 +97,7 @@ public class CQ2GremlinTest extends RESTAPI {
String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
String realTime = headers.getRequestHeaders().getFirst("Real-Time");
SchemaVersions schemaVersions = SpringContextAware.getBean(SchemaVersions.class);
- DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime);
- traversalUriHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion(), type);
+ traversalUriHttpEntry.setHttpEntryProperties(schemaVersions.getDefaultVersion());
traversalUriHttpEntry.setPaginationParameters("-1", "-1");
return processC2UnitTest(content);
}
@@ -123,12 +109,12 @@ public class CQ2GremlinTest extends RESTAPI {
gts = graph.traversal();
List<Vertex> expectedVertices = createGraph(content, graph);
GremlinGroovyShell shell = new GremlinGroovyShell();
- loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, new SchemaVersion("v16"));
+ loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, new SchemaVersion("v19"));
LinkedHashMap <String, Object> params = new LinkedHashMap<>();
//Adding parameters
- content.getQueryRequiredProperties().forEach((K, V) -> {params.put(K, V);});
- content.getQueryOptionalProperties().forEach((K, V) -> {params.put(K, V);});
+ content.getQueryRequiredProperties().forEach(params::put);
+ content.getQueryOptionalProperties().forEach(params::put);
String query = new GroovyQueryBuilder().executeTraversal(dbEngine, content.getStoredQuery(), params);
query = "g" + query;
@@ -166,17 +152,17 @@ public class CQ2GremlinTest extends RESTAPI {
private List<Vertex> createGraph(CustomQueryTestDTO content, Graph graph) {
Map<String, Vertex> verticesMap = Maps.newLinkedHashMap();
//Creating all the Vertices
- content.getVerticesDtos().stream().forEach(vertex -> {
+ content.getVerticesDtos().forEach(vertex -> {
StringBuilder vertexIdentifier = new StringBuilder();
List<String> keyValues = Lists.newArrayList();
keyValues.add(T.id.toString());
keyValues.add(String.format("%02d", verticesMap.size() * 10));
AtomicInteger index = new AtomicInteger(0);
- vertex.forEach((K, V) -> {
+ vertex.forEach((k, v) -> {
if(index.get() == 1)
- vertexIdentifier.append(V);
- keyValues.add(K);
- keyValues.add(V);
+ vertexIdentifier.append(k);
+ keyValues.add(k);
+ keyValues.add(v);
index.incrementAndGet();
});
Vertex graphVertex = graph.addVertex(keyValues.toArray());
@@ -186,7 +172,7 @@ public class CQ2GremlinTest extends RESTAPI {
GraphTraversalSource g = graph.traversal();
//Creating all the Edges
- content.getEdgesDtos().stream().forEach(edge -> {
+ content.getEdgesDtos().forEach(edge -> {
String fromId = edge.get("from-id");
String toId = edge.get("to-id");
boolean treeEdgeIdentifier = !"NONE".equalsIgnoreCase(edge.get("contains-other-v"));
@@ -207,9 +193,7 @@ public class CQ2GremlinTest extends RESTAPI {
List<Vertex> expectedVertices = Lists.newArrayList();
- content.getExpectedResultsDtos().getIds().stream().forEach(vertexId -> {
- expectedVertices.add(verticesMap.get(vertexId));
- });
+ content.getExpectedResultsDtos().getIds().forEach(vertexId -> expectedVertices.add(verticesMap.get(vertexId)));
return expectedVertices;
}
@@ -218,8 +202,8 @@ public class CQ2GremlinTest extends RESTAPI {
if(!startNodeVertex.isPresent()){
throw new IllegalArgumentException("start-node was not specified");
}
- startNodeVertex.get().forEach((K, V) -> {
- g.has(K, V);
+ startNodeVertex.get().forEach((k, v) -> {
+ g.has(k, v);
});
}
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 2d09636..6cb6565 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
@@ -19,24 +19,20 @@
*/
package org.onap.aai.rest;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.onap.aai.concurrent.AaiCallable;
-import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.ModelType;
-import org.onap.aai.logging.LoggingContext;
-import org.onap.aai.logging.StopWatch;
import org.onap.aai.rest.db.HttpEntry;
import org.onap.aai.rest.dsl.DslQueryProcessor;
+import org.onap.aai.rest.enums.QueryVersion;
import org.onap.aai.rest.search.GenericQueryProcessor;
import org.onap.aai.rest.search.GremlinServerSingleton;
import org.onap.aai.rest.search.QueryProcessorType;
import org.onap.aai.restcore.HttpMethod;
-import org.onap.aai.restcore.RESTAPI;
import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
import org.onap.aai.serialization.queryformats.Format;
@@ -45,27 +41,29 @@ 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.transforms.XmlFormatTransformer;
import org.onap.aai.util.AAIConfig;
import org.onap.aai.util.TraversalConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
-import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.*;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.Status;
import java.util.List;
-import java.util.concurrent.TimeUnit;
+import java.util.Map;
+import java.util.Optional;
@Path("{version: v[1-9][0-9]*|latest}/dsl")
-public class DslConsumer extends RESTAPI {
+public class DslConsumer extends TraversalConsumer {
private HttpEntry traversalUriHttpEntry;
private QueryProcessorType processorType = QueryProcessorType.LOCAL_GROOVY;
- private static final String TARGET_ENTITY = "DB";
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(DslConsumer.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(DslConsumer.class);
private DslQueryProcessor dslQueryProcessor;
@@ -74,53 +72,74 @@ public class DslConsumer extends RESTAPI {
private String basePath;
private GremlinServerSingleton gremlinServerSingleton;
+ private final QueryVersion DEFAULT_VERSION = QueryVersion.V1;
+ private QueryVersion dslApiVersion = DEFAULT_VERSION;
+
+ private XmlFormatTransformer xmlFormatTransformer;
@Autowired
public DslConsumer(HttpEntry traversalUriHttpEntry, DslQueryProcessor dslQueryProcessor,
- SchemaVersions schemaVersions, GremlinServerSingleton gremlinServerSingleton,
- @Value("${schema.uri.base.path}") String basePath) {
+ SchemaVersions schemaVersions, GremlinServerSingleton gremlinServerSingleton,
+ XmlFormatTransformer xmlFormatTransformer,
+ @Value("${schema.uri.base.path}") String basePath) {
this.traversalUriHttpEntry = traversalUriHttpEntry;
this.dslQueryProcessor = dslQueryProcessor;
this.schemaVersions = schemaVersions;
this.gremlinServerSingleton = gremlinServerSingleton;
+ this.xmlFormatTransformer = xmlFormatTransformer;
this.basePath = basePath;
}
@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, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize) {
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ public Response executeQuery(String content,
+ @PathParam("version") String versionParam,
+ @DefaultValue("graphson") @QueryParam("format") String queryFormat,
+ @DefaultValue("no_op") @QueryParam("subgraph") String subgraph,
+ @DefaultValue("all") @QueryParam("validate") String validate,
+ @Context HttpHeaders headers,
+ @Context UriInfo info,
+ @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>() {
+ TraversalConstants.AAI_TRAVERSAL_DSL_TIMEOUT_APP,
+ TraversalConstants.AAI_TRAVERSAL_DSL_TIMEOUT_LIMIT,
+ headers,
+ info,
+ HttpMethod.PUT,
+ new AaiCallable() {
@Override
- public Response process() {
- return processExecuteQuery(content, versionParam, uri, queryFormat, subgraph, headers, info,
- req, resultIndex, resultSize);
+ public Response process() throws Exception {
+ return (processExecuteQuery(content, versionParam, queryFormat, subgraph, validate, headers, info,
+ 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, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize) {
+ public Response processExecuteQuery(String content, String versionParam, String queryFormat, String subgraph,
+ String validate, HttpHeaders headers, UriInfo info, String resultIndex,
+ 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");
+
+ Optional<String> dslApiVersionHeader = Optional.ofNullable(headers.getRequestHeaders().getFirst("X-DslApiVersion"));
+ if (dslApiVersionHeader.isPresent()) {
+ try {
+ dslApiVersion = QueryVersion.valueOf(dslApiVersionHeader.get());
+ } catch (IllegalArgumentException e) {
+ LOGGER.debug("Defaulting DSL Api Version to "+DEFAULT_VERSION);
+ }
+ }
+
Response response;
SchemaVersion version = new SchemaVersion(versionParam);
TransactionalGraphEngine dbEngine = null;
try {
- LoggingContext.save();
- DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime);
- traversalUriHttpEntry.setHttpEntryProperties(version, type);
+ traversalUriHttpEntry.setHttpEntryProperties(version);
traversalUriHttpEntry.setPaginationParameters(resultIndex, resultSize);
dbEngine = traversalUriHttpEntry.getDbEngine();
JsonObject input = new JsonParser().parse(content).getAsJsonObject();
@@ -130,48 +149,83 @@ public class DslConsumer extends RESTAPI {
dsl = dslElement.getAsString();
}
- LoggingContext.targetEntity(TARGET_ENTITY);
- LoggingContext.targetServiceName(methodName);
- 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);
-
+ if(isDslOverride) {
+ dslQueryProcessor.setStartNodeValidationFlag(false);
+ }
+
+ dslQueryProcessor.setValidationRules(validate);
+
+ Format format = Format.getFormat(queryFormat);
+
+ if(isAggregate(format)){
+ dslQueryProcessor.setAggregate(true);
+ }
+
+ if(isHistory(format)){
+ validateHistoryParams(format, info.getQueryParameters());
+ }
+
+ GraphTraversalSource traversalSource = getTraversalSource(dbEngine, format, info);
+
GenericQueryProcessor processor = new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton)
- .queryFrom(dsl, "dsl").queryProcessor(dslQueryProcessor).processWith(processorType).create();
-
- String result = "";
+ .queryFrom(dsl, "dsl").queryProcessor(dslQueryProcessor).version(dslApiVersion).processWith(processorType)
+ .format(format).uriParams(info.getQueryParameters()).traversalSource(isHistory(format), traversalSource).create();
+
SubGraphStyle subGraphStyle = SubGraphStyle.valueOf(subgraph);
List<Object> vertTemp = processor.execute(subGraphStyle);
- List<Object> vertices = traversalUriHttpEntry.getPaginatedVertexList(vertTemp);
+
+ List <Object> vertices;
+ if (isAggregate(format)){
+ vertices = traversalUriHttpEntry.getPaginatedVertexListForAggregateFormat(vertTemp);
+ } else {
+ 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");
-
+ MultivaluedMap<String, String> mvm = new MultivaluedHashMap<>();
+ mvm.putAll(info.getQueryParameters());
+ if (isHistory(format)) {
+ mvm.putSingle("startTs", Long.toString(getStartTime(format, mvm)));
+ mvm.putSingle("endTs", Long.toString(getEndTime(mvm)));
+ }
+ Formatter formatter = ff.get(format, mvm);
+
+ final Map<String, List<String>> propertiesMap = processor.getPropertiesMap();
+ String result = "";
+ if (propertiesMap != null && !propertiesMap.isEmpty()){
+ result = formatter.output(vertices, propertiesMap).toString();
+ }
+ else {
+ result = formatter.output(vertices).toString();
+ }
+
+ String acceptType = headers.getHeaderString("Accept");
+
+ if(acceptType == null){
+ acceptType = MediaType.APPLICATION_JSON;
+ }
+
+ if(MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(acceptType))){
+ result = xmlFormatTransformer.transform(result);
+ }
+
if(traversalUriHttpEntry.isPaginated()){
response = Response.status(Status.OK)
- .type(MediaType.APPLICATION_JSON)
+ .type(acceptType)
.header("total-results", traversalUriHttpEntry.getTotalVertices())
.header("total-pages", traversalUriHttpEntry.getTotalPaginationBuckets())
.entity(result)
.build();
}else {
response = Response.status(Status.OK)
- .type(MediaType.APPLICATION_JSON)
+ .type(acceptType)
.entity(result).build();
}
@@ -181,8 +235,6 @@ public class DslConsumer extends RESTAPI {
AAIException ex = new AAIException("AAI_4000", e);
response = consumerExceptionResponseGenerator(headers, info, HttpMethod.PUT, ex);
} finally {
- LoggingContext.restoreIfPossible();
- LoggingContext.successStatusFields();
if (dbEngine != null) {
dbEngine.rollback();
}
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 633bc9c..d91e50d 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
@@ -19,38 +19,16 @@
*/
package org.onap.aai.rest;
-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;
-import javax.ws.rs.DefaultValue;
-import javax.ws.rs.Encoded;
-import javax.ws.rs.PUT;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriInfo;
-
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.onap.aai.concurrent.AaiCallable;
-import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.ModelType;
import org.onap.aai.logging.ErrorLogHelper;
+
import org.onap.aai.parsers.query.QueryParser;
import org.onap.aai.rest.db.HttpEntry;
import org.onap.aai.rest.search.CustomQueryConfig;
@@ -58,7 +36,6 @@ import org.onap.aai.rest.search.GenericQueryProcessor;
import org.onap.aai.rest.search.GremlinServerSingleton;
import org.onap.aai.rest.search.QueryProcessorType;
import org.onap.aai.restcore.HttpMethod;
-import org.onap.aai.restcore.RESTAPI;
import org.onap.aai.restcore.util.URITools;
import org.onap.aai.serialization.db.DBSerializer;
import org.onap.aai.serialization.engines.QueryStyle;
@@ -67,33 +44,28 @@ import org.onap.aai.serialization.queryformats.Format;
import org.onap.aai.serialization.queryformats.FormatFactory;
import org.onap.aai.serialization.queryformats.Formatter;
import org.onap.aai.serialization.queryformats.SubGraphStyle;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-import org.onap.aai.logging.LoggingContext;
-import org.onap.aai.logging.StopWatch;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
-import com.google.gson.JsonParser;
import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.setup.SchemaVersions;
-import org.onap.aai.util.AAIConstants;
+import org.onap.aai.transforms.XmlFormatTransformer;
import org.onap.aai.util.TraversalConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import javax.ws.rs.core.Response.Status;
+import java.net.URI;
+import java.util.*;
+import java.util.stream.Collectors;
+
@Path("{version: v[1-9][0-9]*|latest}/query")
-public class QueryConsumer extends RESTAPI {
-
- /** The introspector factory type. */
- private ModelType introspectorFactoryType = ModelType.MOXY;
-
+public class QueryConsumer extends TraversalConsumer {
+
private QueryProcessorType processorType = QueryProcessorType.LOCAL_GROOVY;
- /** The query style. */
- private QueryStyle queryStyle = QueryStyle.TRAVERSAL;
-
- private static final String TARGET_ENTITY = "DB";
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(QueryConsumer.class);
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(QueryConsumer.class);
private HttpEntry traversalUriHttpEntry;
@@ -104,23 +76,29 @@ public class QueryConsumer extends RESTAPI {
private GremlinServerSingleton gremlinServerSingleton;
+ private XmlFormatTransformer xmlFormatTransformer;
+
@Autowired
- public QueryConsumer(
- HttpEntry traversalUriHttpEntry,
- SchemaVersions schemaVersions,
- GremlinServerSingleton gremlinServerSingleton,
- @Value("${schema.uri.base.path}") String basePath
- ){
+ public QueryConsumer(HttpEntry traversalUriHttpEntry, SchemaVersions schemaVersions,
+ GremlinServerSingleton gremlinServerSingleton, XmlFormatTransformer xmlFormatTransformer, @Value("${schema.uri.base.path}") String basePath) {
this.traversalUriHttpEntry = traversalUriHttpEntry;
this.schemaVersions = schemaVersions;
this.gremlinServerSingleton = gremlinServerSingleton;
this.basePath = basePath;
+ this.xmlFormatTransformer = xmlFormatTransformer;
}
@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, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize){
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
+ public Response executeQuery(String content,
+ @PathParam("version") String versionParam,
+ @DefaultValue("graphson") @QueryParam("format") String queryFormat,
+ @DefaultValue("no_op") @QueryParam("subgraph") String subgraph,
+ @Context HttpHeaders headers,
+ @Context UriInfo info,
+ @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,34 +106,33 @@ public class QueryConsumer extends RESTAPI {
info,
HttpMethod.GET,
new AaiCallable<Response>() {
- @Override
- public Response process() {
- return processExecuteQuery(content, versionParam, uri, queryFormat, subgraph, headers, info, req, resultIndex, resultSize);
- }
- }
- );
+ @Override
+ public Response process() {
+ return processExecuteQuery(content, versionParam, queryFormat, subgraph, headers, info, 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, @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, @DefaultValue("-1") @QueryParam("resultSize") String resultSize) {
- String methodName = "executeQuery";
+ public Response processExecuteQuery(String content, String versionParam, String queryFormat, String subgraph,
+ HttpHeaders headers, UriInfo info, String resultIndex,
+ String resultSize) {
+
String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
- String realTime = headers.getRequestHeaders().getFirst("Real-Time");
String queryProcessor = headers.getRequestHeaders().getFirst("QueryProcessor");
QueryProcessorType processorType = this.processorType;
- Response response = null;
+ Response response;
TransactionalGraphEngine dbEngine = null;
+
try {
- LoggingContext.save();
this.checkQueryParams(info.getQueryParameters());
Format format = Format.getFormat(queryFormat);
if (queryProcessor != null) {
processorType = QueryProcessorType.valueOf(queryProcessor);
}
SubGraphStyle subGraphStyle = SubGraphStyle.valueOf(subgraph);
+
JsonParser parser = new JsonParser();
-
JsonObject input = parser.parse(content).getAsJsonObject();
-
JsonElement startElement = input.get("start");
JsonElement queryElement = input.get("query");
JsonElement gremlinElement = input.get("gremlin");
@@ -164,8 +141,7 @@ public class QueryConsumer extends RESTAPI {
String gremlin = "";
SchemaVersion version = new SchemaVersion(versionParam);
- DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime);
- traversalUriHttpEntry.setHttpEntryProperties(version, type);
+ traversalUriHttpEntry.setHttpEntryProperties(version);
/*
* Changes for Pagination
*/
@@ -196,76 +172,87 @@ public class QueryConsumer extends RESTAPI {
List<String> missingRequiredQueryParameters = checkForMissingQueryParameters( customQueryConfig.getQueryRequiredProperties(), URITools.getQueryMap(queryURIObj));
if ( !missingRequiredQueryParameters.isEmpty() ) {
- return( createMessageMissingQueryRequiredParameters( missingRequiredQueryParameters, headers, info, req));
+ return( createMessageMissingQueryRequiredParameters( missingRequiredQueryParameters, headers));
}
List<String> invalidQueryParameters = checkForInvalidQueryParameters( customQueryConfig, URITools.getQueryMap(queryURIObj));
if ( !invalidQueryParameters.isEmpty() ) {
- return( createMessageInvalidQueryParameters( invalidQueryParameters, headers, info, req));
+ return( createMessageInvalidQueryParameters( invalidQueryParameters, headers));
}
} else if ( queryElement != null ) {
- return( createMessageInvalidQuerySection( queryURI, headers, info, req));
+ return (createMessageInvalidQuerySection(queryURI, headers));
}
-
- GenericQueryProcessor processor = null;
-
- LoggingContext.targetEntity(TARGET_ENTITY);
- LoggingContext.targetServiceName(methodName);
- LoggingContext.startTime();
- StopWatch.conditionalStart();
+ GenericQueryProcessor processor;
+
+ if(isHistory(format)){
+ validateHistoryParams(format, info.getQueryParameters());
+ }
+ GraphTraversalSource traversalSource = getTraversalSource(dbEngine, format, info);
+ QueryStyle queryStyle = getQueryStyle(format, traversalUriHttpEntry);
if (!startURIs.isEmpty()) {
Set<Vertex> vertexSet = new LinkedHashSet<>();
QueryParser uriQuery;
List<Vertex> vertices;
for (URI startUri : startURIs) {
- uriQuery = dbEngine.getQueryBuilder().createQueryFromURI(startUri, URITools.getQueryMap(startUri));
+ uriQuery = dbEngine.getQueryBuilder(queryStyle, traversalSource).createQueryFromURI(startUri, URITools.getQueryMap(startUri));
vertices = uriQuery.getQueryBuilder().toList();
vertexSet.addAll(vertices);
}
-
processor = new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton)
- .startFrom(vertexSet).queryFrom(queryURIObj)
- .processWith(processorType).create();
+ .startFrom(vertexSet).queryFrom(queryURIObj).format(format)
+ .processWith(processorType).traversalSource(isHistory(format), traversalSource).create();
} else if (!queryURI.equals("")){
processor = new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton)
.queryFrom(queryURIObj)
- .processWith(processorType).create();
+ .processWith(processorType).traversalSource(isHistory(format), traversalSource).create();
} else {
processor = new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton)
.queryFrom(gremlin, "gremlin")
- .processWith(processorType).create();
+ .processWith(processorType).traversalSource(isHistory(format), traversalSource).create();
}
- String result = "";
List<Object> vertTemp = processor.execute(subGraphStyle);
List<Object> vertices = traversalUriHttpEntry.getPaginatedVertexList(vertTemp);
-
- DBSerializer serializer = new DBSerializer(version, dbEngine, introspectorFactoryType, sourceOfTruth);
+
+ DBSerializer serializer = new DBSerializer(version, dbEngine, ModelType.MOXY, sourceOfTruth);
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");
-
+ MultivaluedMap<String, String> mvm = new MultivaluedHashMap<>();
+ mvm.putAll(info.getQueryParameters());
+ if (isHistory(format)) {
+ mvm.putSingle("startTs", Long.toString(getStartTime(format, mvm)));
+ mvm.putSingle("endTs", Long.toString(getEndTime(mvm)));
+ }
+ Formatter formatter = ff.get(format, mvm);
+
+ String result = formatter.output(vertices).toString();
+
+ //LOGGER.info ("Completed");
+
+ String acceptType = headers.getHeaderString("Accept");
+
+ if(acceptType == null){
+ acceptType = MediaType.APPLICATION_JSON;
+ }
+
+ if(MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(acceptType))){
+ result = xmlFormatTransformer.transform(result);
+ }
+
if(traversalUriHttpEntry.isPaginated()){
response = Response.status(Status.OK)
- .type(MediaType.APPLICATION_JSON)
+ .type(acceptType)
.header("total-results", traversalUriHttpEntry.getTotalVertices())
.header("total-pages", traversalUriHttpEntry.getTotalPaginationBuckets())
.entity(result)
.build();
}else {
response = Response.status(Status.OK)
- .type(MediaType.APPLICATION_JSON)
+ .type(acceptType)
.entity(result).build();
}
} catch (AAIException e) {
@@ -274,8 +261,6 @@ public class QueryConsumer extends RESTAPI {
AAIException ex = new AAIException("AAI_4000", e);
response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, ex);
} finally {
- LoggingContext.restoreIfPossible();
- LoggingContext.successStatusFields();
if (dbEngine != null) {
dbEngine.rollback();
}
@@ -289,7 +274,7 @@ public class QueryConsumer extends RESTAPI {
if (params.containsKey("depth") && params.getFirst("depth").matches("\\d+")) {
String depth = params.getFirst("depth");
- Integer i = Integer.parseInt(depth);
+ int i = Integer.parseInt(depth);
if (i > 1) {
throw new AAIException("AAI_3303");
}
@@ -310,8 +295,6 @@ public class QueryConsumer extends RESTAPI {
}
private CustomQueryConfig getCustomQueryConfig(URI uriObj ) {
-
- CustomQueryConfig customQueryConfig;
String path = uriObj.getPath();
String[] parts = path.split("/");
@@ -329,77 +312,61 @@ public class QueryConsumer extends RESTAPI {
}
- private Response createMessageMissingQueryRequiredParameters(List<String> missingRequiredQueryParams, HttpHeaders headers, UriInfo info, HttpServletRequest req) {
+ private Response createMessageMissingQueryRequiredParameters(List<String> missingRequiredQueryParams, HttpHeaders headers) {
AAIException e = new AAIException("AAI_3013");
ArrayList<String> templateVars = new ArrayList<>();
+ templateVars.add(missingRequiredQueryParams.toString());
- if (templateVars.isEmpty()) {
- templateVars.add(missingRequiredQueryParams.toString());
- }
-
- Response response = Response
+ return Response
.status(e.getErrorObject().getHTTPResponseCode())
.entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e,
templateVars)).build();
-
- return response;
- }
+ }
- private Response createMessageInvalidQuerySection(String invalidQuery, HttpHeaders headers, UriInfo info, HttpServletRequest req) {
+ private Response createMessageInvalidQuerySection(String invalidQuery, HttpHeaders headers) {
AAIException e = new AAIException("AAI_3014");
ArrayList<String> templateVars = new ArrayList<>();
+ templateVars.add(invalidQuery);
- if (templateVars.isEmpty()) {
- templateVars.add(invalidQuery);
- }
-
- Response response = Response
+ return Response
.status(e.getErrorObject().getHTTPResponseCode())
.entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e,
templateVars)).build();
-
- return response;
- }
+ }
- public List<String> checkForInvalidQueryParameters( CustomQueryConfig customQueryConfig, MultivaluedMap<String, String> queryParams) {
+ private List<String> checkForInvalidQueryParameters( CustomQueryConfig customQueryConfig, MultivaluedMap<String, String> queryParams) {
- List<String> allParameters = new ArrayList<String>();
+ List<String> allParameters = new ArrayList<>();
/*
* Add potential Required and Optional to allParameters
*/
Optional.ofNullable(customQueryConfig.getQueryOptionalProperties()).ifPresent(allParameters::addAll);
Optional.ofNullable(customQueryConfig.getQueryRequiredProperties()).ifPresent(allParameters::addAll);
- if(queryParams.isEmpty())
+ if(queryParams.isEmpty()) {
return new ArrayList<>();
- List<String> invalidParameters = queryParams.keySet().stream()
- .filter(param -> !allParameters.contains(param))
- .collect(Collectors.toList());
-
- return invalidParameters;
-
+ }
+ return queryParams.keySet().stream()
+ .filter(param -> !allParameters.contains(param))
+ .collect(Collectors.toList());
}
- private Response createMessageInvalidQueryParameters(List<String> invalidQueryParams, HttpHeaders headers, UriInfo info, HttpServletRequest req) {
+ private Response createMessageInvalidQueryParameters(List<String> invalidQueryParams, HttpHeaders headers) {
AAIException e = new AAIException("AAI_3022");
ArrayList<String> templateVars = new ArrayList<>();
+ templateVars.add(invalidQueryParams.toString());
- if (templateVars.isEmpty()) {
- templateVars.add(invalidQueryParams.toString());
- }
-
- Response response = Response
+ return Response
.status(e.getErrorObject().getHTTPResponseCode())
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e,
+ .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 3154087..2e43e5b 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
@@ -19,34 +19,12 @@
*/
package org.onap.aai.rest;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import javax.ws.rs.Consumes;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.MultivaluedMap;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriInfo;
-
import org.onap.aai.concurrent.AaiCallable;
-import org.onap.aai.dbmap.DBConnectionType;
-
import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.ModelType;
import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
-import org.onap.aai.setup.SchemaVersion;
-import org.onap.aai.setup.SchemaVersions;
+
import org.onap.aai.rest.db.HttpEntry;
-import org.onap.aai.rest.dsl.DslQueryProcessor;
import org.onap.aai.rest.search.GenericQueryProcessor;
import org.onap.aai.rest.search.GremlinServerSingleton;
import org.onap.aai.rest.search.QueryProcessorType;
@@ -58,16 +36,22 @@ import org.onap.aai.serialization.queryformats.Format;
import org.onap.aai.serialization.queryformats.FormatFactory;
import org.onap.aai.serialization.queryformats.Formatter;
import org.onap.aai.serialization.queryformats.SubGraphStyle;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-import org.onap.aai.logging.LoggingContext;
-import org.onap.aai.logging.StopWatch;
-
+import org.onap.aai.setup.SchemaVersion;
+import org.onap.aai.setup.SchemaVersions;
+import org.onap.aai.transforms.XmlFormatTransformer;
import org.onap.aai.util.AAIConstants;
import org.onap.aai.util.TraversalConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import javax.ws.rs.core.Response.Status;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
@Path("/recents/{version: v[1-9][0-9]*|latest}")
public class RecentAPIConsumer extends RESTAPI {
@@ -77,39 +61,38 @@ public class RecentAPIConsumer extends RESTAPI {
private QueryProcessorType processorType = QueryProcessorType.LOCAL_GROOVY;
/** The query style. */
- private static final String TARGET_ENTITY = "DB";
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(RecentAPIConsumer.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(RecentAPIConsumer.class);
private HttpEntry traversalUriHttpEntry;
- private DslQueryProcessor dslQueryProcessor;
-
private SchemaVersions schemaVersions;
private String basePath;
private GremlinServerSingleton gremlinServerSingleton;
+ private XmlFormatTransformer xmlFormatTransformer;
+
@Autowired
public RecentAPIConsumer(
HttpEntry traversalUriHttpEntry,
- DslQueryProcessor dslQueryProcessor,
SchemaVersions schemaVersions,
GremlinServerSingleton gremlinServerSingleton,
+ XmlFormatTransformer xmlFormatTransformer,
@Value("${schema.uri.base.path}") String basePath
){
this.traversalUriHttpEntry = traversalUriHttpEntry;
- this.dslQueryProcessor = dslQueryProcessor;
this.schemaVersions = schemaVersions;
this.gremlinServerSingleton = gremlinServerSingleton;
+ this.xmlFormatTransformer = xmlFormatTransformer;
this.basePath = basePath;
}
@GET
@Path("/{nodeType: .+}")
@Consumes({ MediaType.APPLICATION_JSON })
- @Produces({ MediaType.APPLICATION_JSON })
+ @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response getRecentData(String content, @PathParam("version") String versionParam,
@PathParam("nodeType") String nodeType, @Context HttpHeaders headers, @Context UriInfo info) {
@@ -126,15 +109,12 @@ public class RecentAPIConsumer extends RESTAPI {
public Response processRecentData(String content, @PathParam("version") String versionParam,
@PathParam("nodeType") String nodeType, @Context UriInfo info, @Context HttpHeaders headers) {
- String methodName = "processRecentData";
String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
- String realTime = headers.getRequestHeaders().getFirst("Real-Time");
String queryProcessor = headers.getRequestHeaders().getFirst("QueryProcessor");
QueryProcessorType processorType = this.processorType;
- Response response = null;
+ Response response;
TransactionalGraphEngine dbEngine = null;
try {
- LoggingContext.save();
if (queryProcessor != null) {
processorType = QueryProcessorType.valueOf(queryProcessor);
@@ -143,8 +123,7 @@ public class RecentAPIConsumer extends RESTAPI {
SchemaVersion version = new SchemaVersion(versionParam);
this.checkVersion(version);
- DBConnectionType type = this.determineConnectionType(sourceOfTruth, realTime);
- traversalUriHttpEntry.setHttpEntryProperties(version, type);
+ traversalUriHttpEntry.setHttpEntryProperties(version);
dbEngine = traversalUriHttpEntry.getDbEngine();
/*
@@ -156,10 +135,7 @@ public class RecentAPIConsumer extends RESTAPI {
GenericQueryProcessor processor = null;
- LoggingContext.targetEntity(TARGET_ENTITY);
- LoggingContext.targetServiceName(methodName);
- LoggingContext.startTime();
- StopWatch.conditionalStart();
+
processor = new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton).queryFrom(nodeType, "nodeQuery")
.uriParams(info.getQueryParameters())
@@ -179,12 +155,19 @@ public class RecentAPIConsumer extends RESTAPI {
result = formater.output(vertices).toString();
- double msecs = StopWatch.stopIfStarted();
- LoggingContext.elapsedTime((long) msecs, TimeUnit.MILLISECONDS);
- LoggingContext.successStatusFields();
- LOGGER.info("Completed");
+ //LOGGER.info("Completed");
+
+ String acceptType = headers.getHeaderString("Accept");
+
+ if(acceptType == null){
+ acceptType = MediaType.APPLICATION_JSON;
+ }
+
+ if(MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(acceptType))){
+ result = xmlFormatTransformer.transform(result);
+ }
- response = Response.status(Status.OK).type(MediaType.APPLICATION_JSON).entity(result).build();
+ response = Response.status(Status.OK).type(acceptType).entity(result).build();
} catch (AAIException e) {
response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, e);
@@ -193,8 +176,6 @@ public class RecentAPIConsumer extends RESTAPI {
response = consumerExceptionResponseGenerator(headers, info, HttpMethod.GET, ex);
} finally {
- LoggingContext.restoreIfPossible();
- LoggingContext.successStatusFields();
if (dbEngine != null) {
dbEngine.rollback();
}
@@ -212,7 +193,7 @@ public class RecentAPIConsumer extends RESTAPI {
public void checkNodeType(String nodeType) throws AAIException {
try {
- Introspector target = traversalUriHttpEntry.getLoader().introspectorFromName(nodeType);
+ traversalUriHttpEntry.getLoader().introspectorFromName(nodeType);
} catch (AAIUnknownObjectException e) {
throw new AAIException("AAI_6115", "Unrecognized nodeType [" + nodeType + "] passed to recents query.");
}
@@ -224,7 +205,7 @@ public class RecentAPIConsumer extends RESTAPI {
if (params != null && params.containsKey("hours") && params.getFirst("hours").matches("-?\\d+")) {
isHoursParameter = true;
- Long hours = 0L;
+ long hours;
try{
hours = Long.parseLong(params.getFirst("hours"));
}
@@ -238,7 +219,7 @@ 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 = 0L;
+ Long startTime;
try{
startTime = Long.parseLong(params.getFirst("date-time"));
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/TraversalConsumer.java b/aai-traversal/src/main/java/org/onap/aai/rest/TraversalConsumer.java
new file mode 100644
index 0000000..4aa0888
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/TraversalConsumer.java
@@ -0,0 +1,232 @@
+/**
+ * ============LICENSE_START==================================================
+ * org.onap.aai
+ * ===========================================================================
+ * Copyright © 2017-2020 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;
+
+import org.apache.tinkerpop.gremlin.process.traversal.P;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
+import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.SubgraphStrategy;
+import org.onap.aai.config.SpringContextAware;
+import org.onap.aai.db.props.AAIProperties;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.rest.db.HttpEntry;
+import org.onap.aai.restcore.RESTAPI;
+import org.onap.aai.serialization.engines.QueryStyle;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.serialization.queryformats.Format;
+
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.UriInfo;
+import java.util.concurrent.TimeUnit;
+
+public abstract class TraversalConsumer extends RESTAPI {
+
+ private static final String HISTORICAL_FORMAT = "state,lifecycle";
+ private final boolean historyEnabled;
+ private final int historyTruncateWindow;
+ private final long currentTime = System.currentTimeMillis();
+ private Long startTime = null;
+ private Long endTime = null;
+ private Long furthestInThePast = null;
+
+ public TraversalConsumer() {
+ this.historyTruncateWindow = Integer.parseInt(
+ SpringContextAware.getApplicationContext().getEnvironment().getProperty("history.truncate.window.days", "365"));
+ this.historyEnabled = Boolean.parseBoolean(
+ SpringContextAware.getApplicationContext().getEnvironment().getProperty("history.enabled", "false"));
+ }
+
+ public boolean isHistory(Format queryFormat) {
+ return isHistoryEnabled() && HISTORICAL_FORMAT.contains(queryFormat.toString());
+ }
+
+ public boolean isAggregate(Format queryFormat) {
+ return Format.aggregate.equals(queryFormat);
+ }
+
+ public boolean isHistoryEnabled() {
+ return historyEnabled;
+ }
+
+ protected SubgraphStrategy getSubgraphStrategy(long startTs, long endTs, Format format) {
+
+ if (Format.state.equals(format)) {
+ return getStateSubgraphStrategy(startTs);
+ } else if (Format.lifecycle.equals(format)) {
+ return getLifeCycleSubgraphStrategy(startTs, endTs);
+ } else {
+ return SubgraphStrategy.build()
+ .vertices(__.has(AAIProperties.START_TS, P.gte(startTs)))
+ .vertexProperties(__.has(AAIProperties.START_TS, P.gte(startTs)))
+ .edges(__.has(AAIProperties.START_TS, P.gte(startTs))).create();
+ }
+ }
+
+ private SubgraphStrategy getLifeCycleSubgraphStrategy(long startTs, long endTs) {
+ return SubgraphStrategy.build()
+ .vertices(
+ __.not(
+ __.or(
+ __.and(
+ __.has(AAIProperties.START_TS, P.gt(startTs)),
+ __.has(AAIProperties.START_TS, P.gt(endTs))
+ ),
+ __.and(
+ __.has(AAIProperties.END_TS).has(AAIProperties.END_TS, P.lt(startTs)),
+ __.has(AAIProperties.END_TS).has(AAIProperties.END_TS, P.lt(endTs))
+ )
+ )
+ )
+ ).vertexProperties(
+ __.not(
+ __.or(
+ __.and(
+ __.has(AAIProperties.START_TS, P.gt(startTs)),
+ __.has(AAIProperties.START_TS, P.gt(endTs))
+ ),
+ __.and(
+ __.has(AAIProperties.END_TS).has(AAIProperties.END_TS, P.lt(startTs)),
+ __.has(AAIProperties.END_TS).has(AAIProperties.END_TS, P.lt(endTs))
+ )
+ )
+ )
+ ).edges(
+ __.not(
+ __.or(
+ __.and(
+ __.has(AAIProperties.START_TS, P.gt(startTs)),
+ __.has(AAIProperties.START_TS, P.gt(endTs))
+ ),
+ __.and(
+ __.has(AAIProperties.END_TS).has(AAIProperties.END_TS, P.lt(startTs)),
+ __.has(AAIProperties.END_TS).has(AAIProperties.END_TS, P.lt(endTs))
+ )
+ )
+ )
+ ).create();
+ }
+
+ private SubgraphStrategy getStateSubgraphStrategy(long startTs) {
+ return SubgraphStrategy.build()
+ .vertices(
+ __.and(__.has(AAIProperties.START_TS, P.lte(startTs)),
+ __.or(__.hasNot(AAIProperties.END_TS), __.has(AAIProperties.END_TS, P.gt(startTs))))
+ ).vertexProperties(
+ __.and(__.has(AAIProperties.START_TS, P.lte(startTs)),
+ __.or(__.hasNot(AAIProperties.END_TS), __.has(AAIProperties.END_TS, P.gt(startTs))))
+ ).edges(
+ __.and(__.has(AAIProperties.START_TS, P.lte(startTs)),
+ __.or(__.hasNot(AAIProperties.END_TS), __.has(AAIProperties.END_TS, P.gt(startTs))))
+ ).create();
+ }
+
+
+
+ protected GraphTraversalSource getTraversalSource(TransactionalGraphEngine dbEngine, Format format, UriInfo info) throws AAIException {
+ if (isHistory(format)) {
+ long startTime = this.getStartTime(format, info.getQueryParameters());
+ long endTime = this.getEndTime(info.getQueryParameters());
+ return dbEngine.asAdmin().getTraversalSource().withStrategies(getSubgraphStrategy(startTime, endTime, format));
+ }
+ return dbEngine.asAdmin().getTraversalSource();
+ }
+
+ protected void validateHistoryParams(Format format, MultivaluedMap<String, String> params) throws AAIException {
+ getStartTime(format, params);
+ getEndTime(params);
+ }
+
+ /**
+ * If a request comes in for information prior to our truncation timeframe, throw an error.
+ * In the changes api, we never return change timestamps prior to the truncation timeframe.
+ * In the lifecycle api, we should treat a call with no timestamp as a lifecycle since call with a timestamp of the truncation time
+ * in the lifecycle api, we should return an error if the timestamp provided is prior to the truncation time
+ * In the state api, we should return an error if the timestamp provided is prior to the truncation time
+ * @param params
+ * @return
+ */
+ protected long getStartTime(Format format, MultivaluedMap<String, String> params) throws AAIException {
+
+ if (startTime != null) {
+ return startTime;
+ }
+
+ String startTs = params.getFirst("startTs") ;
+
+ if (Format.state.equals(format)) {
+ if (startTs == null || startTs.isEmpty() || "-1".equals(startTs) || "now".equals(startTs)) {
+ startTime = currentTime;
+ } else {
+ startTime = Long.valueOf(startTs);
+ verifyTimeAgainstTruncationTime(startTime);
+ }
+ } else if (Format.lifecycle.equals(format)) {
+ if("now".equals(startTs)) {
+ startTime = currentTime;
+ } else if (startTs == null || startTs.isEmpty()|| "-1".equals(startTs)) {
+ startTime = getFurthestInThePast();
+ } else {
+ startTime = Long.valueOf(startTs);
+ verifyTimeAgainstTruncationTime(startTime);
+ }
+ }
+
+ return startTime;
+
+ }
+
+ private void verifyTimeAgainstTruncationTime(long timestamp) throws AAIException {
+ if (timestamp < getFurthestInThePast()) {
+ throw new AAIException("AAI_4019");
+ }
+ }
+
+ protected long getEndTime(MultivaluedMap<String, String> params) throws AAIException {
+ if (endTime != null) {
+ return endTime;
+ }
+
+ String endTs = params.getFirst("endTs") ;
+
+ if (endTs == null || endTs.isEmpty() || "-1".equals(endTs) || "now".equals(endTs)) {
+ endTime = currentTime;
+ } else {
+ endTime = Long.valueOf(endTs);
+ verifyTimeAgainstTruncationTime(endTime);
+ }
+
+ return endTime;
+ }
+
+ protected Long getFurthestInThePast() {
+ if (furthestInThePast == null) {
+ furthestInThePast = currentTime - TimeUnit.DAYS.toMillis(historyTruncateWindow);
+ }
+ return furthestInThePast;
+ }
+
+ protected QueryStyle getQueryStyle(Format format, HttpEntry traversalUriHttpEntry) {
+ if (isHistory(format)) {
+ return QueryStyle.HISTORY_TRAVERSAL;
+ }
+ return traversalUriHttpEntry.getQueryStyle();
+ }
+
+}
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 9ffa69b..cf7f51d 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,13 +19,13 @@
*/
package org.onap.aai.rest.dsl;
+import org.antlr.v4.runtime.ParserRuleContext;
+
import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
-import org.antlr.v4.runtime.ParserRuleContext;
-
public class DslContext {
private ParserRuleContext ctx;
@@ -33,7 +33,7 @@ public class DslContext {
private boolean validationFlag = true;
private boolean isStartNode = false;
private String startNode = "";
- private List<String> startNodeKeys = new ArrayList<String>();
+ private List<String> startNodeKeys = new ArrayList<>();
private String currentNode;
private String previousNode;
@@ -45,13 +45,13 @@ public class DslContext {
private String whereStartNode = "";
- private Deque<String> unionStartNodes = new LinkedList<String>();
+ private Deque<String> unionStartNodes = new LinkedList<>();
/*
* Limit Queries have to be applied in the end - so i have to set this in
* context
*/
- StringBuilder limitQuery = new StringBuilder();
+ public StringBuilder limitQuery = new StringBuilder();
public ParserRuleContext getCtx() {
return ctx;
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 6817cf7..3d324ad 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
@@ -19,21 +19,26 @@
*/
package org.onap.aai.rest.dsl;
-import com.google.common.base.Joiner;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import org.onap.aai.edges.EdgeIngestor;
import org.onap.aai.edges.EdgeRule;
import org.onap.aai.edges.EdgeRuleQuery;
+import org.onap.aai.edges.enums.AAIDirection;
import org.onap.aai.edges.enums.EdgeType;
import org.onap.aai.edges.exceptions.EdgeRuleNotFoundException;
import org.onap.aai.introspection.Introspector;
import org.onap.aai.introspection.Loader;
import org.onap.aai.introspection.exceptions.AAIUnknownObjectException;
import org.onap.aai.schema.enums.PropertyMetadata;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.util.StringUtils;
import java.util.List;
import java.util.Optional;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
public class DslQueryBuilder {
@@ -43,6 +48,8 @@ public class DslQueryBuilder {
private StringBuilder query;
private StringBuilder queryException;
+ private static final Logger LOGGER = LoggerFactory.getLogger(DslQueryBuilder.class);
+
public DslQueryBuilder(EdgeIngestor edgeIngestor, Loader loader) {
this.edgeRules = edgeIngestor;
this.loader = loader;
@@ -74,6 +81,19 @@ public class DslQueryBuilder {
/*
* DSL always dedupes the results
*/
+ public DslQueryBuilder end(long selectCounter) {
+ if(selectCounter <= 0) {
+ return this.end();
+ } else {
+ String selectStep = "step" + selectCounter;
+ query.append(".as('").append(selectStep).append("')").append(".as('stepMain')" +
+ ".select('").append(selectStep).append("')").append(".store('x')").append(".select('stepMain').fold().dedup()");
+ }
+ return this;
+ }
+
+
+
public DslQueryBuilder end() {
query.append(".cap('x').unfold().dedup()");
return this;
@@ -85,6 +105,21 @@ public class DslQueryBuilder {
}
public DslQueryBuilder edgeQuery(List<String> edgeLabels, String aNode, String bNode) {
+ EdgeRuleQuery.Builder baseQ = new EdgeRuleQuery.Builder(aNode, bNode);
+ return edgeQueryWithBuilder(edgeLabels, aNode, bNode, baseQ);
+ }
+
+ public DslQueryBuilder edgeQuery(Edge edge, String aNode, String bNode) {
+ List<String> edgeLabels = edge.getLabels().stream().map(edgeLabel -> StringUtils.quote(edgeLabel.getLabel())).collect(Collectors.toList());
+ EdgeRuleQuery.Builder baseQ = new EdgeRuleQuery.Builder(aNode, bNode);
+
+ if((AAIDirection.valueOf(edge.getDirection().name())) != AAIDirection.BOTH) {
+ baseQ = baseQ.direction(AAIDirection.valueOf(edge.getDirection().name()));
+ }
+ return edgeQueryWithBuilder(edgeLabels, aNode, bNode, baseQ);
+ }
+
+ private DslQueryBuilder edgeQueryWithBuilder(List<String> edgeLabels, String aNode, String bNode, EdgeRuleQuery.Builder edgeBuilder) {
//TODO : change this for fuzzy search.
String edgeType = "";
@@ -94,48 +129,42 @@ public class DslQueryBuilder {
if (!edgeLabels.isEmpty()) {
edgeTraversalClause = ".createEdgeTraversalWithLabels(";
- edgeLabelsClause = String.join("", ", new ArrayList<>(Arrays.asList(", Joiner.on(",").join(edgeLabels), "))");
+ edgeLabelsClause = String.join("", ", new ArrayList<>(Arrays.asList(", String.join(",", edgeLabels), "))");
}
+ LOGGER.debug("EdgeLabels Clause: {}", edgeLabelsClause);
- EdgeRuleQuery.Builder baseQ = new EdgeRuleQuery.Builder(aNode, bNode);
Multimap<String, EdgeRule> rules = ArrayListMultimap.create();
try {
- //TODO chnage this - ugly
if (edgeLabels.isEmpty()) {
- rules.putAll(edgeRules.getRules(baseQ.build()));
+ rules.putAll(edgeRules.getRules(edgeBuilder.build()));
} else {
- edgeLabels.stream().forEach(label -> {
+ edgeLabels.forEach(label -> {
try {
- rules.putAll(edgeRules.getRules(baseQ.label(label).build()));
+ rules.putAll(edgeRules.getRules(edgeBuilder.label(label).build()));
} catch (EdgeRuleNotFoundException e) {
- queryException.append("AAI_6120" + "No EdgeRule found for passed nodeTypes: " + aNode
- + ", " + bNode + label);
-
+ queryException.append("Exception while finding the edge rule between the nodeTypes: ").append(aNode).append(", ").append(bNode).append(label);
}
});
}
} catch (EdgeRuleNotFoundException e) {
if (!edgeLabels.isEmpty()) {
- queryException.append("AAI_6120" + "No EdgeRule found for passed nodeTypes: " + aNode
- + ", " + bNode + edgeLabels.stream().toString());
+ queryException.append("- No EdgeRule found for passed nodeTypes: ").append(aNode).append(", ").append(bNode).append(edgeLabels.stream().toString());
}
else {
- queryException.append("AAI_6120" + "No EdgeRule found for passed nodeTypes: " + aNode
- + ", " + bNode);
+ queryException.append("- No EdgeRule found for passed nodeTypes: ").append(aNode).append(", ").append(bNode);
}
return this;
}
if (rules.isEmpty() || rules.keys().isEmpty()) {
- queryException.append("AAI_6120" + "No EdgeRule found for passed nodeTypes: " + aNode
- + ", " + bNode);
+ queryException.append("- No EdgeRule found for passed nodeTypes: ").append(aNode).append(", ").append(bNode);
} else {
if (edgeLabels.isEmpty()) {
- if (edgeRules.hasRule(baseQ.edgeType(EdgeType.TREE).build())) {
+ if (edgeRules.hasRule(edgeBuilder.edgeType(EdgeType.TREE).build())) {
edgeType = "EdgeType.TREE" + ",";
}
- if (edgeRules.hasRule(baseQ.edgeType(EdgeType.COUSIN).build())) {
+ if (edgeRules.hasRule(edgeBuilder.edgeType(EdgeType.COUSIN).build())) {
if (edgeType.isEmpty()) {
edgeType = "EdgeType.COUSIN" + ",";
} else {
@@ -152,13 +181,19 @@ public class DslQueryBuilder {
}
- public DslQueryBuilder where() {
+ public DslQueryBuilder where(boolean isNot) {
query.append(".where(");
+ if(isNot){
+ query.append("builder.newInstance().not(");
+ }
return this;
}
- public DslQueryBuilder endWhere() {
+ public DslQueryBuilder endWhere(boolean isNot) {
query.append(")");
+ if(isNot){
+ query.append(")");
+ }
return this;
}
@@ -168,12 +203,14 @@ public class DslQueryBuilder {
}
public DslQueryBuilder filter(boolean isNot, String node, String key, List<String> values) {
- return this.filterPropertyStart(isNot).filterPropertyKeys(node, key, values).filterPropertyEnd();
+ return this.filterPropertyStart(isNot,values).filterPropertyKeys(node, key, values).filterPropertyEnd();
}
- public DslQueryBuilder filterPropertyStart(boolean isNot) {
+ public DslQueryBuilder filterPropertyStart(boolean isNot, List<String> values) {
if (isNot) {
query.append(".getVerticesExcludeByProperty(");
+ } else if(values!= null && !values.isEmpty() && Boolean.parseBoolean(values.get(0))) {
+ query.append(".getVerticesByBooleanProperty(");
} else {
query.append(".getVerticesByProperty(");
}
@@ -188,46 +225,63 @@ public class DslQueryBuilder {
public DslQueryBuilder validateFilter(String node, List<String> keys) {
try {
Introspector obj = loader.introspectorFromName(node);
+
if (keys.isEmpty()) {
- queryException.append("No keys sent. Valid keys for " + node + " are "
- + String.join(",", obj.getIndexedProperties()));
+ queryException.append("No keys sent. Valid keys for ")
+ .append(node)
+ .append(" are ")
+ .append(String.join(",", obj.getIndexedProperties()));
return this;
}
- boolean notIndexed = keys.stream()
- .filter(prop -> obj.getIndexedProperties().contains(prop)).collect(Collectors.toList()).isEmpty();
-
- if (notIndexed) {
- queryException.append("Non indexed keys sent. Valid keys for " + node + " "
- + String.join(",", obj.getIndexedProperties()));
- }
} catch (AAIUnknownObjectException e) {
- queryException.append("Unknown Object being referenced by the query" + node);
+ queryException.append("Unknown Object being referenced by the query").append(node);
}
return this;
}
+ public DslQueryBuilder select(boolean isNot, long selectCounter, List<String> keys) {
+ /*
+ * TODO : isNot should look at the vertex properties and include everything except the notKeys
+ */
+
+ Pattern p = Pattern.compile("aai-node-type");
+ Matcher m = p.matcher(query);
+ int count = 0;
+ while (m.find()){
+ count++;
+ }
+
+ if (selectCounter == count || keys == null) {
+ String selectStep = "step" + selectCounter;
+// String keysArray = String.join(",", keys);
+ query.append(".as('").append(selectStep).append("')")
+ .append(".as('stepMain').select('").append(selectStep).append("')");
+ }
+ return this;
+ }
+
public DslQueryBuilder filterPropertyKeys(String node, String key, List<String> values) {
try {
Introspector obj = loader.introspectorFromName(node);
-
- Optional<String> alias = obj.getPropertyMetadata(key, PropertyMetadata.DB_ALIAS);
+ Optional<String> alias = obj.getPropertyMetadata(key.replace("'",""), PropertyMetadata.DB_ALIAS);
if (alias.isPresent()) {
- key = alias.get();
+ key = StringUtils.quote(alias.get());
}
+
query.append(key);
if (!values.isEmpty()) {
if (values.size() > 1) {
String valuesArray = String.join(",", values);
- query.append(",").append(" new ArrayList<>(Arrays.asList(" + valuesArray + "))");
+ query.append(",").append(" new ArrayList<>(Arrays.asList(").append(valuesArray).append("))");
} else {
query.append(",").append(values.get(0));
}
}
} catch (AAIUnknownObjectException e) {
- queryException.append("Unknown Object being referenced by the query" + node);
+ queryException.append("Unknown Object being referenced by the query").append(node);
}
return this;
}
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 a3978fd..14663e1 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
@@ -19,86 +19,151 @@
*/
package org.onap.aai.rest.dsl;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
-import org.antlr.v4.runtime.CharStreams;
-import org.antlr.v4.runtime.CommonTokenStream;
+import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import org.antlr.v4.runtime.tree.ParseTree;
+import org.antlr.v4.runtime.tree.ParseTreeListener;
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.v2.DslListener;
+import org.onap.aai.rest.dsl.validation.DslValidator;
+import org.onap.aai.rest.enums.QueryVersion;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
import java.nio.charset.StandardCharsets;
-
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
/**
* The Class DslQueryProcessor.
*/
public class DslQueryProcessor {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(DslQueryProcessor.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(DslQueryProcessor.class);
+
+ private Map<QueryVersion, ParseTreeListener> dslListeners;
+ private boolean startNodeValidationFlag = true;
+ private String validationRules = "";
+ private String packageName = "org.onap.aai.dsl.";
+ private static final String LEXER = "AAIDslLexer";
+ private static final String PARSER = "AAIDslParser";
+ private static final String EOF_TOKEN = "<EOF>";
- private DslListener dslListener;
- private boolean validationFlag = true;
+ private boolean isAggregate = false;
@Autowired
- public DslQueryProcessor(DslListener dslListener) {
- this.dslListener = dslListener;
+ public DslQueryProcessor(Map<QueryVersion, ParseTreeListener> dslListeners) {
+ this.dslListeners = dslListeners;
}
- public String parseAaiQuery(String aaiQuery) throws AAIException {
+ public Map<String, Object> parseAaiQuery(QueryVersion version, String aaiQuery) throws AAIException {
+ Map<String, Object> resultMap = new HashMap<>();
try {
// Create a input stream that reads our string
InputStream stream = new ByteArrayInputStream(aaiQuery.getBytes(StandardCharsets.UTF_8));
- // Create a lexer from the input CharStream
- AAIDslLexer lexer = new AAIDslLexer(CharStreams.fromStream(stream, StandardCharsets.UTF_8));
+ packageName = packageName + version.toString().toLowerCase() + ".";
+
+ Class<?> lexerClass = Class.forName(packageName + LEXER);
+ Class<?> parserClass = Class.forName(packageName + PARSER);
+
+ Lexer lexer = (Lexer)lexerClass.getConstructor(CharStream.class).newInstance(CharStreams.fromStream(stream, StandardCharsets.UTF_8));
lexer.removeErrorListeners();
lexer.addErrorListener(new AAIDslErrorListener());
-
- // 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);
- parser.removeErrorListeners(); // remove ConsoleErrorListener
+ Parser parser = (Parser)parserClass.getConstructor(TokenStream.class).newInstance(tokens);
+ parser.removeErrorListeners();
parser.addErrorListener(new AAIDslErrorListener());
+ ParseTreeListener dslListener = dslListeners.get(version);
+ dslListener.getClass().getMethod("setValidationFlag", boolean.class).invoke(dslListener, isStartNodeValidationFlag());
+ dslListener.getClass().getMethod("setAggregateFlag", boolean.class).invoke(dslListener,isAggregate());
- dslListener.setValidationFlag(isValidationFlag());
- // Specify our entry point
- ParseTree ptree = parser.aaiquery();
- LOGGER.info("QUERY-interim" + ptree.toStringTree(parser));
+ if(!getValidationRules().isEmpty() && !"none".equals(getValidationRules())) {
+ DslValidator validator = new DslValidator.Builder()
+ .create();
+ dslListener.getClass().getMethod("setQueryValidator", DslValidator.class, String.class).invoke(dslListener, validator, getValidationRules());
+ }
+ // Specify our entry point
+ ParseTree ptree = (ParseTree)parserClass.getMethod("aaiquery").invoke(parser);
+
+ // Check if there is no EOF token at the end of the parsed aaiQuery
+ // If none, DSL query may have not been parsed correctly and omitted part of the query out. If so error out.
+ // If it wasn't expecting a opening parens after a closing bracket for union, it will drop the proceeding part of the query.
+ Token eofToken = tokens.get(tokens.size() - 1);
+ if (eofToken != null && !eofToken.getText().equals(EOF_TOKEN)) {
+ if (eofToken.getText().equals("(")) {
+ throw new AAIException("AAI_6153", "DSL Syntax Error while processing the query: DSL Query could not be parsed correctly. Please check your syntax.");
+ }
+ }
+
+ if (LOGGER.isInfoEnabled()) {
+ LOGGER.info("QUERY-interim {}", ptree.toStringTree(parser));
+ }
// Walk it and attach our listener
ParseTreeWalker walker = new ParseTreeWalker();
+
walker.walk(dslListener, ptree);
- LOGGER.info("Final QUERY" + dslListener.getQuery());
-
- /*
- * TODO - Visitor patternQueryDslVisitor visitor = new
- * QueryDslVisitor(); String query = visitor.visit(ptree);
- *
- */
- return dslListener.getQuery();
- } catch(ParseCancellationException e){
- throw new AAIException("AAI_6149", "DSL Syntax Error while processing the query :" + e.getMessage());
- } catch(AAIException e) {
- throw new AAIException("AAI_6149", "DSL Syntax Error while processing the query :" + e.getMessage());
+ String query = (String) dslListener.getClass().getMethod("getQuery").invoke(dslListener);
+ resultMap.put("query", query);
+ if (version.equals(QueryVersion.V2)){
+ Map<String, List<String>> selectKeys= ((DslListener)dslListener).getSelectKeys();
+ if (selectKeys != null && !selectKeys.isEmpty()){
+ resultMap.put("propertiesMap", selectKeys);
+ }
+ }
+ LOGGER.info("Final QUERY {}", query);
+ return resultMap;
+ }catch(InvocationTargetException e){
+ if (e.getTargetException() instanceof ParseCancellationException) {
+ throw new AAIException("AAI_6153", "DSL Syntax Error while processing the query :" + e.getTargetException().getMessage());
+ } else if (e.getTargetException() instanceof AAIException) {
+ AAIException ex = (AAIException)e.getTargetException();
+ throw new AAIException((ex.getCode().isEmpty() ? "AAI_6149":ex.getCode()), "DSL Error while processing the query :" + ex.getMessage());
+ } else {
+ throw new AAIException("AAI_6152","Exception while processing DSL query");
+ }
+
+ } catch(ParseCancellationException e) {
+ throw new AAIException("AAI_6153", "DSL Syntax Error while processing the query: " + e.getMessage());
+
} catch (Exception e) {
- throw new AAIException("AAI_6149","Error while processing the query :" + e.getMessage());
+ throw new AAIException("AAI_6152","Error while processing the query: " + e.getMessage());
+
}
}
- public boolean isValidationFlag() {
- return validationFlag;
+
+ public boolean isStartNodeValidationFlag() {
+ return startNodeValidationFlag;
+ }
+
+ public void setStartNodeValidationFlag(boolean startNodeValidationFlag) {
+ this.startNodeValidationFlag = startNodeValidationFlag;
+ }
+
+ public boolean isAggregate() {
+ return isAggregate;
+ }
+
+ public void setAggregate(boolean aggregate) {
+ this.isAggregate = aggregate;
+ }
+
+ public String getValidationRules() {
+ return validationRules;
}
- public void setValidationFlag(boolean validationFlag) {
- this.validationFlag = validationFlag;
+ public void setValidationRules(String validationRules) {
+ this.validationRules = validationRules;
}
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/Edge.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/Edge.java
new file mode 100644
index 0000000..c3be5dc
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/Edge.java
@@ -0,0 +1,59 @@
+/**
+ * ============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.dsl;
+
+import org.onap.aai.rest.enums.EdgeDirection;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Edge {
+
+ private List<EdgeLabel> labels;
+ private EdgeDirection direction;
+
+ public Edge (EdgeDirection direction, List<EdgeLabel> labels) {
+ this.labels = labels;
+ this.direction = direction;
+ }
+
+ public List<EdgeLabel> getLabels() {
+ return labels;
+ }
+
+ public void setLabels(List<EdgeLabel> labels) {
+ this.labels = labels;
+ }
+
+ public EdgeDirection getDirection() {
+ return direction;
+ }
+
+ public void setDirection(EdgeDirection direction) {
+ this.direction = direction;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("labels: %s, direction: %s ",
+ labels.stream().map(EdgeLabel::getLabel).collect(Collectors.joining(",")),
+ this.getDirection().name());
+ }
+} \ No newline at end of file
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/EdgeLabel.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/EdgeLabel.java
new file mode 100644
index 0000000..703adaf
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/EdgeLabel.java
@@ -0,0 +1,48 @@
+/**
+ * ============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.dsl;
+
+public class EdgeLabel {
+
+ private String label;
+ private boolean isExactMatch;
+
+ public EdgeLabel (String label, boolean isExactMatch) {
+ this.isExactMatch = isExactMatch;
+ this.label = label;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+ public boolean isExactMatch() {
+ return isExactMatch;
+ }
+
+ public void setExactMatch(boolean isExactMatch) {
+ this.isExactMatch = isExactMatch;
+ }
+
+} \ No newline at end of file
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/v1/DslListener.java
index 8fd23cc..4bb093e 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/v1/DslListener.java
@@ -17,25 +17,26 @@
* limitations under the License.
* ============LICENSE_END=========================================================
*/
-package org.onap.aai.rest.dsl;
+package org.onap.aai.rest.dsl.v1;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
import com.google.common.collect.Lists;
-import org.onap.aai.AAIDslBaseListener;
-import org.onap.aai.AAIDslParser;
+import org.onap.aai.dsl.v1.AAIDslBaseListener;
+import org.onap.aai.dsl.v1.AAIDslParser;
import org.onap.aai.edges.EdgeIngestor;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Loader;
import org.onap.aai.introspection.LoaderFactory;
import org.onap.aai.introspection.ModelType;
+import org.onap.aai.logging.ErrorLogHelper;
+import org.onap.aai.rest.dsl.DslQueryBuilder;
+import org.onap.aai.rest.dsl.validation.DslValidator;
+import org.onap.aai.rest.dsl.validation.DslValidatorRule;
import org.onap.aai.setup.SchemaVersions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.LinkedList;
-import java.util.List;
+import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -44,17 +45,29 @@ import java.util.stream.Stream;
*/
public class DslListener extends AAIDslBaseListener {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(DslListener.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(DslListener.class);
- boolean validationFlag = false;
- EdgeIngestor edgeIngestor;
- Loader loader;
+ private boolean validationFlag = false;
+ private EdgeIngestor edgeIngestor;
+ private Loader loader;
+ private Optional<DslValidator> queryValidator = Optional.empty();
+ private boolean hasReturnValue = false;
+
+ private String validationRules = "none";
private Deque<DslQueryBuilder> dslQueryBuilders = new LinkedList<>();
private Deque<String> traversedNodes = new LinkedList<>();
private Deque<List<String>> returnedNodes = new LinkedList<>();
- List<String> traversedEdgeLabels = new LinkedList<>();
+ private List<String> traversedEdgeLabels = new LinkedList<>();
+
+ private boolean isAggregate = false;
+
+ /*
+ * Additional datastructures to store all nodeCount & looped edges
+ */
+ private int nodeCount = 0;
+ private List<String> traversedEdges = new LinkedList<>();
/**
* Instantiates a new DslListener.
@@ -70,12 +83,20 @@ public class DslListener extends AAIDslBaseListener {
}
public String getQuery() throws AAIException {
- //TODO Change the exception reporting
if (!getException().isEmpty()) {
- LOGGER.error("Exception in the DSL Query" + getException());
- throw new AAIException("AAI_6149", getException());
+ AAIException aaiException = new AAIException("AAI_6149", getException());
+ ErrorLogHelper.logException(aaiException);
+ throw aaiException;
}
+ DslValidatorRule ruleValidator = new DslValidatorRule.Builder()
+ .loop(getValidationRules() , traversedEdges)
+ .nodeCount(getValidationRules(), nodeCount).build();
+ if(queryValidator.isPresent() && !queryValidator.get().validate(ruleValidator)){
+ AAIException aaiException = new AAIException("AAI_6151", "Validation error " + queryValidator.get().getErrorMessage() );
+ ErrorLogHelper.logException(aaiException);
+ throw aaiException;
+ }
return this.compile();
}
@@ -85,7 +106,8 @@ public class DslListener extends AAIDslBaseListener {
}
public String getException() {
- return builder().getQueryException().toString();
+ List<String> exceptions = dslQueryBuilders.stream().map(dslQb -> dslQb.getQueryException().toString()).collect(Collectors.toList());
+ return String.join("", Lists.reverse(exceptions));
}
@Override
@@ -94,6 +116,13 @@ public class DslListener extends AAIDslBaseListener {
}
@Override
+ public void exitAaiquery(AAIDslParser.AaiqueryContext ctx) {
+ if (!hasReturnValue) {
+ throw new RuntimeException(new AAIException("AAI_6149", "No nodes marked for output"));
+ }
+ }
+
+ @Override
public void enterStartStatement(AAIDslParser.StartStatementContext ctx) {
builder().start();
}
@@ -124,7 +153,6 @@ public class DslListener extends AAIDslBaseListener {
if(!ctx.traversal().isEmpty()) {
count += ctx.traversal().size() ;
}
- //TODO so ugly
String resultNode = traversedNodes.peekFirst();
if (!traversedNodes.isEmpty()) {
@@ -147,6 +175,7 @@ public class DslListener extends AAIDslBaseListener {
if (!traversedNodes.isEmpty()) {
builder().edgeQuery(traversedEdgeLabels, traversedNodes.peekFirst(), ctx.label().getText());
+ traversedEdges.add(traversedNodes.peekFirst() + ctx.label().getText());
} else {
builder().nodeQuery(ctx.label().getText());
}
@@ -164,15 +193,17 @@ public class DslListener extends AAIDslBaseListener {
if (ctx.filter() != null) {
allKeys = ctx.filter().propertyFilter().stream().flatMap(
pf -> pf.key().stream()).map(
- e -> e.getText().replaceAll("\'", "")).collect(Collectors.toList());
+ e -> e.getText().replaceFirst("\'", "").substring(0, e.getText().length() - 2)).collect(Collectors.toList());
}
builder().validateFilter(ctx.label().getText(), allKeys);
}
if (ctx.store() != null) {
builder().store();
+ hasReturnValue = true;
}
traversedEdgeLabels = new ArrayList<>();
+ nodeCount++;
}
@@ -187,12 +218,17 @@ public class DslListener extends AAIDslBaseListener {
String resultNode = returnedNodes.pop().get(0);
traversedNodes.addFirst(resultNode);
builder().endUnion();
+ if (ctx.store() != null) {
+ builder().store();
+ hasReturnValue = true;
+ }
}
@Override
public void enterWhereFilter(AAIDslParser.WhereFilterContext ctx) {
+ boolean isNot = ctx.not() != null && !ctx.not().isEmpty();
returnedNodes.addFirst(new ArrayList<>());
- builder().where();
+ builder().where(isNot);
}
@Override
@@ -200,15 +236,8 @@ public class DslListener extends AAIDslBaseListener {
if(!returnedNodes.isEmpty()) {
returnedNodes.pop();
}
- builder().endWhere();
- }
-
- @Override
- public void enterTraversal(AAIDslParser.TraversalContext ctx) {
- }
-
- @Override
- public void enterEdge(AAIDslParser.EdgeContext ctx) {
+ boolean isNot = ctx.not() != null && !ctx.not().isEmpty();
+ builder().endWhere(isNot);
}
@Override
@@ -218,11 +247,6 @@ public class DslListener extends AAIDslBaseListener {
}
@Override
- public void enterFilter(AAIDslParser.FilterContext ctx) {
-
- }
-
- @Override
public void enterPropertyFilter(AAIDslParser.PropertyFilterContext ctx) {
List<AAIDslParser.KeyContext> valueList = ctx.key();
@@ -231,17 +255,26 @@ public class DslListener extends AAIDslBaseListener {
boolean isNot = ctx.not() != null && !ctx.not().isEmpty();
List<AAIDslParser.NumContext> numberValues = ctx.num();
+ List<AAIDslParser.BoolContext> booleanValues = ctx.bool();
+
/*
* Add all String values
*/
List<String> values = valueList.stream().filter(value -> !filterKey.equals(value.getText()))
- .map(value -> "'" + value.getText().replace("'", "") + "'").collect(Collectors.toList());
+ .map(value -> value.getText()).collect(Collectors.toList());
+
/*
* Add all numeric values
*/
values.addAll(numberValues.stream().filter(value -> !filterKey.equals(value.getText()))
.map(value -> value.getText()).collect(Collectors.toList()));
+ /*
+ * Add all boolean values
+ */
+ values.addAll(booleanValues.stream().filter(value -> !filterKey.equals(value.getText()))
+ .map(value -> value.getText().toLowerCase()).collect(Collectors.toList()));
+
builder().filter(isNot, traversedNodes.peekFirst(), filterKey, values);
}
@@ -254,4 +287,20 @@ public class DslListener extends AAIDslBaseListener {
this.validationFlag = validationFlag;
}
+ public void setQueryValidator(DslValidator queryValidator, String validationRules) {
+ this.queryValidator = Optional.of(queryValidator);
+ this.validationRules = validationRules;
+ }
+ public String getValidationRules() {
+ return validationRules;
+ }
+
+ public void setAggregateFlag(boolean isAggregate) {
+ this.isAggregate = isAggregate;
+ }
+
+ public boolean isAggregate(){
+ return this.isAggregate;
+ }
+
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/v2/DslListener.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/v2/DslListener.java
new file mode 100644
index 0000000..8f9f145
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/v2/DslListener.java
@@ -0,0 +1,353 @@
+/**
+ * ============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.dsl.v2;
+
+import com.google.common.collect.Lists;
+import org.onap.aai.dsl.v2.AAIDslBaseListener;
+import org.onap.aai.dsl.v2.AAIDslParser;
+import org.onap.aai.edges.EdgeIngestor;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.introspection.LoaderFactory;
+import org.onap.aai.introspection.ModelType;
+import org.onap.aai.logging.ErrorLogHelper;
+import org.onap.aai.rest.dsl.DslQueryBuilder;
+import org.onap.aai.rest.dsl.Edge;
+import org.onap.aai.rest.dsl.EdgeLabel;
+import org.onap.aai.rest.dsl.validation.DslValidator;
+import org.onap.aai.rest.dsl.validation.DslValidatorRule;
+import org.onap.aai.rest.enums.EdgeDirection;
+import org.onap.aai.setup.SchemaVersions;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import java.util.*;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * The Class DslListener.
+ */
+public class DslListener extends AAIDslBaseListener {
+
+ private static final Logger LOGGER = LoggerFactory.getLogger(DslListener.class.getName());
+
+ private boolean validationFlag = false;
+ private EdgeIngestor edgeIngestor;
+ private Loader loader;
+ private Optional<DslValidator> queryValidator = Optional.empty();
+ private boolean hasReturnValue = false;
+
+ private String validationRules = "none";
+
+ private Deque<DslQueryBuilder> dslQueryBuilders = new LinkedList<>();
+ private Deque<String> traversedNodes = new LinkedList<>();
+ private Deque<List<String>> returnedNodes = new LinkedList<>();
+
+ private Deque<Edge> traversedEdges = new ArrayDeque<>();
+ private long selectCounter = 0;
+
+ /*
+ * Additional datastructures to store all nodeCount & looped edges
+ */
+ int nodeCount = 0;
+ private List<String> traversedEdgesOld = new LinkedList<>();
+
+ private Map<String, List<String>> selectKeys = new HashMap<String, List<String>>();
+ private boolean isAggregate;
+
+ public Map<String, List<String>> getSelectKeys() {
+ return selectKeys;
+ }
+
+ public void setSelectKeys(String nodeType, List<String> properties) {
+ this.selectKeys.put(nodeType, properties);
+ }
+
+ /**
+ * Instantiates a new DslListener.
+ */
+ @Autowired
+ public DslListener(EdgeIngestor edgeIngestor, SchemaVersions schemaVersions, LoaderFactory loaderFactory) {
+ this.loader = loaderFactory.createLoaderForVersion(ModelType.MOXY, schemaVersions.getDefaultVersion());
+ this.edgeIngestor = edgeIngestor;
+ }
+
+ public DslQueryBuilder builder() {
+ return dslQueryBuilders.peekFirst();
+ }
+
+ public String getQuery() throws AAIException {
+ //TODO Change the exception reporting
+ if (!getException().isEmpty()) {
+ AAIException aaiException = new AAIException("AAI_6149", getException());
+ ErrorLogHelper.logException(aaiException);
+ throw aaiException;
+ }
+
+ DslValidatorRule ruleValidator = new DslValidatorRule.Builder()
+ .loop(getValidationRules() , traversedEdgesOld)
+ .nodeCount(getValidationRules(), nodeCount).build();
+ if(queryValidator.isPresent() && !queryValidator.get().validate(ruleValidator)){
+ AAIException aaiException = new AAIException("AAI_6151", "Validation error " + queryValidator.get().getErrorMessage() );
+ ErrorLogHelper.logException(aaiException);
+ throw aaiException;
+ }
+ return this.compile();
+ }
+
+ public String compile() {
+ List<String> queries = dslQueryBuilders.stream().map(dslQb -> dslQb.getQuery().toString()).collect(Collectors.toList());
+ return String.join("", Lists.reverse(queries));
+ }
+
+ public String getException() {
+ List<String> exceptions = dslQueryBuilders.stream().map(dslQb -> dslQb.getQueryException().toString()).collect(Collectors.toList());
+ return String.join("", Lists.reverse(exceptions));
+ }
+
+ @Override
+ public void enterAaiquery(AAIDslParser.AaiqueryContext ctx) {
+ dslQueryBuilders.push(new DslQueryBuilder(edgeIngestor, loader));
+ }
+
+ @Override
+ public void exitAaiquery(AAIDslParser.AaiqueryContext ctx) {
+ if (!hasReturnValue) {
+ throw new RuntimeException(new AAIException("AAI_6149", "No nodes marked for output"));
+ }
+ }
+
+ @Override
+ public void enterStartStatement(AAIDslParser.StartStatementContext ctx) {
+ builder().start();
+ }
+
+ @Override
+ public void exitStartStatement(AAIDslParser.StartStatementContext ctx) {
+ builder().end(selectCounter);
+ if (!traversedNodes.isEmpty()) {
+ traversedNodes.removeFirst();
+ }
+
+ }
+
+ @Override
+ public void exitLimit(AAIDslParser.LimitContext ctx) {
+ builder().limit(ctx.num().getText());
+ }
+
+ @Override
+ public void enterNestedStatement(AAIDslParser.NestedStatementContext ctx) {
+ dslQueryBuilders.addFirst(new DslQueryBuilder(edgeIngestor, loader));
+ builder().startInstance();
+ }
+
+ @Override
+ public void exitNestedStatement(AAIDslParser.NestedStatementContext ctx) {
+ int count = 1;
+ if(!ctx.traversal().isEmpty()) {
+ count = ctx.traversal().size() ;
+ }
+ String resultNode = traversedNodes.peekFirst();
+
+ if (!traversedNodes.isEmpty()) {
+ Stream<Integer> integers = Stream.iterate(0, i -> i + 1);
+ integers.limit(count)
+ .forEach(i -> traversedNodes.removeFirst());
+ }
+ List<String> resultNodes = returnedNodes.pop();
+ resultNodes.add(resultNode);
+ returnedNodes.addFirst(resultNodes);
+ }
+
+ @Override
+ public void enterComma(AAIDslParser.CommaContext ctx) {
+ builder().comma();
+ }
+
+ @Override
+ public void enterVertex(AAIDslParser.VertexContext ctx) {
+
+ if (!traversedEdges.isEmpty() && !traversedNodes.isEmpty()) {
+ builder().edgeQuery(traversedEdges.peekFirst(), traversedNodes.peekFirst(), ctx.label().getText());
+ traversedEdgesOld.add(traversedNodes.peekFirst() + ctx.label().getText());
+ } else {
+ builder().nodeQuery(ctx.label().getText());
+ }
+
+ traversedNodes.addFirst(ctx.label().getText());
+ }
+
+ @Override
+ public void exitVertex(AAIDslParser.VertexContext ctx) {
+
+ /*TODO dont use context */
+ if (ctx.getParent() instanceof AAIDslParser.StartStatementContext && isValidationFlag()) {
+ List<String> allKeys = new ArrayList<>();
+
+ if (ctx.filter() != null) {
+ allKeys = ctx.filter().propertyFilter().stream().flatMap(
+ pf -> pf.key().stream()).map(
+ e -> e.getText().replaceAll("\'", "")).collect(Collectors.toList());
+ }
+ builder().validateFilter(ctx.label().getText(), allKeys);
+ }
+ if (ctx.store() != null) {
+ if (isAggregate() && (selectCounter == nodeCount) && (nodeCount < traversedNodes.size())) {
+ builder().select(false, selectCounter++, null);
+ }
+ builder().store();
+ hasReturnValue = true;
+ }
+ nodeCount++;
+ }
+
+
+ @Override
+ public void enterUnionVertex(AAIDslParser.UnionVertexContext ctx) {
+ returnedNodes.addFirst(new ArrayList<>());
+ builder().union();
+ }
+
+ @Override
+ public void exitUnionVertex(AAIDslParser.UnionVertexContext ctx) {
+ String resultNode = returnedNodes.pop().get(0);
+ traversedNodes.addFirst(resultNode);
+ builder().endUnion();
+ if (ctx.store() != null) {
+ builder().store();
+ hasReturnValue = true;
+ }
+ }
+
+ @Override
+ public void enterWhereFilter(AAIDslParser.WhereFilterContext ctx) {
+ boolean isNot = ctx.not() != null && !ctx.not().isEmpty();
+ returnedNodes.addFirst(new ArrayList<>());
+ builder().where(isNot);
+ }
+
+ @Override
+ public void exitWhereFilter(AAIDslParser.WhereFilterContext ctx) {
+ if(!returnedNodes.isEmpty()) {
+ returnedNodes.pop();
+ }
+ boolean isNot = ctx.not() != null && !ctx.not().isEmpty();
+ builder().endWhere(isNot);
+ }
+
+ @Override
+ public void enterEdge(AAIDslParser.EdgeContext ctx) {
+ List<EdgeLabel> labels = new ArrayList<>();
+
+ if(ctx.edgeFilter() != null) {
+ labels.addAll(ctx.edgeFilter().key().stream().map(
+ e -> new EdgeLabel(removeSingleQuotes(e.getText()), true))
+ .collect(Collectors.toList()));
+ }
+ EdgeDirection direction = EdgeDirection.BOTH;
+ if(ctx.DIRTRAVERSE() != null){
+ direction = EdgeDirection.fromValue(ctx.DIRTRAVERSE().getText());
+ }
+ traversedEdges.addFirst(new Edge(direction, labels));
+ }
+
+ protected String removeSingleQuotes(String value) {
+ return value.replaceFirst("^'(.*)'$", "$1");
+ }
+
+ @Override
+ public void enterPropertyFilter(AAIDslParser.PropertyFilterContext ctx) {
+
+ List<AAIDslParser.KeyContext> valueList = ctx.key();
+ String filterKey = valueList.get(0).getText();
+
+ boolean isNot = ctx.not() != null && !ctx.not().isEmpty();
+ List<AAIDslParser.NumContext> numberValues = ctx.num();
+
+ List<AAIDslParser.BoolContext> booleanValues = ctx.bool();
+
+ /*
+ * Add all String values
+ */
+ List<String> values = valueList.stream().filter(value -> !filterKey.equals(value.getText()))
+ .map(value -> "'" + value.getText().replace("'", "") + "'").collect(Collectors.toList());
+ /*
+ * Add all numeric values
+ */
+ values.addAll(numberValues.stream().filter(value -> !filterKey.equals(value.getText()))
+ .map(value -> value.getText()).collect(Collectors.toList()));
+
+ /*
+ * Add all boolean values
+ */
+ values.addAll(booleanValues.stream().filter(value -> !filterKey.equals(value.getText()))
+ .map(value -> value.getText().toLowerCase()).collect(Collectors.toList()));
+
+ builder().filter(isNot, traversedNodes.peekFirst(), filterKey, values);
+
+ }
+
+ @Override
+ public void enterSelectFilter(AAIDslParser.SelectFilterContext ctx) {
+
+ List<AAIDslParser.KeyContext> keyList = ctx.key();
+
+ boolean isNot = ctx.not() != null && !ctx.not().isEmpty();
+
+ /*
+ * Add all String values
+ */
+ List<String> allKeys = keyList.stream().map(keyValue -> "'" + keyValue.getText().replace("'", "") + "'").collect(Collectors.toList());
+ if (allKeys != null && !allKeys.isEmpty()){
+ setSelectKeys(traversedNodes.getFirst(), allKeys);
+ }
+ if (isAggregate() && (traversedNodes.size() == nodeCount)) {
+ builder().select(isNot, selectCounter++, allKeys);
+ }
+ }
+
+ public boolean isValidationFlag() {
+ return validationFlag;
+ }
+
+ public void setValidationFlag(boolean validationFlag) {
+ this.validationFlag = validationFlag;
+ }
+
+ public void setAggregateFlag(boolean isAggregate) {
+ this.isAggregate = isAggregate;
+ }
+
+ public boolean isAggregate(){
+ return this.isAggregate;
+ }
+
+ public void setQueryValidator(DslValidator queryValidator, String validationRules) {
+ this.queryValidator = Optional.of(queryValidator);
+ this.validationRules = validationRules;
+ }
+ public String getValidationRules() {
+ return validationRules;
+ }
+
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslQueryValidator.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslQueryValidator.java
new file mode 100644
index 0000000..53f2c72
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslQueryValidator.java
@@ -0,0 +1,62 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2018-2019 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.dsl.validation;
+
+import org.onap.aai.util.AAIConfig;
+import org.onap.aai.util.TraversalConstants;
+
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Set;
+
+public class DslQueryValidator extends DslValidator {
+
+ protected DslQueryValidator(Builder builder) {
+ super(builder);
+ }
+
+ public boolean validate(DslValidatorRule dslValidatorRule) {
+
+ return validateLoop(dslValidatorRule.isValidateLoop(), dslValidatorRule.getEdges()) && validateNodeCount(dslValidatorRule.isValidateNodeCount(), dslValidatorRule.getNodeCount());
+ }
+
+ private boolean validateLoop(boolean isValidateLoop, List<String> edges) {
+ if (isValidateLoop) {
+ Set<String> uniqueEdges = new LinkedHashSet<>(edges);
+
+ if (uniqueEdges.size() < (edges.size() / 2)) {
+ this.errorMessage.append("Loop Validation failed");
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean validateNodeCount(boolean isValidateNodeCount, int nodeCount) {
+ String maxNodeString = AAIConfig.get("aai.dsl.max.nodecount", TraversalConstants.DSL_MAX_NODE_COUNT);
+ int maxNodeCount = Integer.parseInt(maxNodeString);
+ if (isValidateNodeCount && nodeCount > maxNodeCount) {
+ this.errorMessage.append("NodeCount Validation failed");
+ return false;
+ }
+ return true;
+ }
+
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslSchemaValidator.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslSchemaValidator.java
new file mode 100644
index 0000000..54a2feb
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslSchemaValidator.java
@@ -0,0 +1,32 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2018-2019 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.dsl.validation;
+
+public class DslSchemaValidator extends DslValidator {
+
+ protected DslSchemaValidator(Builder builder) {
+ super(builder);
+ }
+
+ public boolean validate(DslValidatorRule dslValidatorRule) {
+ return true;
+ }
+
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslValidator.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslValidator.java
new file mode 100644
index 0000000..128f8a8
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslValidator.java
@@ -0,0 +1,58 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2018-2019 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.dsl.validation;
+
+import org.onap.aai.exceptions.AAIException;
+
+public abstract class DslValidator {
+ protected StringBuilder errorMessage = new StringBuilder("");
+
+
+ protected DslValidator(DslValidator.Builder builder) {
+
+ }
+
+ public abstract boolean validate(DslValidatorRule dslValidatorRule) throws AAIException;
+
+ public String getErrorMessage() {
+ return errorMessage.toString();
+ }
+
+ public static class Builder {
+
+ boolean isSchemaValidation = false;
+
+ public Builder schema() {
+ this.setSchemaValidation(true);
+ return this;
+ }
+
+ private void setSchemaValidation(boolean schemaValidation) {
+ isSchemaValidation = schemaValidation;
+ }
+
+ public DslValidator create() {
+ if (isSchemaValidation) {
+ return new DslSchemaValidator(this);
+ }
+ return new DslQueryValidator(this);
+ }
+ }
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslValidatorRule.java b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslValidatorRule.java
new file mode 100644
index 0000000..54d45bd
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/dsl/validation/DslValidatorRule.java
@@ -0,0 +1,141 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2018-2019 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.dsl.validation;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class DslValidatorRule {
+
+ private static final String LOOP_RULE = "loop";
+ private static final String NODECOUNT_RULE = "nodeCount";
+ private static final String ALL_RULE = "all";
+
+ private String query;
+ private boolean validateLoop;
+ private boolean validateNodeCount;
+ private int nodeCount;
+ private List<String> edges;
+
+ protected DslValidatorRule(DslValidatorRule.Builder builder) {
+ query = builder.query;
+ validateLoop = builder.validateLoop;
+ validateNodeCount = builder.validateNodeCount;
+ nodeCount = builder.nodeCount;
+ edges = builder.getEdges();
+ }
+
+ public String getQuery() {
+ return query;
+ }
+
+ public void setQuery(String query) {
+ this.query = query;
+ }
+
+ public boolean isValidateLoop() {
+ return validateLoop;
+ }
+
+ public void setValidateLoop(boolean validateLoop) {
+ this.validateLoop = validateLoop;
+ }
+
+ public boolean isValidateNodeCount() {
+ return validateNodeCount;
+ }
+
+ public void setValidateNodeCount(boolean validateNodeCount) {
+ this.validateNodeCount = validateNodeCount;
+ }
+
+ public int getNodeCount() {
+ return nodeCount;
+ }
+
+ public void setNodeCount(int nodeCount) {
+ this.nodeCount = nodeCount;
+ }
+
+ public List<String> getEdges() {
+ return edges;
+ }
+
+ public void setEdges(List<String> edges) {
+ this.edges = edges;
+ }
+
+ public static class Builder {
+
+ //todo optional
+ String query = "";
+ boolean validateLoop = false;
+ boolean validateNodeCount = false;
+ int nodeCount = 0;
+ List<String> edges = new LinkedList<>();
+
+ public List<String> getEdges() {
+ return edges;
+ }
+
+ public void setEdges(List<String> edges) {
+ this.edges = edges;
+ }
+
+ public Builder query(String query) {
+ this.setQuery(query);
+ return this;
+ }
+
+ public Builder loop(String validateLoop, List<String> edges) {
+ if (validateLoop.contains(LOOP_RULE) || validateLoop.contains(ALL_RULE)) {
+ this.setValidateLoop(true);
+ this.setEdges(edges);
+ }
+
+ return this;
+ }
+
+ public Builder nodeCount(String validateNodeCount, int nodeCount) {
+ if (validateNodeCount.contains(NODECOUNT_RULE) || validateNodeCount.contains(ALL_RULE)) {
+ this.setValidateNodeCount(true);
+ this.nodeCount = nodeCount;
+ }
+ return this;
+ }
+
+ private void setQuery(String query) {
+ this.query = query;
+ }
+
+ private void setValidateLoop(boolean validateLoop) {
+ this.validateLoop = validateLoop;
+ }
+
+ private void setValidateNodeCount(boolean validateNodeCount) {
+ this.validateNodeCount = validateNodeCount;
+ }
+
+ public DslValidatorRule build() {
+
+ return new DslValidatorRule(this);
+ }
+ }
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/enums/EdgeDirection.java b/aai-traversal/src/main/java/org/onap/aai/rest/enums/EdgeDirection.java
new file mode 100644
index 0000000..61f35ac
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/enums/EdgeDirection.java
@@ -0,0 +1,48 @@
+/**
+ * ============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.enums;
+
+public enum EdgeDirection {
+ OUT(">>"),
+ IN("<<"),
+ BOTH(">");
+
+
+ private final String value;
+
+ private EdgeDirection(String value) {
+ this.value = value;
+ }
+
+
+ public static EdgeDirection fromValue(String value) {
+
+ for (EdgeDirection d : values()) {
+ if (d.value.equals(value)) {
+ return d;
+ }
+ }
+ return BOTH;
+ }
+ @Override
+ public String toString() {
+ return value;
+ }
+} \ No newline at end of file
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/enums/QueryVersion.java b/aai-traversal/src/main/java/org/onap/aai/rest/enums/QueryVersion.java
new file mode 100644
index 0000000..0e30f28
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/enums/QueryVersion.java
@@ -0,0 +1,25 @@
+/**
+ * ============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.enums;
+
+public enum QueryVersion {
+ V1,
+ V2;
+} \ No newline at end of file
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 56b748c..8e62900 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
@@ -19,10 +19,12 @@
*/
package org.onap.aai.rest.search;
-import com.att.eelf.configuration.EELFLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.att.eelf.configuration.EELFManager;
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.Vertex;
@@ -30,9 +32,12 @@ import org.javatuples.Pair;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.query.builder.MissingOptionalParameter;
import org.onap.aai.rest.dsl.DslQueryProcessor;
+import org.onap.aai.rest.enums.QueryVersion;
import org.onap.aai.restcore.search.GroovyQueryBuilder;
import org.onap.aai.restcore.util.URITools;
+import org.onap.aai.serialization.engines.QueryStyle;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+import org.onap.aai.serialization.queryformats.Format;
import org.onap.aai.serialization.queryformats.SubGraphStyle;
import javax.ws.rs.core.MultivaluedHashMap;
@@ -45,7 +50,7 @@ import java.util.regex.Pattern;
public abstract class GenericQueryProcessor {
- private static EELFLogger LOGGER = EELFManager.getInstance().getLogger(GenericQueryProcessor.class);
+ private static Logger LOGGER = LoggerFactory.getLogger(GenericQueryProcessor.class);
protected final Optional<URI> uri;
protected final MultivaluedMap<String, String> queryParams;
@@ -57,11 +62,27 @@ public abstract class GenericQueryProcessor {
protected GroovyQueryBuilder groovyQueryBuilder = new GroovyQueryBuilder();
protected final boolean isGremlin;
protected Optional<DslQueryProcessor> dslQueryProcessorOptional;
+
+ public Map<String, List<String>> getPropertiesMap() {
+ return propertiesList;
+ }
+
+ public void setPropertiesMap(Map<String, List<String>> propertiesMap) {
+ this.propertiesList = propertiesMap;
+ }
+
+ private Map<String, List<String>> propertiesList;
/* dsl parameters to store dsl query and to check
+
* if this is a DSL request
*/
protected Optional<String> dsl;
protected final boolean isDsl ;
+ protected boolean isHistory;
+ protected GraphTraversalSource traversalSource;
+ protected QueryStyle style;
+ protected QueryVersion dslApiVersion;
+ protected Format format;
protected GenericQueryProcessor(Builder builder) {
this.uri = builder.getUri();
@@ -73,16 +94,23 @@ public abstract class GenericQueryProcessor {
this.isDsl = builder.isDsl();
this.gremlinServerSingleton = builder.getGremlinServerSingleton();
this.dslQueryProcessorOptional = builder.getDslQueryProcessor();
+ this.dslApiVersion = builder.getDslApiVersion();
if (uri.isPresent()) {
queryParams = URITools.getQueryMap(uri.get());
+ } else if (builder.getUriParams() != null) {
+ queryParams = builder.getUriParams();
} else {
queryParams = new MultivaluedHashMap<>();
}
+ this.traversalSource = builder.getTraversalSource();
+ this.style = builder.getStyle();
+ this.isHistory = builder.isHistory();
+ this.format = builder.getFormat();
}
- protected abstract GraphTraversal<?,?> runQuery(String query, Map<String, Object> params);
-
+ protected abstract GraphTraversal<?,?> runQuery(String query, Map<String, Object> params, GraphTraversalSource traversalSource);
+
protected List<Object> processSubGraph(SubGraphStyle style, GraphTraversal<?,?> g) {
final List<Object> resultVertices = new Vector<>();
g.store("y");
@@ -106,18 +134,45 @@ public abstract class GenericQueryProcessor {
Pair<String, Map<String, Object>> tuple = this.createQuery();
String query = tuple.getValue0();
+ if (queryParams.containsKey("as-tree")) {
+ if (queryParams.getFirst("as-tree").equalsIgnoreCase("true")) {
+ if (this.isDsl) { // If dsl query and as-tree parameter is true, remove "end" concatenation and append tree.
+ query = removeDslQueryEnd(query);
+ }
+ query = query.concat(".tree()"); // Otherwise, normal gremlin query will just append tree
+ }
+ }
Map<String, Object> params = tuple.getValue1();
if (query.equals("") && (vertices.isPresent() && vertices.get().isEmpty())) {
//nothing to do, just exit
return new ArrayList<>();
}
- GraphTraversal<?,?> g = this.runQuery(query, params);
+ GraphTraversal<?,?> g = this.runQuery(query, params, traversalSource);
resultVertices = this.processSubGraph(style, g);
return resultVertices;
}
+
+ private String removeDslQueryEnd(String query) {
+ String end = ".cap('x').unfold().dedup()";
+ if (query.length() <= end.length()) {
+ return query;
+ }
+ if (query.contains(end)) {
+ int startIndex = query.length() - end.length();
+ for (int i = 0; startIndex - i >= 0; i++) { // remove tailing instance
+ startIndex = query.length() - end.length() - i;
+ int lastIndex = query.length() - i;
+ if (query.substring(startIndex, lastIndex).equals(end)) {
+ query = query.substring(0, startIndex) + query.substring(lastIndex);
+ break;
+ }
+ }
+ }
+ return query;
+ }
protected Pair<String, Map<String, Object>> createQuery() throws AAIException {
Map<String, Object> params = new HashMap<>();
@@ -128,8 +183,15 @@ public abstract class GenericQueryProcessor {
}else if (this.isDsl) {
String dslUserQuery = dsl.get();
if(dslQueryProcessorOptional.isPresent()){
- String dslQuery = dslQueryProcessorOptional.get().parseAaiQuery(dslUserQuery);
- query = groovyQueryBuilder.executeTraversal(dbEngine, dslQuery, params);
+ Map<String, Object>resultMap = dslQueryProcessorOptional.get().parseAaiQuery(dslApiVersion, dslUserQuery);
+ String dslQuery = resultMap.get("query").toString();
+ Object propMap = resultMap.get("propertiesMap");
+ if (propMap instanceof Map) {
+ Map<String, List<String>> newPropMap = new HashMap<String, List<String>>();
+ newPropMap = (Map<String, List<String>>)propMap;
+ setPropertiesMap(newPropMap);
+ }
+ query = groovyQueryBuilder.executeTraversal(dbEngine, dslQuery, params, style, traversalSource);
String startPrefix = "g.V()";
query = startPrefix + query;
}
@@ -178,7 +240,7 @@ public abstract class GenericQueryProcessor {
if (query == null) {
query = "";
} else {
- query = groovyQueryBuilder.executeTraversal(dbEngine, query, params);
+ query = groovyQueryBuilder.executeTraversal(dbEngine, query, params, style, traversalSource);
}
String startPrefix = "g.V(startVertexes)";
@@ -227,7 +289,14 @@ public abstract class GenericQueryProcessor {
private GremlinServerSingleton gremlinServerSingleton;
private Optional<String> nodeType = Optional.empty();
private boolean isNodeTypeQuery = false;
- protected MultivaluedMap<String, String> uriParams;
+ protected MultivaluedMap<String, String> uriParams;
+ protected GraphTraversalSource traversalSource;
+ protected boolean isHistory = false;
+ protected QueryVersion dslApiVersion;
+ protected Format format;
+
+
+ protected QueryStyle style = QueryStyle.GREMLIN_TRAVERSAL;
public Builder(TransactionalGraphEngine dbEngine, GremlinServerSingleton gremlinServerSingleton) {
this.dbEngine = dbEngine;
@@ -272,11 +341,31 @@ public abstract class GenericQueryProcessor {
return this;
}
+ public Builder format(Format format) {
+ this.format = format;
+ return this;
+ }
+
+ public Builder traversalSource(boolean isHistory, GraphTraversalSource source) {
+ this.traversalSource = source;
+ this.isHistory = isHistory;
+ if(this.isHistory){
+ this.style = QueryStyle.HISTORY_GREMLIN_TRAVERSAL;
+ }
+
+ return this;
+ }
+
public Builder queryProcessor(DslQueryProcessor dslQueryProcessor){
this.dslQueryProcessor = dslQueryProcessor;
return this;
}
+ public Builder version(QueryVersion version){
+ this.dslApiVersion = version;
+ return this;
+ }
+
public Optional<DslQueryProcessor> getDslQueryProcessor(){
return Optional.ofNullable(this.dslQueryProcessor);
}
@@ -288,6 +377,8 @@ public abstract class GenericQueryProcessor {
return uri;
}
+ public MultivaluedMap<String, String> getUriParams() { return uriParams; }
+
public Optional<String> getGremlin() {
return gremlin;
}
@@ -330,6 +421,40 @@ public abstract class GenericQueryProcessor {
}
return new GroovyShellImpl(this);
}
+
+ public GraphTraversalSource getTraversalSource() {
+ return traversalSource;
+ }
+
+ public void setTraversalSource(GraphTraversalSource traversalSource) {
+ this.traversalSource = traversalSource;
+ }
+
+ public boolean isHistory() {
+ return isHistory;
+ }
+
+ public void setHistory(boolean history) {
+ isHistory = history;
+ }
+
+ public QueryStyle getStyle() {
+ return style;
+ }
+
+ public void setStyle(QueryStyle style) {
+ this.style = style;
+ }
+
+ public QueryVersion getDslApiVersion() {
+ return dslApiVersion;
+ }
+
+ public void setDslApiVersion(QueryVersion dslApiVersion) {
+ this.dslApiVersion = dslApiVersion;
+ }
+
+ public Format getFormat(){ return this.format; }
}
}
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 9ae3dec..e30f13f 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
@@ -21,8 +21,8 @@ package org.onap.aai.rest.search;
import org.onap.aai.logging.LogFormatTools;
import org.onap.aai.util.AAIConstants;
-import org.onap.aai.util.FileWatcher;
-import com.att.eelf.configuration.EELFLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.att.eelf.configuration.EELFManager;
import org.apache.tinkerpop.gremlin.driver.Cluster;
import org.springframework.beans.factory.annotation.Autowired;
@@ -43,7 +43,7 @@ import java.util.TimerTask;
public class GremlinServerSingleton {
- private static EELFLogger logger = EELFManager.getInstance().getLogger(GremlinServerSingleton.class);
+ private static Logger logger = LoggerFactory.getLogger(GremlinServerSingleton.class);
private boolean timerSet;
private Timer timer;
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 712d7f0..340c525 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,13 @@ import java.util.Map;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
+import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
+import org.onap.aai.aailog.logs.AaiDBTraversalMetricLog;
import org.onap.aai.restcore.search.GremlinGroovyShell;
+import org.onap.aai.restcore.util.URITools;
+import org.onap.aai.util.AAIConstants;
+
+import javax.ws.rs.core.MultivaluedHashMap;
public class GroovyShellImpl extends GenericQueryProcessor {
@@ -32,13 +38,17 @@ public class GroovyShellImpl extends GenericQueryProcessor {
}
@Override
- protected GraphTraversal<?,?> runQuery(String query, Map<String, Object> params) {
+ protected GraphTraversal<?,?> runQuery(String query, Map<String, Object> params, GraphTraversalSource traversalSource) {
- params.put("g", this.dbEngine.asAdmin().getTraversalSource());
-
+ AaiDBTraversalMetricLog metricLog = new AaiDBTraversalMetricLog (AAIConstants.AAI_TRAVERSAL_MS);
+ metricLog.pre(uri);
+
+ params.put("g", traversalSource);
GremlinGroovyShell shell = new GremlinGroovyShell();
-
- return shell.executeTraversal(query, params);
+ GraphTraversal<?,?> graphTraversal = shell.executeTraversal(query, params);
+
+ metricLog.post();
+ return graphTraversal;
}
}
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
index bcd4c4e..52957d4 100644
--- 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
@@ -19,11 +19,14 @@
*/
package org.onap.aai.rest.search;
-import com.att.eelf.configuration.EELFLogger;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.logging.ErrorLogHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.att.eelf.configuration.EELFManager;
+import org.onap.aai.aaf.auth.FileWatcher;
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;
@@ -37,7 +40,7 @@ import java.util.Timer;
import java.util.TimerTask;
public class LocalCQConfig extends CQConfig {
- private static EELFLogger logger = EELFManager.getInstance().getLogger(LocalCQConfig.class);
+ private static Logger logger = LoggerFactory.getLogger(LocalCQConfig.class);
@Value("${schema.queries.location}")
private String storedQueriesLocation;
@@ -56,7 +59,9 @@ public class LocalCQConfig extends CQConfig {
queryConfig = new GetCustomQueryConfig(customQueryConfigJson);
} catch (IOException e) {
- logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e));
+ AAIException aaiException = new AAIException("AAI_4002", e);
+ ErrorLogHelper.logException(aaiException);
+ //logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e));
}
TimerTask task = new FileWatcher(new File(storedQueriesLocation)) {
@@ -69,7 +74,9 @@ public class LocalCQConfig extends CQConfig {
queryConfig = new GetCustomQueryConfig(customQueryConfigJson);
} catch (IOException e) {
- logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e));
+ AAIException aaiException = new AAIException("AAI_4002", e);
+ ErrorLogHelper.logException(aaiException);
+ //logger.error("Error occurred during the processing of query json file: " + LogFormatTools.getStackTop(e));
}
}
};
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/search/ModelAndNamedQueryRestProvider.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/ModelAndNamedQueryRestProvider.java
index 4102c52..e590964 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/search/ModelAndNamedQueryRestProvider.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/ModelAndNamedQueryRestProvider.java
@@ -19,22 +19,21 @@
*/
package org.onap.aai.rest.search;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
+import org.onap.aai.aailog.logs.AaiDBTraversalMetricLog;
+import org.onap.aai.concurrent.AaiCallable;
import org.onap.aai.dbgraphmap.SearchGraph;
-import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.extensions.AAIExtensionMap;
import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.logging.LoggingContext;
-import org.onap.aai.logging.StopWatch;
+
+import org.onap.aai.rest.util.AAIExtensionMap;
import org.onap.aai.restcore.HttpMethod;
import org.onap.aai.restcore.RESTAPI;
import org.onap.aai.setup.SchemaVersions;
import org.onap.aai.util.AAIConstants;
import org.onap.aai.util.TraversalConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.onap.aai.concurrent.AaiCallable;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.POST;
@@ -43,8 +42,9 @@ import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.*;
import javax.ws.rs.core.Response.Status;
+import java.net.URI;
import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
+import java.util.Optional;
/**
* Implements the search subdomain in the REST API. All API calls must include
@@ -54,15 +54,13 @@ import java.util.concurrent.TimeUnit;
@Path("/search")
public class ModelAndNamedQueryRestProvider extends RESTAPI {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(ModelAndNamedQueryRestProvider.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(ModelAndNamedQueryRestProvider.class);
public static final String NAMED_QUERY = "/named-query";
public static final String MODEL_QUERY = "/model";
- public static final String TARGET_ENTITY = "DB";
-
private SearchGraph searchGraph;
private SchemaVersions schemaVersions;
@@ -107,19 +105,12 @@ public class ModelAndNamedQueryRestProvider extends RESTAPI {
public Response processNamedQueryResponse(@Context HttpHeaders headers,
@Context HttpServletRequest req,
String queryParameters) {
- String methodName = "getNamedQueryResponse";
AAIException ex = null;
- Response response = null;
- String fromAppId = null;
- String transId = null;
- double dbTimeMsecs = 0;
- String rqstTm = genDate();
- ArrayList<String> templateVars = new ArrayList<String>();
+ Response response;
+ String fromAppId;
+ String transId;
+ ArrayList<String> templateVars = new ArrayList<String>();
try {
- LoggingContext.save();
- LoggingContext.targetEntity(TARGET_ENTITY);
- LoggingContext.targetServiceName(methodName);
-
fromAppId = getFromAppId(headers);
transId = getTransId(headers);
@@ -127,29 +118,25 @@ public class ModelAndNamedQueryRestProvider extends RESTAPI {
aaiExtMap.setHttpHeaders(headers);
aaiExtMap.setServletRequest(req);
aaiExtMap.setApiVersion(schemaVersions.getDefaultVersion().toString());
- String realTime = headers.getRequestHeaders().getFirst("Real-Time");
- //only consider header value for search
- DBConnectionType type = this.determineConnectionType("force-cache", realTime);
-
- LoggingContext.startTime();
- StopWatch.conditionalStart();
-
- response = searchGraph.runNamedQuery(fromAppId, transId, queryParameters, type, aaiExtMap);
-
- dbTimeMsecs += StopWatch.stopIfStarted();
- LoggingContext.elapsedTime((long)dbTimeMsecs,TimeUnit.MILLISECONDS);
- LoggingContext.successStatusFields();
-
-
- LOGGER.info ("Completed");
-
- LoggingContext.restoreIfPossible();
- LoggingContext.successStatusFields();
-
- String respTm = genDate();
+ //only consider header value for search
+
+
+ AaiDBTraversalMetricLog metricLog = new AaiDBTraversalMetricLog (AAIConstants.AAI_TRAVERSAL_MS);
+ String uriString = req.getRequestURI();
+ Optional<URI> o;
+ if (uriString != null) {
+ o = Optional.of(new URI(uriString));
+ }
+ else {
+ o = Optional.empty();
+ }
+ metricLog.pre(o);
+
+ response = searchGraph.runNamedQuery(fromAppId, transId, queryParameters, aaiExtMap);
+ metricLog.post();
+ //LOGGER.info ("Completed");
} catch (AAIException e) {
- LoggingContext.restoreIfPossible();
// send error response
ex = e;
templateVars.add("POST Search");
@@ -159,7 +146,6 @@ public class ModelAndNamedQueryRestProvider extends RESTAPI {
.entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
.build();
} catch (Exception e) {
- LoggingContext.restoreIfPossible();
// send error response
ex = new AAIException("AAI_4000", e);
templateVars.add("POST Search");
@@ -214,20 +200,13 @@ public class ModelAndNamedQueryRestProvider extends RESTAPI {
@Context HttpServletRequest req,
String inboundPayload,
@QueryParam("action") String action) {
- String methodName = "getModelQueryResponse";
AAIException ex = null;
- Response response = null;
- String fromAppId = null;
- String transId = null;
- double dbTimeMsecs = 0;
-
- String rqstTm = genDate();
- ArrayList<String> templateVars = new ArrayList<String>();
+ Response response;
+ String fromAppId;
+ String transId;
+
+ ArrayList<String> templateVars = new ArrayList<>();
try {
- LoggingContext.save();
- LoggingContext.targetEntity(TARGET_ENTITY);
- LoggingContext.targetServiceName(methodName);
-
fromAppId = getFromAppId(headers);
transId = getTransId(headers);
@@ -238,30 +217,28 @@ public class ModelAndNamedQueryRestProvider extends RESTAPI {
aaiExtMap.setFromAppId(fromAppId);
aaiExtMap.setTransId(transId);
- String realTime = headers.getRequestHeaders().getFirst("Real-Time");
- //only consider header value for search
- DBConnectionType type = this.determineConnectionType("force-cache", realTime);
-
- LoggingContext.startTime();
- StopWatch.conditionalStart();
-
+ //only consider header value for search
+
+
+ AaiDBTraversalMetricLog metricLog = new AaiDBTraversalMetricLog (AAIConstants.AAI_TRAVERSAL_MS);
+ String uriString = req.getRequestURI();
+ Optional<URI> o;
+ if (uriString != null) {
+ o = Optional.of(new URI(uriString));
+ }
+ else {
+ o = Optional.empty();
+ }
+ metricLog.pre(o);
if (action != null && action.equalsIgnoreCase("DELETE")) {
- response = searchGraph.executeModelOperation(fromAppId, transId, inboundPayload, type, true, aaiExtMap);
+ response = searchGraph.executeModelOperation(fromAppId, transId, inboundPayload, true, aaiExtMap);
} else {
- response = searchGraph.executeModelOperation(fromAppId, transId, inboundPayload, type, false, aaiExtMap);
+ response = searchGraph.executeModelOperation(fromAppId, transId, inboundPayload, false, aaiExtMap);
}
- dbTimeMsecs += StopWatch.stopIfStarted();
- LoggingContext.elapsedTime((long)dbTimeMsecs,TimeUnit.MILLISECONDS);
- LoggingContext.successStatusFields();
-
- LOGGER.info ("Completed");
-
- LoggingContext.restoreIfPossible();
- LoggingContext.successStatusFields();
- String respTm = genDate();
-
+ metricLog.post();
+ //LOGGER.info ("Completed");
+
} catch (AAIException e) {
- LoggingContext.restoreIfPossible();
// send error response
ex = e;
templateVars.add("POST Search");
@@ -271,7 +248,6 @@ public class ModelAndNamedQueryRestProvider extends RESTAPI {
.entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
.build();
} catch (Exception e) {
- LoggingContext.restoreIfPossible();
// send error response
ex = new AAIException("AAI_4000", e);
templateVars.add("POST Search");
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 6421f67..61f370b 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
@@ -19,7 +19,8 @@
*/
package org.onap.aai.rest.search;
-import com.att.eelf.configuration.EELFLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.att.eelf.configuration.EELFManager;
import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
@@ -41,7 +42,7 @@ import javax.ws.rs.core.MultivaluedMap;
public class NodeQueryProcessor extends GroovyShellImpl {
- private static EELFLogger LOGGER = EELFManager.getInstance().getLogger(NodeQueryProcessor.class);
+ private static Logger LOGGER = LoggerFactory.getLogger(NodeQueryProcessor.class);
protected String nodeType;
private MultivaluedMap<String, String> nodeQueryParams = new MultivaluedHashMap<String, String>();
@@ -106,7 +107,7 @@ public class NodeQueryProcessor extends GroovyShellImpl {
// nothing to do, just exit
return new ArrayList<>();
}
- GraphTraversal<?, ?> g = this.runQuery(query, params);
+ GraphTraversal<?, ?> g = this.runQuery(query, params, dbEngine.asAdmin().getTraversalSource());
resultVertices.addAll(g.toList());
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
index 6e55246..ea1b62f 100644
--- 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
@@ -19,12 +19,13 @@
*/
package org.onap.aai.rest.search;
-import com.att.eelf.configuration.EELFLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
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.beans.factory.annotation.Qualifier;
import org.springframework.http.ResponseEntity;
import javax.annotation.PostConstruct;
@@ -33,14 +34,15 @@ import java.util.Map;
public class SchemaServiceCQConfig extends CQConfig {
- private static EELFLogger logger = EELFManager.getInstance().getLogger(SchemaServiceCQConfig.class);
+ private static Logger logger = LoggerFactory.getLogger(SchemaServiceCQConfig.class);
private static final String SCHEMA_SERVICE = "schema-service";
@Value("${schema.service.custom.queries.endpoint}")
private String customQueriesUri;
+ @Qualifier("restClient")
@Autowired
- private RestClientFactory restClientFactory;
+ private RestClient restClient;
@PostConstruct
public void initialize() {
@@ -55,8 +57,6 @@ public class SchemaServiceCQConfig extends CQConfig {
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/rest/search/SearchProvider.java b/aai-traversal/src/main/java/org/onap/aai/rest/search/SearchProvider.java
index 8c97c0a..75a19c9 100644
--- a/aai-traversal/src/main/java/org/onap/aai/rest/search/SearchProvider.java
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/search/SearchProvider.java
@@ -19,48 +19,41 @@
*/
package org.onap.aai.rest.search;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.GET;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.HttpHeaders;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import javax.ws.rs.core.Response.Status;
-import javax.ws.rs.core.UriInfo;
+import org.onap.aai.aailog.logs.AaiDBTraversalMetricLog;
+import org.onap.aai.concurrent.AaiCallable;
import org.onap.aai.dbgraphmap.SearchGraph;
-import org.onap.aai.dbmap.DBConnectionType;
import org.onap.aai.exceptions.AAIException;
import org.onap.aai.introspection.Loader;
import org.onap.aai.introspection.LoaderFactory;
import org.onap.aai.introspection.ModelType;
import org.onap.aai.logging.ErrorLogHelper;
-import org.onap.aai.logging.LoggingContext;
-import org.onap.aai.logging.StopWatch;
import org.onap.aai.restcore.HttpMethod;
import org.onap.aai.restcore.RESTAPI;
import org.onap.aai.serialization.db.DBSerializer;
-import org.onap.aai.serialization.engines.QueryStyle;
import org.onap.aai.serialization.engines.JanusGraphDBEngine;
+import org.onap.aai.serialization.engines.QueryStyle;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
import org.onap.aai.serialization.queryformats.utils.UrlBuilder;
import org.onap.aai.setup.SchemaVersion;
import org.onap.aai.setup.SchemaVersions;
+import org.onap.aai.util.AAIConstants;
import org.onap.aai.util.GenericQueryBuilder;
import org.onap.aai.util.NodesQueryBuilder;
import org.onap.aai.util.TraversalConstants;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
-import org.onap.aai.concurrent.AaiCallable;
-import com.att.eelf.configuration.EELFLogger;
-import com.att.eelf.configuration.EELFManager;
import org.springframework.beans.factory.annotation.Value;
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.*;
+import javax.ws.rs.core.*;
+import javax.ws.rs.core.Response.Status;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
/**
* Implements the search subdomain in the REST API. All API calls must include X-FromAppId and
* X-TransactionId in the header.
@@ -68,14 +61,12 @@ import org.springframework.beans.factory.annotation.Value;
@Path("/{version: v[1-9][0-9]*|latest}/search")
public class SearchProvider extends RESTAPI {
- private static final EELFLogger LOGGER = EELFManager.getInstance().getLogger(SearchProvider.class);
+ private static final Logger LOGGER = LoggerFactory.getLogger(SearchProvider.class);
public static final String GENERIC_QUERY = "/generic-query";
public static final String NODES_QUERY = "/nodes-query";
- public static final String TARGET_ENTITY = "DB";
-
private SearchGraph searchGraph;
private LoaderFactory loaderFactory;
@@ -130,51 +121,37 @@ public class SearchProvider extends RESTAPI {
@QueryParam("include") final List<String> includeNodeTypes, @QueryParam("depth") final int depth,
@PathParam("version") String versionParam) {
- String methodName = "getGenericQueryResponse";
AAIException ex = null;
- Response searchResult = null;
- String fromAppId = null;
- String transId = null;
- String rqstTm = genDate();
- ArrayList<String> templateVars = new ArrayList<String>();
- double dbTimeMsecs = 0;
+ Response searchResult;
+ String fromAppId;
+ ArrayList<String> templateVars = new ArrayList<>();
try {
- LoggingContext.save();
- LoggingContext.targetEntity(TARGET_ENTITY);
- LoggingContext.targetServiceName(methodName);
fromAppId = getFromAppId(headers);
- transId = getTransId(headers);
- String realTime = headers.getRequestHeaders().getFirst("Real-Time");
+ getTransId(headers);
// only consider header value for search
- DBConnectionType type = this.determineConnectionType("force-cache", realTime);
final SchemaVersion version = new SchemaVersion(versionParam);
final ModelType factoryType = ModelType.MOXY;
Loader loader = loaderFactory.createLoaderForVersion(factoryType, version);
- TransactionalGraphEngine dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, type, loader);
+ TransactionalGraphEngine dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, loader);
DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer, schemaVersions, this.basePath);
- LoggingContext.startTime();
- StopWatch.conditionalStart();
+
+ AaiDBTraversalMetricLog metricLog = new AaiDBTraversalMetricLog (AAIConstants.AAI_TRAVERSAL_MS);
+ metricLog.pre(Optional.of(new URI(req.getRequestURI())));
+
searchResult = searchGraph
.runGenericQuery(new GenericQueryBuilder().setHeaders(headers).setStartNodeType(startNodeType)
.setStartNodeKeyParams(startNodeKeyParams).setIncludeNodeTypes(includeNodeTypes)
.setDepth(depth).setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder));
- dbTimeMsecs += StopWatch.stopIfStarted();
-
- LoggingContext.successStatusFields();
- LoggingContext.elapsedTime((long) dbTimeMsecs, TimeUnit.MILLISECONDS);
- LOGGER.info("Completed");
- LoggingContext.restoreIfPossible();
- LoggingContext.successStatusFields();
+ metricLog.post();
- String respTm = genDate();
+ //LOGGER.info("Completed");
} catch (AAIException e) {
- LoggingContext.restoreIfPossible();
// send error response
ex = e;
templateVars.add("GET Search");
@@ -183,7 +160,6 @@ public class SearchProvider extends RESTAPI {
.entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
.build();
} catch (Exception e) {
- LoggingContext.restoreIfPossible();
// send error response
ex = new AAIException("AAI_4000", e);
templateVars.add("GET Search");
@@ -239,50 +215,37 @@ public class SearchProvider extends RESTAPI {
@QueryParam("search-node-type") final String searchNodeType,
@QueryParam("edge-filter") final List<String> edgeFilterList,
@QueryParam("filter") final List<String> filterList, @PathParam("version") String versionParam) {
- String methodName = "getNodesQueryResponse";
+
AAIException ex = null;
- Response searchResult = null;
- String fromAppId = null;
- String transId = null;
- String rqstTm = genDate();
- ArrayList<String> templateVars = new ArrayList<String>();
- double dbTimeMsecs = 0;
+ Response searchResult;
+ String fromAppId;
+ ArrayList<String> templateVars = new ArrayList<>();
try {
- LoggingContext.save();
- LoggingContext.targetEntity(TARGET_ENTITY);
- LoggingContext.targetServiceName(methodName);
fromAppId = getFromAppId(headers);
- transId = getTransId(headers);
+ getTransId(headers);
String realTime = headers.getRequestHeaders().getFirst("Real-Time");
// only consider header value for search
- DBConnectionType type = this.determineConnectionType("force-cache", realTime);
final SchemaVersion version = new SchemaVersion(versionParam);
final ModelType factoryType = ModelType.MOXY;
Loader loader = loaderFactory.createLoaderForVersion(factoryType, version);
- TransactionalGraphEngine dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, type, loader);
+ TransactionalGraphEngine dbEngine = new JanusGraphDBEngine(QueryStyle.TRAVERSAL, loader);
DBSerializer dbSerializer = new DBSerializer(version, dbEngine, factoryType, fromAppId);
UrlBuilder urlBuilder = new UrlBuilder(version, dbSerializer, schemaVersions, this.basePath);
- LoggingContext.startTime();
- StopWatch.conditionalStart();
+
+ AaiDBTraversalMetricLog metricLog = new AaiDBTraversalMetricLog (AAIConstants.AAI_TRAVERSAL_MS);
+ metricLog.pre(Optional.of(new URI(req.getRequestURI())));
searchResult = searchGraph.runNodesQuery(new NodesQueryBuilder().setHeaders(headers)
.setTargetNodeType(searchNodeType).setEdgeFilterParams(edgeFilterList).setFilterParams(filterList)
.setDbEngine(dbEngine).setLoader(loader).setUrlBuilder(urlBuilder));
- dbTimeMsecs += StopWatch.stopIfStarted();
- LoggingContext.elapsedTime((long) dbTimeMsecs, TimeUnit.MILLISECONDS);
- LoggingContext.successStatusFields();
- LOGGER.info("Completed");
-
- LoggingContext.restoreIfPossible();
- LoggingContext.successStatusFields();
+ metricLog.post();
+ //LOGGER.info("Completed");
- String respTm = genDate();
} catch (AAIException e) {
- LoggingContext.restoreIfPossible();
// send error response
ex = e;
templateVars.add("GET Search");
@@ -291,7 +254,6 @@ public class SearchProvider extends RESTAPI {
.entity(ErrorLogHelper.getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), e, templateVars))
.build();
} catch (Exception e) {
- LoggingContext.restoreIfPossible();
// send error response
ex = new AAIException("AAI_4000", e);
templateVars.add("GET Search");
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/util/AAIExtensionMap.java b/aai-traversal/src/main/java/org/onap/aai/rest/util/AAIExtensionMap.java
new file mode 100644
index 0000000..0aa70e3
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/util/AAIExtensionMap.java
@@ -0,0 +1,826 @@
+/**
+ * ============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.util;
+
+import org.apache.tinkerpop.gremlin.structure.Graph;
+import org.apache.tinkerpop.gremlin.structure.Vertex;
+import org.eclipse.persistence.jaxb.dynamic.DynamicJAXBContext;
+import org.onap.aai.domain.responseMessage.AAIResponseMessages;
+import org.onap.aai.introspection.Loader;
+import org.onap.aai.rest.db.DBRequest;
+import org.onap.aai.rest.db.HttpEntry;
+import org.onap.aai.serialization.engines.TransactionalGraphEngine;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.HttpHeaders;
+import javax.ws.rs.core.UriInfo;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.HashMap;
+
+public class AAIExtensionMap {
+ // =======================================================================
+ // Attribute | Type
+ // =======================================================================
+ // message | java.lang.String (RW)
+ // ----------------------------------------------------------------------
+ // templateVars | java.lang.ArrayList<String> (RW)
+ // -----------------------------------------------------------------------
+ // preExtException | java.lang.Exception (RW)
+ // -----------------------------------------------------------------------
+ // preExtErrorCallback | java.lang.reflect.Method (RW)
+ // -----------------------------------------------------------------------
+ // postExtException | java.lang.Exception (RW)
+ // -----------------------------------------------------------------------
+ // postExtErrorCallback | java.lang.reflect.Method (RW)
+ // -----------------------------------------------------------------------
+ // servletRequest | javax.servlet.http.HttpServletRequest (RO)
+ // -----------------------------------------------------------------------
+ // headers | javax.ws.rs.core.HttpHeaders (RO)
+ // -----------------------------------------------------------------------
+ // objFromRequestType | String (ex. ?org.onap.aai.domain.yang.Vce?) (RO)
+ // -----------------------------------------------------------------------
+ // objFromRequest | $TYPE {ObjFromRequestType) (RO)
+ // -----------------------------------------------------------------------
+ // preExtFailOnError | java.lang.Boolean (RW)
+ // -----------------------------------------------------------------------
+ // postExtFailOnError | java.lang.Boolean (RW)
+ // -----------------------------------------------------------------------
+ // preExtSkipErrorCallback | java.lang.Boolean (RW)
+ // -----------------------------------------------------------------------
+ // postExtSkipErrorCallback | java.lang.Boolean (RW)
+ // -----------------------------------------------------------------------
+ // graph | org.janusgraph.core.JanusGraph (RW)
+ // -----------------------------------------------------------------------
+ // objectFromResponse | Object
+ // -----------------------------------------------------------------------
+ // precheckAddedList | java.util.HashMap
+ // -----------------------------------------------------------------------
+ // precheckResponseMessages | org.onap.aai.extensions.AAIResponseMessages
+ // =======================================================================
+
+ private String message;
+ private ArrayList<String> templateVars;
+ private Exception preExtException;
+ private Exception postExtException;
+ private Method preExtErrorCallback;
+ private Method postExtErrorCallback;
+ private HttpServletRequest servletRequest;
+ private HttpHeaders httpHeaders;
+ private String objectFromRequestType;
+ private Object objectFromRequest;
+ private boolean preExtFailOnError = true;
+ private boolean postExtFailOnError = true;
+ private boolean preExtSkipErrorCallback = true;
+ private boolean postExtSkipErrorCallback = true;
+ private String fromAppId;
+ private String transId;
+ private Graph graph;
+ private Object objectFromResponse;
+ private HashMap<String, Object> lookupHashMap;
+ private HashMap<String, ArrayList<String>> precheckAddedList;
+ private AAIResponseMessages precheckResponseMessages;
+ private HashMap<String, Object> topology;
+ private HashMap<String, Vertex> vertexCache;
+ private String baseObject;
+ private String namespace;
+ private String fullResourceName;
+ private String topObjectFullResourceName;
+ private String uri;
+ private String notificationUri;
+ private String apiVersion;
+ private long startTime;
+ private long checkpointTime;
+ private DynamicJAXBContext jaxbContext;
+ private String objectFromResponseType;
+ private String eventAction;
+ private TransactionalGraphEngine dbEngine;
+ private Loader loader;
+ private UriInfo uriInfo;
+ private DBRequest dbRequest;
+ private HttpEntry httpEntry;
+
+ /**
+ * Sets the message.
+ *
+ * @param _message the new message
+ */
+ public void setMessage(String _message) {
+ this.message = _message;
+ }
+
+ /**
+ * Sets the template vars.
+ *
+ * @param _templateVars the new template vars
+ */
+ public void setTemplateVars(ArrayList<String> _templateVars) {
+ this.templateVars = _templateVars;
+ }
+
+ /**
+ * Sets the pre ext exception.
+ *
+ * @param _exception the new pre ext exception
+ */
+ public void setPreExtException(Exception _exception) {
+ this.preExtException = _exception;
+ }
+
+ /**
+ * Sets the pre ext error callback.
+ *
+ * @param _errorCallback the new pre ext error callback
+ */
+ public void setPreExtErrorCallback(Method _errorCallback) {
+ this.preExtErrorCallback = _errorCallback;
+ }
+
+ /**
+ * Sets the post ext exception.
+ *
+ * @param _exception the new post ext exception
+ */
+ public void setPostExtException(Exception _exception) {
+ this.postExtException = _exception;
+ }
+
+ /**
+ * Sets the post ext error callback.
+ *
+ * @param _errorCallback the new post ext error callback
+ */
+ public void setPostExtErrorCallback(Method _errorCallback) {
+ this.postExtErrorCallback = _errorCallback;
+ }
+
+ /**
+ * Sets the servlet request.
+ *
+ * @param _httpServletRequest the new servlet request
+ */
+ public void setServletRequest(HttpServletRequest _httpServletRequest) {
+ this.servletRequest = _httpServletRequest;
+ }
+
+ /**
+ * Sets the http headers.
+ *
+ * @param _httpHeaders the new http headers
+ */
+ public void setHttpHeaders(HttpHeaders _httpHeaders) {
+ this.httpHeaders = _httpHeaders;
+ }
+
+ /**
+ * Sets the object from request type.
+ *
+ * @param _objectFromRequestType the new object from request type
+ */
+ public void setObjectFromRequestType(String _objectFromRequestType) {
+ this.objectFromRequestType = _objectFromRequestType;
+ }
+
+ /**
+ * Sets the object from request.
+ *
+ * @param _objectFromRequest the new object from request
+ */
+ public void setObjectFromRequest(Object _objectFromRequest) {
+ this.objectFromRequest = _objectFromRequest;
+ }
+
+ /**
+ * Sets the object from response type.
+ *
+ * @param resourceClassName the new object from response type
+ */
+ public void setObjectFromResponseType(String resourceClassName) {
+ // TODO Auto-generated method stub
+ this.objectFromResponseType = resourceClassName;
+ }
+
+ /**
+ * Gets the object from response type.
+ *
+ * @return the object from response type
+ */
+ public String getObjectFromResponseType() {
+ // TODO Auto-generated method stub
+ return this.objectFromResponseType;
+ }
+
+ /**
+ * Sets the pre ext fail on error.
+ *
+ * @param _failOnError the new pre ext fail on error
+ */
+ public void setPreExtFailOnError(boolean _failOnError) {
+ this.preExtFailOnError = _failOnError;
+ }
+
+ /**
+ * Sets the post ext fail on error.
+ *
+ * @param _failOnError the new post ext fail on error
+ */
+ public void setPostExtFailOnError(boolean _failOnError) {
+ this.postExtFailOnError = _failOnError;
+ }
+
+ /**
+ * Gets the message.
+ *
+ * @return the message
+ */
+ public String getMessage() {
+ return this.message;
+ }
+
+ /**
+ * Gets the template vars.
+ *
+ * @return the template vars
+ */
+ public ArrayList<String> getTemplateVars() {
+ if (this.templateVars == null) {
+ this.templateVars = new ArrayList<String>();
+ }
+ return this.templateVars;
+ }
+
+ /**
+ * Gets the pre ext exception.
+ *
+ * @return the pre ext exception
+ */
+ public Exception getPreExtException() {
+ return this.preExtException;
+ }
+
+ /**
+ * Gets the pre ext error callback.
+ *
+ * @return the pre ext error callback
+ */
+ public Method getPreExtErrorCallback() {
+ return this.preExtErrorCallback;
+ }
+
+ /**
+ * Gets the post ext exception.
+ *
+ * @return the post ext exception
+ */
+ public Exception getPostExtException() {
+ return this.postExtException;
+ }
+
+ /**
+ * Gets the post ext error callback.
+ *
+ * @return the post ext error callback
+ */
+ public Method getPostExtErrorCallback() {
+ return this.postExtErrorCallback;
+ }
+
+ /**
+ * Gets the http servlet request.
+ *
+ * @return the http servlet request
+ */
+ public HttpServletRequest getHttpServletRequest() {
+ return this.servletRequest;
+ }
+
+ /**
+ * Gets the http headers.
+ *
+ * @return the http headers
+ */
+ public HttpHeaders getHttpHeaders() {
+ return this.httpHeaders;
+ }
+
+ /**
+ * Gets the object from request type.
+ *
+ * @return the object from request type
+ */
+ public String getObjectFromRequestType() {
+ return this.objectFromRequestType;
+ }
+
+ /**
+ * Gets the object from request.
+ *
+ * @return the object from request
+ */
+ public Object getObjectFromRequest() {
+ return this.objectFromRequest;
+ }
+
+ /**
+ * Gets the pre ext fail on error.
+ *
+ * @return the pre ext fail on error
+ */
+ public boolean getPreExtFailOnError() {
+ return this.preExtFailOnError;
+ }
+
+ /**
+ * Gets the post ext fail on error.
+ *
+ * @return the post ext fail on error
+ */
+ public boolean getPostExtFailOnError() {
+ return this.postExtFailOnError;
+ }
+
+ /**
+ * Gets the from app id.
+ *
+ * @return the from app id
+ */
+ public String getFromAppId() {
+ return this.fromAppId;
+ }
+
+ /**
+ * Sets the from app id.
+ *
+ * @param fromAppId the new from app id
+ */
+ public void setFromAppId(String fromAppId) {
+ this.fromAppId = fromAppId;
+ }
+
+ /**
+ * Gets the trans id.
+ *
+ * @return the trans id
+ */
+ public String getTransId() {
+ return this.transId;
+ }
+
+ /**
+ * Sets the trans id.
+ *
+ * @param transId the new trans id
+ */
+ public void setTransId(String transId) {
+ this.transId = transId;
+ }
+
+ /**
+ * Gets the pre ext skip error callback.
+ *
+ * @return the pre ext skip error callback
+ */
+ public boolean getPreExtSkipErrorCallback() {
+ return preExtSkipErrorCallback;
+ }
+
+ /**
+ * Sets the pre ext skip error callback.
+ *
+ * @param preExtSkipErrorCallback the new pre ext skip error callback
+ */
+ public void setPreExtSkipErrorCallback(boolean preExtSkipErrorCallback) {
+ this.preExtSkipErrorCallback = preExtSkipErrorCallback;
+ }
+
+ /**
+ * Gets the post ext skip error callback.
+ *
+ * @return the post ext skip error callback
+ */
+ public boolean getPostExtSkipErrorCallback() {
+ return postExtSkipErrorCallback;
+ }
+
+ /**
+ * Sets the post ext skip error callback.
+ *
+ * @param postExtSkipErrorCallback the new post ext skip error callback
+ */
+ public void setPostExtSkipErrorCallback(boolean postExtSkipErrorCallback) {
+ this.postExtSkipErrorCallback = postExtSkipErrorCallback;
+ }
+
+ /**
+ * Gets the graph.
+ *
+ * @return the graph
+ */
+ public Graph getGraph() {
+ return graph;
+ }
+
+ /**
+ * Sets the graph.
+ *
+ * @param graph the new graph
+ */
+ public void setGraph(Graph graph) {
+ this.graph = graph;
+ }
+
+ /**
+ * Gets the object from response.
+ *
+ * @return the object from response
+ */
+ public Object getObjectFromResponse() {
+ return objectFromResponse;
+ }
+
+ /**
+ * Sets the object from response.
+ *
+ * @param objectFromResponse the new object from response
+ */
+ public void setObjectFromResponse(Object objectFromResponse) {
+ this.objectFromResponse = objectFromResponse;
+ }
+
+ /**
+ * Gets the lookup hash map.
+ *
+ * @return the lookup hash map
+ */
+ public HashMap<String, Object> getLookupHashMap() {
+ if (this.lookupHashMap == null) {
+ this.lookupHashMap = new HashMap<String, Object>();
+ }
+ return this.lookupHashMap;
+ }
+
+ /**
+ * Sets the lookup hash map.
+ *
+ * @param lookupHashMap the lookup hash map
+ */
+ public void setLookupHashMap(HashMap<String, Object> lookupHashMap) {
+ this.lookupHashMap = lookupHashMap;
+ }
+
+ /**
+ * Gets the precheck added list.
+ *
+ * @return the precheck added list
+ */
+ public HashMap<String, ArrayList<String>> getPrecheckAddedList() {
+ if (this.precheckAddedList == null) {
+ this.precheckAddedList = new HashMap<String, ArrayList<String>>();
+ }
+ return precheckAddedList;
+ }
+
+ /**
+ * Sets the precheck added list.
+ *
+ * @param precheckAddedList the precheck added list
+ */
+ public void setPrecheckAddedList(HashMap<String, ArrayList<String>> precheckAddedList) {
+ this.precheckAddedList = precheckAddedList;
+ }
+
+ /**
+ * Gets the precheck response messages.
+ *
+ * @return the precheck response messages
+ */
+ public AAIResponseMessages getPrecheckResponseMessages() {
+ if (this.precheckResponseMessages == null) {
+ this.precheckResponseMessages = new AAIResponseMessages();
+ }
+ return precheckResponseMessages;
+ }
+
+ /**
+ * Sets the precheck response messages.
+ *
+ * @param precheckResponseData the new precheck response messages
+ */
+ public void setPrecheckResponseMessages(AAIResponseMessages precheckResponseData) {
+ this.precheckResponseMessages = precheckResponseData;
+ }
+
+ /**
+ * Gets the topology.
+ *
+ * @return the topology
+ */
+ public HashMap<String, Object> getTopology() {
+ if (this.topology == null) {
+ this.topology = new HashMap<String, Object>();
+ }
+ return topology;
+ }
+
+ /**
+ * Gets the vertex cache.
+ *
+ * @return the vertex cache
+ */
+ public HashMap<String, Vertex> getVertexCache() {
+ if (this.vertexCache == null) {
+ this.vertexCache = new HashMap<String, Vertex>();
+ }
+ return vertexCache;
+ }
+
+ /**
+ * Gets the base object.
+ *
+ * @return the base object
+ */
+ public String getBaseObject() {
+ return baseObject;
+ }
+
+ /**
+ * Sets the base object.
+ *
+ * @param baseObject the new base object
+ */
+ public void setBaseObject(String baseObject) {
+ this.baseObject = baseObject;
+ }
+
+ /**
+ * Gets the namespace.
+ *
+ * @return the namespace
+ */
+ public String getNamespace() {
+ return namespace;
+ }
+
+ /**
+ * Sets the namespace.
+ *
+ * @param namespace the new namespace
+ */
+ public void setNamespace(String namespace) {
+ this.namespace = namespace;
+ }
+
+ /**
+ * Gets the full resource name.
+ *
+ * @return the full resource name
+ */
+ public String getFullResourceName() {
+ return fullResourceName;
+ }
+
+ /**
+ * Sets the full resource name.
+ *
+ * @param fullResourceName the new full resource name
+ */
+ public void setFullResourceName(String fullResourceName) {
+ this.fullResourceName = fullResourceName;
+ }
+
+ /**
+ * Gets the top object full resource name.
+ *
+ * @return the top object full resource name
+ */
+ public String getTopObjectFullResourceName() {
+ return topObjectFullResourceName;
+ }
+
+ /**
+ * Sets the top object full resource name.
+ *
+ * @param topObjectFullResourceName the new top object full resource name
+ */
+ public void setTopObjectFullResourceName(String topObjectFullResourceName) {
+ this.topObjectFullResourceName = topObjectFullResourceName;
+ }
+
+ /**
+ * Gets the uri.
+ *
+ * @return the uri
+ */
+ public String getUri() {
+ return uri;
+ }
+
+ /**
+ * Sets the uri.
+ *
+ * @param uri the new uri
+ */
+ public void setUri(String uri) {
+ this.uri = uri;
+ }
+
+ /**
+ * Gets the api version.
+ *
+ * @return the api version
+ */
+ public String getApiVersion() {
+ return apiVersion;
+ }
+
+ /**
+ * Sets the api version.
+ *
+ * @param apiVersion the new api version
+ */
+ public void setApiVersion(String apiVersion) {
+ this.apiVersion = apiVersion;
+ }
+
+ /**
+ * Sets the notification uri.
+ *
+ * @param uri the new notification uri
+ */
+ public void setNotificationUri(String uri) {
+ this.notificationUri = uri;
+
+ }
+
+ /**
+ * Gets the notification uri.
+ *
+ * @return the notification uri
+ */
+ public String getNotificationUri() {
+ return this.notificationUri;
+
+ }
+
+ /**
+ * Gets the start time.
+ *
+ * @return the start time
+ */
+ public long getStartTime() {
+ return startTime;
+ }
+
+ /**
+ * Sets the start time.
+ *
+ * @param startTime the new start time
+ */
+ public void setStartTime(long startTime) {
+ this.startTime = startTime;
+ }
+
+ /**
+ * Gets the checkpoint time.
+ *
+ * @return the checkpoint time
+ */
+ public long getCheckpointTime() {
+ return checkpointTime;
+ }
+
+ /**
+ * Sets the checkpoint time.
+ *
+ * @param checkpointTime the new checkpoint time
+ */
+ public void setCheckpointTime(long checkpointTime) {
+ this.checkpointTime = checkpointTime;
+ }
+
+ /**
+ * Gets the jaxb context.
+ *
+ * @return the jaxb context
+ */
+ public DynamicJAXBContext getJaxbContext() {
+ return jaxbContext;
+ }
+
+ /**
+ * Sets the jaxb context.
+ *
+ * @param jaxbContext the new jaxb context
+ */
+ public void setJaxbContext(DynamicJAXBContext jaxbContext) {
+ this.jaxbContext = jaxbContext;
+ }
+
+ /**
+ * Sets the event action.
+ *
+ * @param eventAction the new event action
+ */
+ public void setEventAction(String eventAction) {
+ this.eventAction = eventAction;
+ }
+
+ /**
+ * Gets the event action.
+ *
+ * @return the event action
+ */
+ public String getEventAction() {
+ return this.eventAction;
+ }
+
+ /**
+ * Gets the transactional graph engine.
+ *
+ * @return the transactional graph engine
+ */
+ public TransactionalGraphEngine getTransactionalGraphEngine() {
+ return this.dbEngine;
+
+ }
+
+ /**
+ * Sets the transactional graph engine.
+ *
+ * @param dbEngine the new transactional graph engine
+ */
+ public void setTransactionalGraphEngine(TransactionalGraphEngine dbEngine) {
+ this.dbEngine = dbEngine;
+
+ }
+
+ /**
+ * Gets the loader.
+ *
+ * @return the loader
+ */
+ public Loader getLoader() {
+ return loader;
+ }
+
+ /**
+ * Sets the loader.
+ *
+ * @param loader the new loader
+ */
+ public void setLoader(Loader loader) {
+ this.loader = loader;
+ }
+
+ /**
+ * Gets the uri info.
+ *
+ * @return the uri info
+ */
+ public UriInfo getUriInfo() {
+ return uriInfo;
+ }
+
+ /**
+ * Sets the uri info.
+ *
+ * @param uriInfo the new uri info
+ */
+ public void setUriInfo(UriInfo uriInfo) {
+ this.uriInfo = uriInfo;
+ }
+
+ public DBRequest getDbRequest() {
+ return dbRequest;
+ }
+
+ public void setDbRequest(DBRequest dbRequest) {
+ this.dbRequest = dbRequest;
+ }
+
+ public HttpEntry getHttpEntry() {
+ return httpEntry;
+ }
+
+ public void setHttpEntry(HttpEntry httpEntry) {
+ this.httpEntry = httpEntry;
+ }
+}
diff --git a/aai-traversal/src/main/java/org/onap/aai/service/AuthorizationService.java b/aai-traversal/src/main/java/org/onap/aai/service/AuthorizationService.java
index 2bb2794..c0fa93e 100644
--- a/aai-traversal/src/main/java/org/onap/aai/service/AuthorizationService.java
+++ b/aai-traversal/src/main/java/org/onap/aai/service/AuthorizationService.java
@@ -19,7 +19,8 @@
*/
package org.onap.aai.service;
-import com.att.eelf.configuration.EELFLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.att.eelf.configuration.EELFManager;
import org.eclipse.jetty.util.security.Password;
import org.onap.aai.Profiles;
@@ -41,7 +42,7 @@ import java.util.stream.Stream;
@Profile(Profiles.ONE_WAY_SSL)
public class AuthorizationService {
- private static final EELFLogger logger = EELFManager.getInstance().getLogger(AuthorizationService.class);
+ private static final Logger logger = LoggerFactory.getLogger(AuthorizationService.class);
private final Map<String, String> authorizedUsers = new HashMap<>();
@@ -72,7 +73,7 @@ public class AuthorizationService {
String[] usernamePasswordArray = usernamePassword.split(":");
if(usernamePasswordArray == null || usernamePasswordArray.length != 3){
- throw new RuntimeException("Not a valid entry for the realm.properties entry: " + usernamePassword);
+ throw new RuntimeException("This username / pwd is not a valid entry in realm.properties");
}
String username = usernamePasswordArray[0];
diff --git a/aai-traversal/src/main/java/org/onap/aai/transforms/MapTraverser.java b/aai-traversal/src/main/java/org/onap/aai/transforms/MapTraverser.java
index 36c453a..9091998 100644
--- a/aai-traversal/src/main/java/org/onap/aai/transforms/MapTraverser.java
+++ b/aai-traversal/src/main/java/org/onap/aai/transforms/MapTraverser.java
@@ -19,13 +19,14 @@
*/
package org.onap.aai.transforms;
+
+import joptsimple.internal.Objects;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import org.apache.commons.collections.MapUtils;
-
public class MapTraverser {
private Converter converter;
@@ -36,9 +37,8 @@ public class MapTraverser {
public Map<String, Object> convertKeys(Map<String, Object> map){
- if (MapUtils.isEmpty(map)) {
- throw new NullPointerException("map cannot be null");
- }
+ Objects.ensureNotNull(map);
+
Map<String, Object> modifiedMap = new HashMap<String, Object>();
convertKeys(map, modifiedMap);
diff --git a/aai-traversal/src/main/java/org/onap/aai/util/MakeNamedQuery.java b/aai-traversal/src/main/java/org/onap/aai/util/MakeNamedQuery.java
index 503cf6c..4a80f58 100644
--- a/aai-traversal/src/main/java/org/onap/aai/util/MakeNamedQuery.java
+++ b/aai-traversal/src/main/java/org/onap/aai/util/MakeNamedQuery.java
@@ -26,7 +26,8 @@ import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
-import com.att.eelf.configuration.EELFLogger;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import com.att.eelf.configuration.EELFManager;
import org.apache.commons.io.FileUtils;
import org.onap.aai.config.SpringContextAware;
@@ -41,7 +42,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
public class MakeNamedQuery {
- private static final EELFLogger logger = EELFManager.getInstance().getLogger(MakeNamedQuery.class.getName());
+ private static final Logger logger = LoggerFactory.getLogger(MakeNamedQuery.class.getName());
public static void main(String[] args) throws Exception {
String _apiVersion = AAIConfig.get(AAIConstants.AAI_DEFAULT_API_VERSION_PROP);
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 4b5ebfe..fdeefe1 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
@@ -31,7 +31,8 @@ public final class TraversalConstants {
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 String DSL_MAX_NODE_COUNT = "15";
+
public static final long HISTORY_MAX_HOURS = 192;
private TraversalConstants() {
diff --git a/aai-traversal/src/main/java/org/onap/aai/web/JerseyConfiguration.java b/aai-traversal/src/main/java/org/onap/aai/web/JerseyConfiguration.java
index ab3c9fd..e6cf080 100644
--- a/aai-traversal/src/main/java/org/onap/aai/web/JerseyConfiguration.java
+++ b/aai-traversal/src/main/java/org/onap/aai/web/JerseyConfiguration.java
@@ -19,131 +19,131 @@
*/
package org.onap.aai.web;
+import jersey.repackaged.com.google.common.collect.Sets;
import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.servlet.ServletProperties;
-import org.onap.aai.rest.CQ2Gremlin;
-import org.onap.aai.rest.CQ2GremlinTest;
-import org.onap.aai.rest.DslConsumer;
-import org.onap.aai.rest.QueryConsumer;
-import org.onap.aai.rest.RecentAPIConsumer;
+import org.onap.aai.aailog.logs.AaiDebugLog;
+import org.onap.aai.rest.*;
import org.onap.aai.rest.search.ModelAndNamedQueryRestProvider;
import org.onap.aai.rest.search.SearchProvider;
import org.onap.aai.rest.util.EchoResponse;
-import org.reflections.Reflections;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
-import org.springframework.stereotype.Component;
import javax.annotation.Priority;
-import javax.ws.rs.container.ContainerRequestFilter;
-import javax.ws.rs.container.ContainerResponseFilter;
-
-import java.util.List;
+import java.lang.reflect.AnnotatedElement;
+import java.util.Collection;
+import java.util.Comparator;
import java.util.Set;
import java.util.logging.Logger;
-import java.util.stream.Collectors;
-@Component
-public class JerseyConfiguration extends ResourceConfig {
+import static java.lang.Boolean.parseBoolean;
+import static java.util.Comparator.comparingInt;
- private static final Logger log = Logger.getLogger(JerseyConfiguration.class.getName());
+@Configuration
+public class JerseyConfiguration {
- private Environment env;
+ private static final Logger log = Logger.getLogger(JerseyConfiguration.class.getName());
+ private static final org.slf4j.Logger logger = LoggerFactory.getLogger(JerseyConfiguration.class.getName());
- @Autowired
- public JerseyConfiguration(Environment env) {
-
- this.env = env;
-
- register(SearchProvider.class);
- register(ModelAndNamedQueryRestProvider.class);
- register(QueryConsumer.class);
- register(RecentAPIConsumer.class);
- register(DslConsumer.class);
- register(EchoResponse.class);
- register(CQ2Gremlin.class);
- register(CQ2GremlinTest.class);
-
- //Request Filters
- registerFiltersForRequests();
- // Response Filters
- registerFiltersForResponses();
-
- property(ServletProperties.FILTER_FORWARD_ON_404, true);
-
- // Following registers the request headers and response headers
- // If the LoggingFilter second argument is set to true, it will print response value as well
- if ("true".equalsIgnoreCase(env.getProperty("aai.request.logging.enabled"))) {
- register(new LoggingFilter(log, false));
- }
+ private static AaiDebugLog debugLog = new AaiDebugLog();
+ static {
+ debugLog.setupMDC();
}
- public void registerFiltersForRequests() {
+ private static final String LOGGING_ENABLED_PROPERTY = "aai.request.logging.enabled";
+ private static final boolean ENABLE_RESPONSE_LOGGING = false;
+
+ private final Environment environment;
- // Find all the classes within the interceptors package
- Reflections reflections = new Reflections("org.onap.aai.interceptors");
- // Filter them based on the clazz that was passed in
- Set<Class<? extends ContainerRequestFilter>> filters = reflections.getSubTypesOf(ContainerRequestFilter.class);
+ @Autowired
+ public JerseyConfiguration(Environment environment) {
+ this.environment = environment;
+ }
+ @Bean
+ public ResourceConfig resourceConfig() {
+ ResourceConfig resourceConfig = new ResourceConfig();
+
+ Set<Class<?>> classes = Sets.newHashSet(
+ SearchProvider.class,
+ ModelAndNamedQueryRestProvider.class,
+ QueryConsumer.class,
+ RecentAPIConsumer.class,
+ DslConsumer.class,
+ EchoResponse.class,
+ CQ2Gremlin.class,
+ CQ2GremlinTest.class
+ );
+ Set<Class<?>> filterClasses = Sets.newHashSet(
+ org.onap.aai.aailog.filter.AaiAuditLogContainerFilter.class,
+ org.onap.aai.interceptors.pre.RequestTransactionLogging.class,
+ org.onap.aai.interceptors.pre.HeaderValidation.class,
+ org.onap.aai.interceptors.pre.HttpHeaderInterceptor.class,
+ org.onap.aai.interceptors.pre.OneWaySslAuthorization.class,
+ org.onap.aai.interceptors.pre.VersionLatestInterceptor.class,
+ org.onap.aai.interceptors.pre.RetiredInterceptor.class,
+ org.onap.aai.interceptors.pre.VersionInterceptor.class,
+ org.onap.aai.interceptors.pre.RequestHeaderManipulation.class,
+ org.onap.aai.interceptors.pre.RequestModification.class,
+ org.onap.aai.interceptors.post.InvalidResponseStatus.class,
+ org.onap.aai.interceptors.post.ResponseTransactionLogging.class,
+ org.onap.aai.interceptors.post.ResponseHeaderManipulation.class
+ );
+ if (isLoggingEnabled()) {
+ logRequests(resourceConfig);
+ }
+ resourceConfig.registerClasses(classes);
+ logger.debug("REGISTERED CLASSES " + classes.toString());
+
+ throwIfPriorityAnnotationAbsent(filterClasses);
+ filterClasses.stream()
+ .filter(this::isEnabledByActiveProfiles)
+ .sorted(priorityComparator())
+ .forEach(resourceConfig::register);
+
+ filterClasses.stream()
+ .filter(this::isEnabledByActiveProfiles)
+ .sorted(priorityComparator())
+ .forEach(s -> logger.debug("REGISTERED FILTERS " + s.getName()));
+ return resourceConfig;
+ }
- // Check to ensure that each of the filter has the @Priority annotation and if not throw exception
- for (Class filterClass : filters) {
- if (filterClass.getAnnotation(Priority.class) == null) {
- throw new RuntimeException("Container filter " + filterClass.getName() + " does not have @Priority annotation");
+ private <T> void throwIfPriorityAnnotationAbsent(Collection<Class<? extends T>> classes) {
+ for (Class clazz : classes) {
+ if (!clazz.isAnnotationPresent(Priority.class)) {
+ logger.debug("throwIfPriorityAnnotationAbsent: missing filter priority for : " + clazz.getName());
+ throw new MissingFilterPriorityException(clazz);
}
}
+ }
- // Turn the set back into a list
- List<Class<? extends ContainerRequestFilter>> filtersList = filters
- .stream()
- .filter(f -> {
- if (f.isAnnotationPresent(Profile.class)
- && !env.acceptsProfiles(f.getAnnotation(Profile.class).value())) {
- return false;
- }
- return true;
- })
- .collect(Collectors.toList());
-
- // Sort them by their priority levels value
- filtersList.sort((c1, c2) -> Integer.valueOf(c1.getAnnotation(Priority.class).value()).compareTo(c2.getAnnotation(Priority.class).value()));
-
- // Then register this to the jersey application
- filtersList.forEach(this::register);
+ private <T> Comparator<Class<? extends T>> priorityComparator() {
+ return comparingInt(clazz -> clazz.getAnnotation(Priority.class).value());
}
- public void registerFiltersForResponses() {
+ private void logRequests(ResourceConfig resourceConfig) {
+ resourceConfig.register(new LoggingFilter(log, ENABLE_RESPONSE_LOGGING));
+ }
- // Find all the classes within the interceptors package
- Reflections reflections = new Reflections("org.onap.aai.interceptors");
- // Filter them based on the clazz that was passed in
- Set<Class<? extends ContainerResponseFilter>> filters = reflections.getSubTypesOf(ContainerResponseFilter.class);
+ private boolean isLoggingEnabled() {
+ return parseBoolean(environment.getProperty(LOGGING_ENABLED_PROPERTY));
+ }
+ private boolean isEnabledByActiveProfiles(AnnotatedElement annotatedElement) {
+ boolean result = !annotatedElement.isAnnotationPresent(Profile.class) ||
+ environment.acceptsProfiles(annotatedElement.getAnnotation(Profile.class).value());
+ logger.debug("isEnabledByActiveProfiles: annotatedElement: " + annotatedElement.toString() + " result=" + result);
+ return result;
+ }
- // Check to ensure that each of the filter has the @Priority annotation and if not throw exception
- for (Class filterClass : filters) {
- if (filterClass.getAnnotation(Priority.class) == null) {
- throw new RuntimeException("Container filter " + filterClass.getName() + " does not have @Priority annotation");
- }
+ private class MissingFilterPriorityException extends RuntimeException {
+ private MissingFilterPriorityException(Class<?> clazz) {
+ super("Container filter " + clazz.getName() + " does not have @Priority annotation");
}
-
- // Turn the set back into a list
- List<Class<? extends ContainerResponseFilter>> filtersList = filters.stream()
- .filter(f -> {
- if (f.isAnnotationPresent(Profile.class)
- && !env.acceptsProfiles(f.getAnnotation(Profile.class).value())) {
- return false;
- }
- return true;
- })
- .collect(Collectors.toList());
-
- // Sort them by their priority levels value
- filtersList.sort((c1, c2) -> Integer.valueOf(c1.getAnnotation(Priority.class).value()).compareTo(c2.getAnnotation(Priority.class).value()));
-
- // Then register this to the jersey application
- filtersList.forEach(this::register);
}
-}
+} \ No newline at end of file