From 33521592f3a466fd5cb6959340c1ec70e412dfa8 Mon Sep 17 00:00:00 2001 From: Fiete Ostkamp Date: Fri, 8 Dec 2023 16:47:19 +0100 Subject: Separate entity retrieval from jax-rs Response creation - move logic to retrieve entity from db into a separate method - do not use runner() from AAI core [1][2] - use global ExceptionHandler to provide a common exception to error response mapping [1] the runner will spawn a separate thread to process the request. In this change there is nothing to replace this functionality. The reason that it is removed is that it tightly couples the app with a) aai-common and b) jax-rs and is also catching all exceptions. Also the timeout mechanism that is implemented is not actually stopping the execution of the thread after the timeout, but rather returning an early response (after 3 minutes(!)). [2] these changes are also done to make a future full migration to spring boot/the removal of jax-rs easier Issue-ID: AAI-3693 Change-Id: I177913c5f6295e1cab476e3c206fecacd7620f69 Signed-off-by: Fiete Ostkamp --- aai-traversal/pom.xml | 6 + .../org/onap/aai/entities/AAIErrorResponse.java | 30 +++ .../java/org/onap/aai/entities/RequestError.java | 30 +++ .../org/onap/aai/entities/ServiceException.java | 34 +++ .../main/java/org/onap/aai/rest/DslConsumer.java | 257 ++++++++++----------- .../java/org/onap/aai/rest/ExceptionHandler.java | 50 ++-- .../main/java/org/onap/aai/rest/QueryConsumer.java | 2 +- .../java/org/onap/aai/rest/TraversalConsumer.java | 6 +- .../java/org/onap/aai/web/JerseyConfiguration.java | 1 + .../java/org/onap/aai/rest/DslConsumerTest.java | 1 + .../org/onap/aai/rest/ExceptionHandlerTest.java | 17 +- 11 files changed, 253 insertions(+), 181 deletions(-) create mode 100644 aai-traversal/src/main/java/org/onap/aai/entities/AAIErrorResponse.java create mode 100644 aai-traversal/src/main/java/org/onap/aai/entities/RequestError.java create mode 100644 aai-traversal/src/main/java/org/onap/aai/entities/ServiceException.java diff --git a/aai-traversal/pom.xml b/aai-traversal/pom.xml index c079cf4..e8a7916 100644 --- a/aai-traversal/pom.xml +++ b/aai-traversal/pom.xml @@ -771,6 +771,12 @@ ${keycloak.version} test + + org.projectlombok + lombok + 1.18.30 + provided + 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 new file mode 100644 index 0000000..b80b83d --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/entities/AAIErrorResponse.java @@ -0,0 +1,30 @@ +/** + * ============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.entities; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class AAIErrorResponse { + private 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 new file mode 100644 index 0000000..4aaf43c --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/entities/RequestError.java @@ -0,0 +1,30 @@ +/** + * ============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.entities; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +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 new file mode 100644 index 0000000..3eb9a21 --- /dev/null +++ b/aai-traversal/src/main/java/org/onap/aai/entities/ServiceException.java @@ -0,0 +1,34 @@ +/** + * ============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.entities; + +import java.util.List; + +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class ServiceException { + private String messageId; + private String text; + private List variables; +} 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 bbb1aea..d814b48 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 @@ -3,6 +3,7 @@ * 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. @@ -19,6 +20,7 @@ */ package org.onap.aai.rest; +import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -78,33 +80,28 @@ import com.google.gson.JsonParser; import io.micrometer.core.annotation.Timed; -@Path("{version: v[1-9][0-9]*|latest}/dsl") @Timed +@Path("{version: v[1-9][0-9]*|latest}/dsl") public class DslConsumer extends TraversalConsumer { - private HttpEntry traversalUriHttpEntry; - - private QueryProcessorType processorType = QueryProcessorType.LOCAL_GROOVY; - private static final Logger LOGGER = LoggerFactory.getLogger(DslConsumer.class); + private static final QueryProcessorType processorType = QueryProcessorType.LOCAL_GROOVY; + private static final QueryVersion DEFAULT_VERSION = QueryVersion.V1; - private DslQueryProcessor dslQueryProcessor; - - private SchemaVersions schemaVersions; - - private String basePath; + 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 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, - XmlFormatTransformer xmlFormatTransformer, - @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; @@ -116,33 +113,28 @@ public class DslConsumer extends TraversalConsumer { @PUT @Consumes({MediaType.APPLICATION_JSON}) @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 HttpServletRequest req, @Context UriInfo info, - @DefaultValue("-1") @QueryParam("resultIndex") String resultIndex, - @DefaultValue("-1") @QueryParam("resultSize") String resultSize) { + 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 roles = this.getRoles(req.getUserPrincipal()); - 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() { - @Override - public Response process() throws Exception { - return (processExecuteQuery(content, req, versionParam, queryFormat, subgraph, - validate, headers, info, resultIndex, resultSize, roles)); - } - }); + return processExecuteQuery(dslQuery, req, versionParam, queryFormat, subgraph, + validate, headers, info, resultIndex, resultSize, roles); } - public Response processExecuteQuery(String content, HttpServletRequest req, String versionParam, - String queryFormat, String subgraph, String validate, HttpHeaders headers, UriInfo info, - String resultIndex, String resultSize, Set roles) { + public Response processExecuteQuery(String dslQuery, HttpServletRequest request, String versionParam, + String queryFormat, String subgraph, String validate, HttpHeaders headers, UriInfo info, + String resultIndex, String resultSize, Set roles) throws FileNotFoundException, AAIException { - String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); - String dslOverride = headers.getRequestHeaders().getFirst("X-DslOverride"); + final SchemaVersion version = new SchemaVersion(versionParam); + final String sourceOfTruth = headers.getRequestHeaders().getFirst("X-FromAppId"); + final String dslOverride = headers.getRequestHeaders().getFirst("X-DslOverride"); Optional dslApiVersionHeader = Optional.ofNullable(headers.getRequestHeaders().getFirst("X-DslApiVersion")); @@ -154,123 +146,110 @@ public class DslConsumer extends TraversalConsumer { } } - Response response; - SchemaVersion version = new SchemaVersion(versionParam); - - TransactionalGraphEngine dbEngine = null; - try { - String serverBase = - req.getRequestURL().toString().replaceAll("/(v[0-9]+|latest)/.*", "/"); - traversalUriHttpEntry.setHttpEntryProperties(version, serverBase); - traversalUriHttpEntry.setPaginationParameters(resultIndex, resultSize); - dbEngine = traversalUriHttpEntry.getDbEngine(); - JsonObject input = JsonParser.parseString(content).getAsJsonObject(); - JsonElement dslElement = input.get("dsl"); - String dsl = ""; - if (dslElement != null) { - dsl = dslElement.getAsString(); - } - - boolean isDslOverride = dslOverride != null - && !AAIConfig.get(TraversalConstants.DSL_OVERRIDE).equals("false") - && dslOverride.equals(AAIConfig.get(TraversalConstants.DSL_OVERRIDE)); + String result = executeQuery(dslQuery, request, queryFormat, subgraph, validate, info.getQueryParameters(), resultIndex, resultSize, + roles, version, sourceOfTruth, dslOverride); - if (isDslOverride) { - dslQueryProcessor.setStartNodeValidationFlag(false); - } - - dslQueryProcessor.setValidationRules(validate); + String acceptType = headers.getHeaderString("Accept"); + if (acceptType == null) { + acceptType = MediaType.APPLICATION_JSON; + } - Format format = Format.getFormat(queryFormat); + if (MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(acceptType))) { + result = xmlFormatTransformer.transform(result); + } - if (isAggregate(format)) { - dslQueryProcessor.setAggregate(true); - } + if (traversalUriHttpEntry.isPaginated()) { + return Response.status(Status.OK).type(acceptType) + .header("total-results", traversalUriHttpEntry.getTotalVertices()) + .header("total-pages", traversalUriHttpEntry.getTotalPaginationBuckets()) + .entity(result).build(); + } else { + return Response.status(Status.OK).type(acceptType).entity(result).build(); + } + } - if (isHistory(format)) { - validateHistoryParams(format, info.getQueryParameters()); - } + private String executeQuery(String content, HttpServletRequest req, String queryFormat, String subgraph, + String validate, MultivaluedMap queryParameters, String resultIndex, String resultSize, Set roles, + final SchemaVersion version, final String sourceOfTruth, final String dslOverride) + throws AAIException, FileNotFoundException { + final String serverBase = + 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"); + String dsl = ""; + if (dslElement != null) { + dsl = dslElement.getAsString(); + } - GraphTraversalSource traversalSource = - getTraversalSource(dbEngine, format, info, roles); + boolean isDslOverride = dslOverride != null + && !AAIConfig.get(TraversalConstants.DSL_OVERRIDE).equals("false") + && dslOverride.equals(AAIConfig.get(TraversalConstants.DSL_OVERRIDE)); - GenericQueryProcessor processor = - new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton) - .queryFrom(dsl, "dsl").queryProcessor(dslQueryProcessor).version(dslApiVersion) - .processWith(processorType).format(format).uriParams(info.getQueryParameters()) - .traversalSource(isHistory(format), traversalSource).create(); + if (isDslOverride) { + dslQueryProcessor.setStartNodeValidationFlag(false); + } - SubGraphStyle subGraphStyle = SubGraphStyle.valueOf(subgraph); - List vertTemp = processor.execute(subGraphStyle); + dslQueryProcessor.setValidationRules(validate); - // Dedup if duplicate objects are returned in each array in the aggregate format - // scenario. - List vertTempDedupedObjectList = dedupObjectInAggregateFormatResult(vertTemp); + Format format = Format.getFormat(queryFormat); - List vertices; - if (isAggregate(format)) { - vertices = traversalUriHttpEntry - .getPaginatedVertexListForAggregateFormat(vertTempDedupedObjectList); - } else { - vertices = traversalUriHttpEntry.getPaginatedVertexList(vertTemp); - } + if (isAggregate(format)) { + dslQueryProcessor.setAggregate(true); + } - DBSerializer serializer = - new DBSerializer(version, dbEngine, ModelType.MOXY, sourceOfTruth); - FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, - schemaVersions, this.basePath, serverBase); + if (isHistory(format)) { + validateHistoryParams(format, queryParameters); + } - MultivaluedMap 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> propertiesMap = processor.getPropertiesMap(); - String result = ""; - if (propertiesMap != null && !propertiesMap.isEmpty()) { - result = formatter.output(vertices, propertiesMap).toString(); - } else { - result = formatter.output(vertices).toString(); - } + GraphTraversalSource traversalSource = + getTraversalSource(dbEngine, format, queryParameters, roles); - String acceptType = headers.getHeaderString("Accept"); + GenericQueryProcessor processor = + new GenericQueryProcessor.Builder(dbEngine, gremlinServerSingleton) + .queryFrom(dsl, "dsl").queryProcessor(dslQueryProcessor).version(dslApiVersion) + .processWith(processorType).format(format).uriParams(queryParameters) + .traversalSource(isHistory(format), traversalSource).create(); - if (acceptType == null) { - acceptType = MediaType.APPLICATION_JSON; - } + SubGraphStyle subGraphStyle = SubGraphStyle.valueOf(subgraph); + List vertTemp = processor.execute(subGraphStyle); - if (MediaType.APPLICATION_XML_TYPE.isCompatible(MediaType.valueOf(acceptType))) { - result = xmlFormatTransformer.transform(result); - } + // Dedup if duplicate objects are returned in each array in the aggregate format + // scenario. + List vertTempDedupedObjectList = dedupObjectInAggregateFormatResult(vertTemp); - if (traversalUriHttpEntry.isPaginated()) { - response = Response.status(Status.OK).type(acceptType) - .header("total-results", traversalUriHttpEntry.getTotalVertices()) - .header("total-pages", traversalUriHttpEntry.getTotalPaginationBuckets()) - .entity(result).build(); - } else { - response = Response.status(Status.OK).type(acceptType).entity(result).build(); - } + List vertices; + if (isAggregate(format)) { + vertices = traversalUriHttpEntry + .getPaginatedVertexListForAggregateFormat(vertTempDedupedObjectList); + } else { + vertices = traversalUriHttpEntry.getPaginatedVertexList(vertTemp); + } - } catch (AAIException e) { - response = consumerExceptionResponseGenerator(headers, info, HttpMethod.PUT, e); - } catch (SchemaViolationException sve) { - AAIException ex = new AAIException("AAI_4020", sve); - response = consumerExceptionResponseGenerator(headers, info, HttpMethod.PUT, ex); - } catch (Exception e) { - AAIException ex = new AAIException("AAI_4000", e); - response = consumerExceptionResponseGenerator(headers, info, HttpMethod.PUT, ex); - } finally { - if (dbEngine != null) { - dbEngine.rollback(); - } + DBSerializer serializer = + new DBSerializer(version, dbEngine, ModelType.MOXY, sourceOfTruth); + FormatFactory ff = new FormatFactory(traversalUriHttpEntry.getLoader(), serializer, + schemaVersions, this.basePath, serverBase); + MultivaluedMap mvm = new MultivaluedHashMap<>(); + mvm.putAll(queryParameters); + if (isHistory(format)) { + mvm.putSingle("startTs", Long.toString(getStartTime(format, mvm))); + mvm.putSingle("endTs", Long.toString(getEndTime(mvm))); } - - return response; + Formatter formatter = ff.get(format, mvm); + + final Map> propertiesMap = processor.getPropertiesMap(); + String result = ""; + if (propertiesMap != null && !propertiesMap.isEmpty()) { + result = formatter.output(vertices, propertiesMap).toString(); + } else { + result = formatter.output(vertices).toString(); + } + return result; } private List dedupObjectInAggregateFormatResult(List vertTemp) { @@ -280,7 +259,7 @@ public class DslConsumer extends TraversalConsumer { Object o = itr.next(); if (o instanceof ArrayList) { vertTempDedupedObjectList - .add(((ArrayList) o).stream().distinct().collect(Collectors.toList())); + .add(((ArrayList) o).stream().distinct().collect(Collectors.toList())); } } return vertTempDedupedObjectList; 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 index f15e375..447ecdd 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/ExceptionHandler.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/ExceptionHandler.java @@ -26,6 +26,7 @@ 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; @@ -35,6 +36,7 @@ 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; @@ -42,6 +44,7 @@ import org.onap.aai.logging.ErrorLogHelper; * The Class ExceptionHandler. */ @Provider +@Priority(10000) public class ExceptionHandler implements ExceptionMapper { private static final String AAI_4007 = "AAI_4007"; @@ -58,47 +61,30 @@ public class ExceptionHandler implements ExceptionMapper { // with a linked exception if (exception instanceof WebApplicationException) { if (exception.getCause() instanceof SAXParseException2) { - return buildInputParsingErrorResponse(exception, "UnmarshalException"); + return buildAAIExceptionResponse(new AAIException(AAI_4007, exception)); } else { - return ((WebApplicationException)exception).getResponse(); + return ((WebApplicationException) exception).getResponse(); } } else if (exception instanceof JsonParseException) { // jackson does it differently so we get the direct JsonParseException - return buildInputParsingErrorResponse(exception); + return buildAAIExceptionResponse(new AAIException(AAI_4007, exception)); } else if (exception instanceof JsonMappingException) { // jackson does it differently so we get the direct JsonParseException - return buildInputParsingErrorResponse(exception); + 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 buildInputParsingErrorResponse(Exception exception) { - ArrayList templateVars = new ArrayList<>(); - templateVars.add(exception.getClass().getSimpleName()); - return buildInputParsingErrorResponse(exception, templateVars); - } - - private Response buildInputParsingErrorResponse(Exception exception, String customExceptionName) { - ArrayList templateVars = new ArrayList<>(); - templateVars.add(customExceptionName); - return buildInputParsingErrorResponse(exception, templateVars); - } - - private Response buildInputParsingErrorResponse(Exception exception, ArrayList templateVars) { - AAIException ex = new AAIException(AAI_4007, exception); - return Response - .status(400).entity(ErrorLogHelper - .getRESTAPIErrorResponse(headers.getAcceptableMediaTypes(), ex, templateVars)) - .build(); - } - - private Response defaultException(Exception exception) { + private Response buildAAIExceptionResponse(AAIException exception) { ArrayList templateVars = new ArrayList<>(); templateVars.add(request.getMethod()); - templateVars.add("unknown"); - AAIException ex = new AAIException("AAI_4000", exception); + templateVars.add(request.getRequestURI()); // prefer xml, use json otherwise return headers.getAcceptableMediaTypes().stream() @@ -107,12 +93,16 @@ public class ExceptionHandler implements ExceptionMapper { .map(xmlType -> Response.status(400).type(MediaType.APPLICATION_XML_TYPE) .entity(ErrorLogHelper.getRESTAPIErrorResponse( - headers.getAcceptableMediaTypes(), ex, templateVars)) + headers.getAcceptableMediaTypes(), exception, templateVars)) .build()) .orElseGet(() -> Response.status(400).type(MediaType.APPLICATION_JSON_TYPE) .entity(ErrorLogHelper.getRESTAPIErrorResponse( - headers.getAcceptableMediaTypes(), ex, templateVars)) + 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/QueryConsumer.java b/aai-traversal/src/main/java/org/onap/aai/rest/QueryConsumer.java index cade20c..5a2e19f 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 @@ -215,7 +215,7 @@ public class QueryConsumer extends TraversalConsumer { validateHistoryParams(format, info.getQueryParameters()); } GraphTraversalSource traversalSource = - getTraversalSource(dbEngine, format, info, roles); + getTraversalSource(dbEngine, format, info.getQueryParameters(), roles); QueryStyle queryStyle = getQueryStyle(format, traversalUriHttpEntry); if (!startURIs.isEmpty()) { 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 index 2980f28..bc74308 100644 --- a/aai-traversal/src/main/java/org/onap/aai/rest/TraversalConsumer.java +++ b/aai-traversal/src/main/java/org/onap/aai/rest/TraversalConsumer.java @@ -131,12 +131,12 @@ public abstract class TraversalConsumer extends RESTAPI { } protected GraphTraversalSource getTraversalSource(TransactionalGraphEngine dbEngine, - Format format, UriInfo info, Set roles) throws AAIException { + Format format, MultivaluedMap queryParameters, Set roles) throws AAIException { GraphTraversalSource traversalSource; if (isHistory(format)) { - long localStartTime = this.getStartTime(format, info.getQueryParameters()); - long localEndTime = this.getEndTime(info.getQueryParameters()); + long localStartTime = this.getStartTime(format, queryParameters); + long localEndTime = this.getEndTime(queryParameters); traversalSource = dbEngine.asAdmin().getTraversalSource() .withStrategies(getSubgraphStrategy(localStartTime, localEndTime, format)); } else { 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 feb8d1d..f4f3949 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 @@ -78,6 +78,7 @@ public class JerseyConfiguration { 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); resourceConfig.registerClasses(classes); logger.debug("REGISTERED CLASSES " + classes.toString()); diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/DslConsumerTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/DslConsumerTest.java index 81f47b1..ac6b749 100644 --- a/aai-traversal/src/test/java/org/onap/aai/rest/DslConsumerTest.java +++ b/aai-traversal/src/test/java/org/onap/aai/rest/DslConsumerTest.java @@ -267,6 +267,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { assertEquals("SVC6152", response.getBody().getRequestError().getServiceException().getMessageId()); assertEquals("DSL Generic Error (msg=%1) (ec=%2)", response.getBody().getRequestError().getServiceException().getText()); assertEquals("DSL Generic Error:Error while processing the query: org.onap.aai.exceptions.AAIException: No nodes marked for output", response.getBody().getRequestError().getServiceException().getVariables().get(0)); + assertEquals("/aai/v11/dsl", response.getBody().getRequestError().getServiceException().getVariables().get(3)); } @Test diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/ExceptionHandlerTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/ExceptionHandlerTest.java index c7314bc..bed964e 100644 --- a/aai-traversal/src/test/java/org/onap/aai/rest/ExceptionHandlerTest.java +++ b/aai-traversal/src/test/java/org/onap/aai/rest/ExceptionHandlerTest.java @@ -81,6 +81,7 @@ public class ExceptionHandlerTest { when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes); when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap); when(request.getMethod()).thenReturn("PUT"); + when(request.getRequestURI()).thenReturn("/aai/v14/dsl"); } @Test @@ -108,8 +109,8 @@ public class ExceptionHandlerTest { assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); assertEquals("SVC3102",responseEntity.getRequestError().getServiceException().getMessageId()); assertEquals("Error parsing input performing %1 on %2 (msg=%3) (ec=%4)",responseEntity.getRequestError().getServiceException().getText()); - assertEquals("UnmarshalException",responseEntity.getRequestError().getServiceException().getVariables().get(0)); - assertEquals("null",responseEntity.getRequestError().getServiceException().getVariables().get(1)); + assertEquals("PUT",responseEntity.getRequestError().getServiceException().getVariables().get(0)); + assertEquals("/aai/v14/dsl",responseEntity.getRequestError().getServiceException().getVariables().get(1)); assertEquals("Input parsing error:javax.ws.rs.WebApplicationException: HTTP 500 Internal Server Error",responseEntity.getRequestError().getServiceException().getVariables().get(2)); assertEquals("ERR.5.4.4007",responseEntity.getRequestError().getServiceException().getVariables().get(3)); } @@ -127,8 +128,8 @@ public class ExceptionHandlerTest { assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); assertEquals("SVC3102",responseEntity.getRequestError().getServiceException().getMessageId()); assertEquals("Error parsing input performing %1 on %2 (msg=%3) (ec=%4)",responseEntity.getRequestError().getServiceException().getText()); - assertEquals("JsonParseException",responseEntity.getRequestError().getServiceException().getVariables().get(0)); - assertEquals("null",responseEntity.getRequestError().getServiceException().getVariables().get(1)); + assertEquals("PUT",responseEntity.getRequestError().getServiceException().getVariables().get(0)); + assertEquals("/aai/v14/dsl",responseEntity.getRequestError().getServiceException().getVariables().get(1)); assertEquals("Input parsing error:com.fasterxml.jackson.core.JsonParseException: ",responseEntity.getRequestError().getServiceException().getVariables().get(2)); assertEquals("ERR.5.4.4007",responseEntity.getRequestError().getServiceException().getVariables().get(3)); } @@ -145,8 +146,8 @@ public class ExceptionHandlerTest { assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); assertEquals("SVC3102",responseEntity.getRequestError().getServiceException().getMessageId()); assertEquals("Error parsing input performing %1 on %2 (msg=%3) (ec=%4)",responseEntity.getRequestError().getServiceException().getText()); - assertEquals("JsonMappingException",responseEntity.getRequestError().getServiceException().getVariables().get(0)); - assertEquals("null",responseEntity.getRequestError().getServiceException().getVariables().get(1)); + assertEquals("PUT",responseEntity.getRequestError().getServiceException().getVariables().get(0)); + assertEquals("/aai/v14/dsl",responseEntity.getRequestError().getServiceException().getVariables().get(1)); assertEquals("Input parsing error:com.fasterxml.jackson.databind.JsonMappingException: ",responseEntity.getRequestError().getServiceException().getVariables().get(2)); assertEquals("ERR.5.4.4007",responseEntity.getRequestError().getServiceException().getVariables().get(3)); } @@ -164,7 +165,7 @@ public class ExceptionHandlerTest { assertEquals("SVC3002",responseEntity.getRequestError().getServiceException().getMessageId()); assertEquals("Error writing output performing %1 on %2 (msg=%3) (ec=%4)",responseEntity.getRequestError().getServiceException().getText()); assertEquals("PUT",responseEntity.getRequestError().getServiceException().getVariables().get(0)); - assertEquals("unknown",responseEntity.getRequestError().getServiceException().getVariables().get(1)); + assertEquals("/aai/v14/dsl",responseEntity.getRequestError().getServiceException().getVariables().get(1)); assertEquals("Internal Error:java.lang.Exception",responseEntity.getRequestError().getServiceException().getVariables().get(2)); assertEquals("ERR.5.4.4000",responseEntity.getRequestError().getServiceException().getVariables().get(3)); } @@ -186,7 +187,7 @@ public class ExceptionHandlerTest { assertEquals("SVC3002",responseEntity.getRequestError().getServiceException().getMessageId()); assertEquals("Error writing output performing %1 on %2 (msg=%3) (ec=%4)",responseEntity.getRequestError().getServiceException().getText()); assertEquals("PUT",responseEntity.getRequestError().getServiceException().getVariables().get(0)); - assertEquals("unknown",responseEntity.getRequestError().getServiceException().getVariables().get(1)); + assertEquals("/aai/v14/dsl",responseEntity.getRequestError().getServiceException().getVariables().get(1)); assertEquals("Internal Error:java.lang.Exception",responseEntity.getRequestError().getServiceException().getVariables().get(2)); assertEquals("ERR.5.4.4000",responseEntity.getRequestError().getServiceException().getVariables().get(3)); } -- cgit 1.2.3-korg