summaryrefslogtreecommitdiffstats
path: root/aai-traversal/src/main
diff options
context:
space:
mode:
authorFiete Ostkamp <Fiete.Ostkamp@telekom.de>2023-12-18 11:12:30 +0100
committerFiete Ostkamp <Fiete.Ostkamp@telekom.de>2023-12-18 11:16:33 +0100
commit6d7077ca105bad3593881db079ef2b5eb1aaa6b1 (patch)
tree520451e439035ce6bfdf4358b9c5e8f35096fa1c /aai-traversal/src/main
parent33521592f3a466fd5cb6959340c1ec70e412dfa8 (diff)
Make the jax-rs resource a spring boot RestController
- replace jax-rs annotations with spring boot equivalents - replace the jersey exception handler with a ControllerAdvice class - move AAIErrorResponse definitions from test/ to main/ Issue-ID: AAI-3694 Change-Id: I5a45309727bfd84bb2aee5c20957fd845c484d5e Signed-off-by: Fiete Ostkamp <Fiete.Ostkamp@telekom.de>
Diffstat (limited to 'aai-traversal/src/main')
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/entities/AAIErrorResponse.java4
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/entities/RequestError.java2
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/entities/ServiceException.java2
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/interceptors/post/ResponseTransactionLogging.java29
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/interceptors/pre/RequestTransactionLogging.java43
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/DslConsumer.java143
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/ExceptionHandler.java108
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/GlobalExceptionHandler.java109
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/rest/dsl/DslQueryProcessor.java5
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/web/JerseyConfiguration.java15
-rw-r--r--aai-traversal/src/main/java/org/onap/aai/web/WebConfiguration.java29
-rw-r--r--aai-traversal/src/main/resources/application.properties4
12 files changed, 251 insertions, 242 deletions
diff --git a/aai-traversal/src/main/java/org/onap/aai/entities/AAIErrorResponse.java b/aai-traversal/src/main/java/org/onap/aai/entities/AAIErrorResponse.java
index b80b83d..7cb7edf 100644
--- a/aai-traversal/src/main/java/org/onap/aai/entities/AAIErrorResponse.java
+++ b/aai-traversal/src/main/java/org/onap/aai/entities/AAIErrorResponse.java
@@ -22,9 +22,11 @@ package org.onap.aai.entities;
import lombok.Builder;
import lombok.Data;
+import lombok.extern.jackson.Jacksonized;
@Data
@Builder
+@Jacksonized
public class AAIErrorResponse {
- private RequestError requestError;
+ private final RequestError requestError;
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/entities/RequestError.java b/aai-traversal/src/main/java/org/onap/aai/entities/RequestError.java
index 4aaf43c..aca87b4 100644
--- a/aai-traversal/src/main/java/org/onap/aai/entities/RequestError.java
+++ b/aai-traversal/src/main/java/org/onap/aai/entities/RequestError.java
@@ -22,9 +22,11 @@ package org.onap.aai.entities;
import lombok.Builder;
import lombok.Data;
+import lombok.extern.jackson.Jacksonized;
@Data
@Builder
+@Jacksonized
public class RequestError {
private ServiceException serviceException;
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/entities/ServiceException.java b/aai-traversal/src/main/java/org/onap/aai/entities/ServiceException.java
index 3eb9a21..39a7490 100644
--- a/aai-traversal/src/main/java/org/onap/aai/entities/ServiceException.java
+++ b/aai-traversal/src/main/java/org/onap/aai/entities/ServiceException.java
@@ -24,9 +24,11 @@ import java.util.List;
import lombok.Builder;
import lombok.Data;
+import lombok.extern.jackson.Jacksonized;
@Data
@Builder
+@Jacksonized
public class ServiceException {
private String messageId;
private String text;
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 854eeed..06c10e6 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
@@ -25,7 +25,6 @@ import java.io.IOException;
import java.util.*;
import javax.annotation.Priority;
-import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
@@ -38,8 +37,6 @@ 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;
-
@Priority(AAIResponseFilterPriority.RESPONSE_TRANS_LOGGING)
public class ResponseTransactionLogging extends AAIContainerFilter
implements ContainerResponseFilter {
@@ -54,9 +51,6 @@ public class ResponseTransactionLogging extends AAIContainerFilter
private final static String RECENTS_API_PATH_SEGMENT = "recents";
private final static Set<String> READ_ONLY_QUERIES = getReadOnlyQueries();
- @Autowired
- private HttpServletResponse httpServletResponse;
-
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
@@ -80,23 +74,22 @@ public class ResponseTransactionLogging extends AAIContainerFilter
} catch (AAIException e) {
return;
}
-
- String transId = requestContext.getHeaderString(AAIHeaderProperties.TRANSACTION_ID);
- String fromAppId = requestContext.getHeaderString(AAIHeaderProperties.FROM_APP_ID);
- String fullUri = requestContext.getUriInfo().getRequestUri().toString();
- String requestTs = (String) requestContext.getProperty(AAIHeaderProperties.AAI_REQUEST_TS);
-
String httpMethod = requestContext.getMethod();
- String status = Integer.toString(responseContext.getStatus());
-
- String request = (String) requestContext.getProperty(AAIHeaderProperties.AAI_REQUEST);
- String response = this.getResponseString(responseContext);
-
if (!Boolean.parseBoolean(logValue)) {
} else if (!Boolean.parseBoolean(postValue) && "POST".equals(httpMethod)) {
} else {
+ String transId = requestContext.getHeaderString(AAIHeaderProperties.TRANSACTION_ID);
+ String fromAppId = requestContext.getHeaderString(AAIHeaderProperties.FROM_APP_ID);
+ String fullUri = requestContext.getUriInfo().getRequestUri().toString();
+ String requestTs = (String) requestContext.getProperty(AAIHeaderProperties.AAI_REQUEST_TS);
+
+ String status = Integer.toString(responseContext.getStatus());
+
+ String request = (String) requestContext.getProperty(AAIHeaderProperties.AAI_REQUEST);
+ String response = this.getResponseString(responseContext);
+
JsonObject logEntry = new JsonObject();
logEntry.addProperty("transactionId", transId);
logEntry.addProperty("status", status);
@@ -141,7 +134,7 @@ public class ResponseTransactionLogging extends AAIContainerFilter
private String getResponseString(ContainerResponseContext responseContext) {
JsonObject response = new JsonObject();
response.addProperty("ID", responseContext.getHeaderString(AAIHeaderProperties.AAI_TX_ID));
- response.addProperty("Content-Type", this.httpServletResponse.getContentType());
+ response.addProperty("Content-Type", responseContext.getHeaders().getFirst("Content-Type").toString());
response.addProperty("Response-Code", responseContext.getStatus());
response.addProperty("Headers", responseContext.getHeaders().toString());
Optional<Object> entityOptional = Optional.ofNullable(responseContext.getEntity());
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 b37a804..8c73033 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
@@ -25,6 +25,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.Charset;
import java.security.SecureRandom;
import java.util.Random;
import java.util.UUID;
@@ -38,6 +39,8 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriInfo;
+import org.apache.commons.io.Charsets;
+import org.apache.commons.io.IOUtils;
import org.glassfish.jersey.message.internal.ReaderWriter;
import org.glassfish.jersey.server.ContainerException;
import org.onap.aai.exceptions.AAIException;
@@ -46,17 +49,14 @@ import org.onap.aai.interceptors.AAIHeaderProperties;
import org.onap.aai.util.AAIConfig;
import org.onap.aai.util.AAIConstants;
import org.onap.aai.util.HbaseSaltPrefixer;
-import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
+// Here
@PreMatching
@Priority(AAIRequestFilterPriority.REQUEST_TRANS_LOGGING)
public class RequestTransactionLogging extends AAIContainerFilter
implements ContainerRequestFilter {
- @Autowired
- private HttpServletRequest httpServletRequest;
-
private static final String DEFAULT_CONTENT_TYPE = MediaType.APPLICATION_JSON;
private static final String DEFAULT_RESPONSE_TYPE = MediaType.APPLICATION_XML;
@@ -67,23 +67,15 @@ public class RequestTransactionLogging extends AAIContainerFilter
private static final String APPLICATION_JSON = "application/json";
@Override
- public void filter(ContainerRequestContext requestContext) throws IOException {
-
+ public void filter(ContainerRequestContext requestContext) throws IOException {
String currentTimeStamp = genDate();
String fullId = this.getAAITxIdToHeader(currentTimeStamp);
- this.addToRequestContext(requestContext, AAIHeaderProperties.AAI_TX_ID, fullId);
- this.addToRequestContext(requestContext, AAIHeaderProperties.AAI_REQUEST,
- this.getRequest(requestContext, fullId));
- this.addToRequestContext(requestContext, AAIHeaderProperties.AAI_REQUEST_TS,
- currentTimeStamp);
+ requestContext.setProperty(AAIHeaderProperties.AAI_TX_ID, fullId);
+ requestContext.setProperty(AAIHeaderProperties.AAI_REQUEST, this.getRequest(requestContext, fullId));
+ requestContext.setProperty(AAIHeaderProperties.AAI_REQUEST_TS, currentTimeStamp);
this.addDefaultContentType(requestContext);
}
- private void addToRequestContext(ContainerRequestContext requestContext, String name,
- String aaiTxIdToHeader) {
- requestContext.setProperty(name, aaiTxIdToHeader);
- }
-
private void addDefaultContentType(ContainerRequestContext requestContext) {
String contentType = requestContext.getHeaderString(CONTENT_TYPE);
@@ -124,27 +116,16 @@ public class RequestTransactionLogging extends AAIContainerFilter
return txId;
}
- private String getRequest(ContainerRequestContext requestContext, String fullId) {
+ private String getRequest(ContainerRequestContext requestContext, String fullId) throws IOException {
JsonObject request = new JsonObject();
request.addProperty("ID", fullId);
request.addProperty("Http-Method", requestContext.getMethod());
- request.addProperty(CONTENT_TYPE, httpServletRequest.getContentType());
request.addProperty("Headers", requestContext.getHeaders().toString());
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- InputStream in = requestContext.getEntityStream();
-
- try {
- if (in.available() > 0) {
- ReaderWriter.writeTo(in, out);
- byte[] requestEntity = out.toByteArray();
- request.addProperty("Payload", new String(requestEntity, "UTF-8"));
- requestContext.setEntityStream(new ByteArrayInputStream(requestEntity));
- }
- } catch (IOException ex) {
- throw new ContainerException(ex);
- }
+ // String requestEntity = IOUtils.toString(requestContext.getEntityStream(), Charsets.UTF_8);
+ // InputStream in = IOUtils.toInputStream(requestEntity, Charset.defaultCharset());
+ // requestContext.setEntityStream(in);
return request.toString();
}
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 d814b48..2a02ff5 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
@@ -22,34 +22,24 @@ package org.onap.aai.rest;
import java.io.FileNotFoundException;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.DefaultValue;
-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.MultivaluedHashMap;
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.antlr.v4.runtime.tree.ParseTreeListener;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
-import org.janusgraph.core.SchemaViolationException;
-import org.onap.aai.concurrent.AaiCallable;
+import org.onap.aai.edges.EdgeIngestor;
import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.introspection.LoaderFactory;
import org.onap.aai.introspection.ModelType;
import org.onap.aai.rest.db.HttpEntry;
import org.onap.aai.rest.dsl.DslQueryProcessor;
@@ -57,7 +47,6 @@ 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.serialization.db.DBSerializer;
import org.onap.aai.serialization.engines.TransactionalGraphEngine;
import org.onap.aai.serialization.queryformats.Format;
@@ -73,6 +62,16 @@ 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.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.PutMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
@@ -81,7 +80,8 @@ import com.google.gson.JsonParser;
import io.micrometer.core.annotation.Timed;
@Timed
-@Path("{version: v[1-9][0-9]*|latest}/dsl")
+@RestController
+@RequestMapping("/{version:v[1-9][0-9]*|latest}/dsl")
public class DslConsumer extends TraversalConsumer {
private static final Logger LOGGER = LoggerFactory.getLogger(DslConsumer.class);
@@ -89,55 +89,58 @@ public class DslConsumer extends TraversalConsumer {
private static final QueryVersion DEFAULT_VERSION = QueryVersion.V1;
private final HttpEntry traversalUriHttpEntry;
- private final DslQueryProcessor dslQueryProcessor;
private final SchemaVersions schemaVersions;
private final String basePath;
private final GremlinServerSingleton gremlinServerSingleton;
private final XmlFormatTransformer xmlFormatTransformer;
+ // private final Map<QueryVersion, ParseTreeListener> dslListeners;
+ private final EdgeIngestor edgeIngestor;
+ private final LoaderFactory loaderFactory;
private QueryVersion dslApiVersion = DEFAULT_VERSION;
@Autowired
- public DslConsumer(HttpEntry traversalUriHttpEntry, DslQueryProcessor dslQueryProcessor,
+ public DslConsumer(HttpEntry traversalUriHttpEntry,
SchemaVersions schemaVersions, GremlinServerSingleton gremlinServerSingleton,
XmlFormatTransformer xmlFormatTransformer,
+ EdgeIngestor edgeIngestor, LoaderFactory loaderFactory,
@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;
+ this.edgeIngestor = edgeIngestor;
+ this.loaderFactory = loaderFactory;
}
- @PUT
- @Consumes({MediaType.APPLICATION_JSON})
- @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
- public Response executeQuery(String dslQuery, @PathParam("version") String versionParam,
- @DefaultValue("graphson") @QueryParam("format") String queryFormat,
- @DefaultValue("no_op") @QueryParam("subgraph") String subgraph,
- @DefaultValue("all") @QueryParam("validate") String validate,
- @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex,
- @DefaultValue("-1") @QueryParam("resultSize") String resultSize,
- @Context HttpHeaders headers,
- @Context HttpServletRequest req,
- @Context UriInfo info) throws FileNotFoundException, AAIException {
- Set<String> roles = this.getRoles(req.getUserPrincipal());
-
- return processExecuteQuery(dslQuery, req, versionParam, queryFormat, subgraph,
- validate, headers, info, resultIndex, resultSize, roles);
+ @PutMapping(produces = {MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE})
+ public ResponseEntity<String> executeQuery(@RequestBody String dslQuery,
+ @PathVariable("version") String versionParam,
+ @RequestParam(defaultValue = "graphson") String format,
+ @RequestParam(defaultValue = "no_op") String subgraph,
+ @RequestParam(defaultValue = "all") String validate,
+ @RequestParam(defaultValue = "-1") String resultIndex,
+ @RequestParam(defaultValue = "-1") String resultSize,
+ @RequestHeader HttpHeaders headers,
+ HttpServletRequest request) throws FileNotFoundException, AAIException {
+ Set<String> roles = this.getRoles(request.getUserPrincipal());
+
+ return processExecuteQuery(dslQuery, request, versionParam, format, subgraph,
+ validate, headers, resultIndex, resultSize, roles);
}
- public Response processExecuteQuery(String dslQuery, HttpServletRequest request, String versionParam,
- String queryFormat, String subgraph, String validate, HttpHeaders headers, UriInfo info,
+ public ResponseEntity<String> processExecuteQuery(String dslQuery, HttpServletRequest request, String versionParam,
+ String queryFormat, String subgraph, String validate, HttpHeaders headers,
String resultIndex, String resultSize, Set<String> roles) throws FileNotFoundException, AAIException {
final SchemaVersion version = new SchemaVersion(versionParam);
- final String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId");
- final String dslOverride = headers.getRequestHeaders().getFirst("X-DslOverride");
+ final String sourceOfTruth = headers.getFirst("X-FromAppId");
+ final String dslOverride = headers.getFirst("X-DslOverride");
+ final MultivaluedMap<String,String> queryParams = toMultivaluedMap(request.getParameterMap());
Optional<String> dslApiVersionHeader =
- Optional.ofNullable(headers.getRequestHeaders().getFirst("X-DslApiVersion"));
+ Optional.ofNullable(headers.getFirst("X-DslApiVersion"));
if (dslApiVersionHeader.isPresent()) {
try {
dslApiVersion = QueryVersion.valueOf(dslApiVersionHeader.get());
@@ -146,25 +149,25 @@ public class DslConsumer extends TraversalConsumer {
}
}
- String result = executeQuery(dslQuery, request, queryFormat, subgraph, validate, info.getQueryParameters(), resultIndex, resultSize,
+ String result = executeQuery(dslQuery, request, queryFormat, subgraph, validate, queryParams, resultIndex, resultSize,
roles, version, sourceOfTruth, dslOverride);
+ MediaType acceptType = headers.getAccept().stream()
+ .filter(Objects::nonNull)
+ .filter(header -> !header.equals(MediaType.ALL))
+ .findAny()
+ .orElse(MediaType.APPLICATION_JSON);
- String acceptType = headers.getHeaderString("Accept");
- if (acceptType == null) {
- acceptType = MediaType.APPLICATION_JSON;
- }
-
- if (MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(acceptType))) {
+ if (MediaType.APPLICATION_XML.isCompatibleWith(acceptType)) {
result = xmlFormatTransformer.transform(result);
}
if (traversalUriHttpEntry.isPaginated()) {
- return Response.status(Status.OK).type(acceptType)
- .header("total-results", traversalUriHttpEntry.getTotalVertices())
- .header("total-pages", traversalUriHttpEntry.getTotalPaginationBuckets())
- .entity(result).build();
+ return ResponseEntity.ok()
+ .header("total-results", String.valueOf(traversalUriHttpEntry.getTotalVertices()))
+ .header("total-pages", String.valueOf(traversalUriHttpEntry.getTotalPaginationBuckets()))
+ .body(result);
} else {
- return Response.status(Status.OK).type(acceptType).entity(result).build();
+ return ResponseEntity.ok(result);
}
}
@@ -176,7 +179,6 @@ public class DslConsumer extends TraversalConsumer {
req.getRequestURL().toString().replaceAll("/(v[0-9]+|latest)/.*", "/");
traversalUriHttpEntry.setHttpEntryProperties(version, serverBase);
traversalUriHttpEntry.setPaginationParameters(resultIndex, resultSize);
- final TransactionalGraphEngine dbEngine = traversalUriHttpEntry.getDbEngine();
JsonObject input = JsonParser.parseString(content).getAsJsonObject();
JsonElement dslElement = input.get("dsl");
@@ -189,6 +191,12 @@ public class DslConsumer extends TraversalConsumer {
&& !AAIConfig.get(TraversalConstants.DSL_OVERRIDE).equals("false")
&& dslOverride.equals(AAIConfig.get(TraversalConstants.DSL_OVERRIDE));
+ 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));
+ DslQueryProcessor dslQueryProcessor = new DslQueryProcessor(dslListeners);
if (isDslOverride) {
dslQueryProcessor.setStartNodeValidationFlag(false);
}
@@ -205,9 +213,10 @@ public class DslConsumer extends TraversalConsumer {
validateHistoryParams(format, queryParameters);
}
+ final TransactionalGraphEngine dbEngine = traversalUriHttpEntry.getDbEngine();
GraphTraversalSource traversalSource =
getTraversalSource(dbEngine, format, queryParameters, roles);
-
+
GenericQueryProcessor processor =
new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton)
.queryFrom(dsl, "dsl").queryProcessor(dslQueryProcessor).version(dslApiVersion)
@@ -217,12 +226,11 @@ public class DslConsumer extends TraversalConsumer {
SubGraphStyle subGraphStyle = SubGraphStyle.valueOf(subgraph);
List<Object> vertTemp = processor.execute(subGraphStyle);
- // Dedup if duplicate objects are returned in each array in the aggregate format
- // scenario.
- List<Object> vertTempDedupedObjectList = dedupObjectInAggregateFormatResult(vertTemp);
-
List<Object> vertices;
if (isAggregate(format)) {
+ // Dedup if duplicate objects are returned in each array in the aggregate format
+ // scenario.
+ List<Object> vertTempDedupedObjectList = dedupObjectInAggregateFormatResult(vertTemp);
vertices = traversalUriHttpEntry
.getPaginatedVertexListForAggregateFormat(vertTempDedupedObjectList);
} else {
@@ -252,6 +260,12 @@ public class DslConsumer extends TraversalConsumer {
return result;
}
+ private List<Object> dedupObjectInAggregateFormatResultStreams(List<Object> vertTemp) {
+ return vertTemp.stream()
+ .filter(o -> o instanceof ArrayList)
+ .map(o -> ((ArrayList<?>) o).stream().distinct().collect(Collectors.toList()))
+ .collect(Collectors.toList());
+ }
private List<Object> dedupObjectInAggregateFormatResult(List<Object> vertTemp) {
List<Object> vertTempDedupedObjectList = new ArrayList<Object>();
Iterator<Object> itr = vertTemp.listIterator();
@@ -264,4 +278,15 @@ public class DslConsumer extends TraversalConsumer {
}
return vertTempDedupedObjectList;
}
+
+ private MultivaluedMap<String, String> toMultivaluedMap(Map<String, String[]> map) {
+ MultivaluedMap<String, String> multivaluedMap = new MultivaluedHashMap<>();
+
+ for (Map.Entry<String, String[]> entry : map.entrySet()) {
+ for (String val : entry.getValue())
+ multivaluedMap.add(entry.getKey(), val);
+ }
+
+ return multivaluedMap;
+ }
}
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/ExceptionHandler.java b/aai-traversal/src/main/java/org/onap/aai/rest/ExceptionHandler.java
deleted file mode 100644
index 447ecdd..0000000
--- a/aai-traversal/src/main/java/org/onap/aai/rest/ExceptionHandler.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/**
- * ============LICENSE_START=======================================================
- * org.onap.aai
- * ================================================================================
- * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
- * Modifications Copyright (C) 2023 Deutsche Telekom SA.
- * ================================================================================
- * 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 com.fasterxml.jackson.core.JsonParseException;
-import com.fasterxml.jackson.databind.JsonMappingException;
-import com.sun.istack.SAXParseException2;
-
-import java.util.ArrayList;
-
-import javax.annotation.Priority;
-import javax.servlet.http.HttpServletRequest;
-import javax.ws.rs.WebApplicationException;
-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.ext.ExceptionMapper;
-import javax.ws.rs.ext.Provider;
-
-import org.janusgraph.core.SchemaViolationException;
-import org.onap.aai.exceptions.AAIException;
-import org.onap.aai.logging.ErrorLogHelper;
-
-/**
- * The Class ExceptionHandler.
- */
-@Provider
-@Priority(10000)
-public class ExceptionHandler implements ExceptionMapper<Exception> {
-
- private static final String AAI_4007 = "AAI_4007";
-
- @Context
- private HttpServletRequest request;
-
- @Context
- private HttpHeaders headers;
-
- @Override
- public Response toResponse(Exception exception) {
- // the general case is that cxf will give us a WebApplicationException
- // with a linked exception
- if (exception instanceof WebApplicationException) {
- if (exception.getCause() instanceof SAXParseException2) {
- return buildAAIExceptionResponse(new AAIException(AAI_4007, exception));
- } else {
- return ((WebApplicationException) exception).getResponse();
- }
- } else if (exception instanceof JsonParseException) {
- // jackson does it differently so we get the direct JsonParseException
- return buildAAIExceptionResponse(new AAIException(AAI_4007, exception));
- } else if (exception instanceof JsonMappingException) {
- // jackson does it differently so we get the direct JsonParseException
- return buildAAIExceptionResponse(new AAIException(AAI_4007, exception));
- } else if (exception instanceof SchemaViolationException) {
- return buildAAIExceptionResponse(new AAIException("AAI_4020", exception));
- // it didn't get set above, we wrap a general fault here
- } else if (exception instanceof AAIException) {
- return buildAAIExceptionResponse((AAIException) exception);
- } else {
- return defaultException(exception);
- }
- }
-
- private Response buildAAIExceptionResponse(AAIException exception) {
- ArrayList<String> templateVars = new ArrayList<>();
- templateVars.add(request.getMethod());
- templateVars.add(request.getRequestURI());
-
- // prefer xml, use json otherwise
- return headers.getAcceptableMediaTypes().stream()
- .filter(MediaType.APPLICATION_ATOM_XML_TYPE::isCompatible)
- .findAny()
- .map(xmlType ->
- Response.status(400).type(MediaType.APPLICATION_XML_TYPE)
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(
- headers.getAcceptableMediaTypes(), exception, templateVars))
- .build())
- .orElseGet(() ->
- Response.status(400).type(MediaType.APPLICATION_JSON_TYPE)
- .entity(ErrorLogHelper.getRESTAPIErrorResponse(
- headers.getAcceptableMediaTypes(), exception, templateVars))
- .build());
- }
-
- private Response defaultException(Exception exception) {
- return buildAAIExceptionResponse(new AAIException("AAI_4000", exception));
- }
-} \ No newline at end of file
diff --git a/aai-traversal/src/main/java/org/onap/aai/rest/GlobalExceptionHandler.java b/aai-traversal/src/main/java/org/onap/aai/rest/GlobalExceptionHandler.java
new file mode 100644
index 0000000..c934e8c
--- /dev/null
+++ b/aai-traversal/src/main/java/org/onap/aai/rest/GlobalExceptionHandler.java
@@ -0,0 +1,109 @@
+/**
+ * ============LICENSE_START=======================================================
+ * org.onap.aai
+ * ================================================================================
+ * Copyright © 2023 Deutsche Telekom. 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 java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.ws.rs.core.MediaType;
+
+import org.janusgraph.core.SchemaViolationException;
+import org.onap.aai.exceptions.AAIException;
+import org.onap.aai.logging.ErrorLogHelper;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseStatus;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+import org.springframework.web.context.request.WebRequest;
+import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+
+@ControllerAdvice
+public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {
+
+ private static final String AAI_4007 = "AAI_4007";
+
+ @ExceptionHandler({JsonParseException.class, JsonMappingException.class})
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ public ResponseEntity<String> handleJsonException(
+ JsonParseException exception,
+ WebRequest request
+ ){
+ return buildAAIExceptionResponse(new AAIException(AAI_4007, exception));
+ }
+
+ @ExceptionHandler({SchemaViolationException.class})
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ public ResponseEntity<String> handleSchemaViolationException(
+ SchemaViolationException exception,
+ WebRequest request
+ ){
+ return buildAAIExceptionResponse(new AAIException("AAI_4020", exception));
+ }
+
+ @ExceptionHandler({AAIException.class})
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ public ResponseEntity<String> handleAAIException(
+ AAIException exception,
+ WebRequest request
+ ){
+ return buildAAIExceptionResponse(exception);
+ }
+
+ @ExceptionHandler(Exception.class)
+ @ResponseStatus(HttpStatus.BAD_REQUEST)
+ public ResponseEntity<String> handleUnknownException(
+ Exception exception,
+ WebRequest request) {
+ return defaultException(exception);
+ }
+
+ private ResponseEntity<String> buildAAIExceptionResponse(AAIException exception) {
+
+ String body = getResponseBody(exception);
+ return new ResponseEntity<>(body, new HttpHeaders(), HttpStatus.BAD_REQUEST);
+ }
+
+ private String getResponseBody(AAIException exception) {
+ HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes())
+ .getRequest();
+ ArrayList<String> templateVars = new ArrayList<>();
+ templateVars.add(request.getMethod());
+ templateVars.add(request.getRequestURI());
+
+ List<MediaType> mediaTypes = Collections.singletonList(MediaType.APPLICATION_JSON_TYPE);
+ String body = ErrorLogHelper.getRESTAPIErrorResponse(
+ mediaTypes, exception, templateVars);
+ return body;
+ }
+
+ private ResponseEntity<String> defaultException(Exception exception) {
+ return buildAAIExceptionResponse(new AAIException("AAI_4000", exception));
+ }
+}
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 695e125..59d4df1 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
@@ -50,7 +50,7 @@ public class DslQueryProcessor {
private Map<QueryVersion, ParseTreeListener> dslListeners;
private boolean startNodeValidationFlag = true;
private String validationRules = "";
- private String packageName = "org.onap.aai.dsl.";
+ private static final String DSL_BASE_PACKAGE = "org.onap.aai.dsl.";
private static final String LEXER = "AAIDslLexer";
private static final String PARSER = "AAIDslParser";
private static final String EOF_TOKEN = "<EOF>";
@@ -69,8 +69,7 @@ public class DslQueryProcessor {
InputStream stream =
new ByteArrayInputStream(aaiQuery.getBytes(StandardCharsets.UTF_8));
- packageName = packageName + version.toString().toLowerCase() + ".";
-
+ String packageName = DSL_BASE_PACKAGE + version.toString().toLowerCase() + ".";
Class<?> lexerClass = Class.forName(packageName + LEXER);
Class<?> parserClass = Class.forName(packageName + PARSER);
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 f4f3949..0bfbd9d 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
@@ -33,6 +33,7 @@ import java.util.logging.Logger;
import javax.annotation.Priority;
import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.servlet.ServletProperties;
import org.onap.aai.rest.*;
import org.onap.aai.rest.search.ModelAndNamedQueryRestProvider;
import org.onap.aai.rest.search.SearchProvider;
@@ -63,11 +64,12 @@ public class JerseyConfiguration {
public ResourceConfig resourceConfig() {
ResourceConfig resourceConfig = new ResourceConfig();
+ resourceConfig.property(ServletProperties.FILTER_FORWARD_ON_404, true);
Set<Class<?>> classes = Sets.newHashSet(SearchProvider.class,
- ModelAndNamedQueryRestProvider.class, QueryConsumer.class, RecentAPIConsumer.class,
- DslConsumer.class, EchoResponse.class, CQ2Gremlin.class, CQ2GremlinTest.class);
+ ModelAndNamedQueryRestProvider.class, QueryConsumer.class, RecentAPIConsumer.class, EchoResponse.class, CQ2Gremlin.class, CQ2GremlinTest.class);
Set<Class<?>> filterClasses =
- Sets.newHashSet(org.onap.aai.interceptors.pre.RequestTransactionLogging.class,
+ Sets.newHashSet(
+ 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,
@@ -77,9 +79,10 @@ public class JerseyConfiguration {
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.rest.ExceptionHandler.class,
- org.onap.aai.interceptors.post.ResponseHeaderManipulation.class);
+ org.onap.aai.interceptors.post.ResponseHeaderManipulation.class
+ );
resourceConfig.registerClasses(classes);
logger.debug("REGISTERED CLASSES " + classes.toString());
@@ -93,7 +96,7 @@ public class JerseyConfiguration {
}
private <T> void throwIfPriorityAnnotationAbsent(Collection<Class<? extends T>> classes) {
- for (Class clazz : classes) {
+ for (Class<? extends T> clazz : classes) {
if (!clazz.isAnnotationPresent(Priority.class)) {
logger.debug("throwIfPriorityAnnotationAbsent: missing filter priority for : "
+ clazz.getName());
diff --git a/aai-traversal/src/main/java/org/onap/aai/web/WebConfiguration.java b/aai-traversal/src/main/java/org/onap/aai/web/WebConfiguration.java
index a2a4271..2dee807 100644
--- a/aai-traversal/src/main/java/org/onap/aai/web/WebConfiguration.java
+++ b/aai-traversal/src/main/java/org/onap/aai/web/WebConfiguration.java
@@ -19,24 +19,25 @@
*/
package org.onap.aai.web;
-import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import org.springframework.http.MediaType;
+import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
-public class WebConfiguration {
+public class WebConfiguration implements WebMvcConfigurer {
- @Bean
- public WebMvcConfigurerAdapter forwardToIndex() {
- return new WebMvcConfigurerAdapter() {
- @Override
- public void addViewControllers(ViewControllerRegistry registry) {
- registry.addViewController("/swagger").setViewName("redirect:/swagger/index.html");
- registry.addViewController("/swagger/").setViewName("redirect:/swagger/index.html");
- registry.addViewController("/docs").setViewName("redirect:/docs/html/index.html");
- registry.addViewController("/docs/").setViewName("redirect:/docs/html/index.html");
- }
- };
+ @Override
+ public void addViewControllers(ViewControllerRegistry registry) {
+ registry.addViewController("/swagger").setViewName("redirect:/swagger/index.html");
+ registry.addViewController("/swagger/").setViewName("redirect:/swagger/index.html");
+ registry.addViewController("/docs").setViewName("redirect:/docs/html/index.html");
+ registry.addViewController("/docs/").setViewName("redirect:/docs/html/index.html");
+ }
+
+ @Override
+ public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
+ configurer.defaultContentType(MediaType.APPLICATION_JSON);
}
}
diff --git a/aai-traversal/src/main/resources/application.properties b/aai-traversal/src/main/resources/application.properties
index c86fa8a..5242148 100644
--- a/aai-traversal/src/main/resources/application.properties
+++ b/aai-traversal/src/main/resources/application.properties
@@ -8,7 +8,7 @@ spring.application.name=aai-traversal
spring.jersey.type=filter
spring.main.allow-bean-definition-overriding=true
-server.servlet.context-path=/
+server.servlet.context-path=${schema.uri.base.path}
spring.autoconfigure.exclude=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
@@ -16,7 +16,7 @@ spring.autoconfigure.exclude=\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration, \
org.springframework.boot.actuate.autoconfigure.security.servlet.ManagementWebSecurityAutoConfiguration
-spring.jersey.application-path=${schema.uri.base.path}
+spring.jersey.application-path=/
#The max number of active threads in this pool
jetty.threadPool.maxThreads=200