From 6d7077ca105bad3593881db079ef2b5eb1aaa6b1 Mon Sep 17 00:00:00 2001 From: Fiete Ostkamp Date: Mon, 18 Dec 2023 11:12:30 +0100 Subject: 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 --- .../org/onap/aai/entities/AAIErrorResponse.java | 4 +- .../java/org/onap/aai/entities/RequestError.java | 2 + .../org/onap/aai/entities/ServiceException.java | 2 + .../post/ResponseTransactionLogging.java | 29 +-- .../pre/RequestTransactionLogging.java | 43 ++-- .../main/java/org/onap/aai/rest/DslConsumer.java | 143 +++++++------ .../java/org/onap/aai/rest/ExceptionHandler.java | 108 ---------- .../org/onap/aai/rest/GlobalExceptionHandler.java | 109 ++++++++++ .../org/onap/aai/rest/dsl/DslQueryProcessor.java | 5 +- .../java/org/onap/aai/web/JerseyConfiguration.java | 15 +- .../java/org/onap/aai/web/WebConfiguration.java | 29 +-- .../src/main/resources/application.properties | 4 +- .../org/onap/aai/entities/AAIErrorResponse.java | 33 --- .../java/org/onap/aai/entities/RequestError.java | 33 --- .../org/onap/aai/entities/ServiceException.java | 53 ----- .../java/org/onap/aai/rest/DslConsumerTest.java | 86 +++++--- .../org/onap/aai/rest/ExceptionHandlerTest.java | 224 --------------------- .../onap/aai/rest/SpringExceptionHandlerTest.java | 127 ++++++++++++ .../src/test/resources/application-test.properties | 4 +- 19 files changed, 433 insertions(+), 620 deletions(-) delete mode 100644 aai-traversal/src/main/java/org/onap/aai/rest/ExceptionHandler.java create mode 100644 aai-traversal/src/main/java/org/onap/aai/rest/GlobalExceptionHandler.java delete mode 100644 aai-traversal/src/test/java/org/onap/aai/entities/AAIErrorResponse.java delete mode 100644 aai-traversal/src/test/java/org/onap/aai/entities/RequestError.java delete mode 100644 aai-traversal/src/test/java/org/onap/aai/entities/ServiceException.java delete mode 100644 aai-traversal/src/test/java/org/onap/aai/rest/ExceptionHandlerTest.java create mode 100644 aai-traversal/src/test/java/org/onap/aai/rest/SpringExceptionHandlerTest.java (limited to 'aai-traversal') 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 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 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 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 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 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 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 processExecuteQuery(String dslQuery, HttpServletRequest request, String versionParam, + String queryFormat, String subgraph, String validate, HttpHeaders headers, String resultIndex, String resultSize, Set 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 queryParams = toMultivaluedMap(request.getParameterMap()); Optional 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 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 vertTemp = processor.execute(subGraphStyle); - // Dedup if duplicate objects are returned in each array in the aggregate format - // scenario. - List vertTempDedupedObjectList = dedupObjectInAggregateFormatResult(vertTemp); - List vertices; if (isAggregate(format)) { + // Dedup if duplicate objects are returned in each array in the aggregate format + // scenario. + List vertTempDedupedObjectList = dedupObjectInAggregateFormatResult(vertTemp); vertices = traversalUriHttpEntry .getPaginatedVertexListForAggregateFormat(vertTempDedupedObjectList); } else { @@ -252,6 +260,12 @@ public class DslConsumer extends TraversalConsumer { return result; } + private List dedupObjectInAggregateFormatResultStreams(List vertTemp) { + return vertTemp.stream() + .filter(o -> o instanceof ArrayList) + .map(o -> ((ArrayList) o).stream().distinct().collect(Collectors.toList())) + .collect(Collectors.toList()); + } private List dedupObjectInAggregateFormatResult(List vertTemp) { List vertTempDedupedObjectList = new ArrayList(); Iterator itr = vertTemp.listIterator(); @@ -264,4 +278,15 @@ public class DslConsumer extends TraversalConsumer { } return vertTempDedupedObjectList; } + + private MultivaluedMap toMultivaluedMap(Map map) { + MultivaluedMap multivaluedMap = new MultivaluedHashMap<>(); + + for (Map.Entry 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 { - - 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 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 handleJsonException( + JsonParseException exception, + WebRequest request + ){ + return buildAAIExceptionResponse(new AAIException(AAI_4007, exception)); + } + + @ExceptionHandler({SchemaViolationException.class}) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseEntity handleSchemaViolationException( + SchemaViolationException exception, + WebRequest request + ){ + return buildAAIExceptionResponse(new AAIException("AAI_4020", exception)); + } + + @ExceptionHandler({AAIException.class}) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseEntity handleAAIException( + AAIException exception, + WebRequest request + ){ + return buildAAIExceptionResponse(exception); + } + + @ExceptionHandler(Exception.class) + @ResponseStatus(HttpStatus.BAD_REQUEST) + public ResponseEntity handleUnknownException( + Exception exception, + WebRequest request) { + return defaultException(exception); + } + + private ResponseEntity 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 templateVars = new ArrayList<>(); + templateVars.add(request.getMethod()); + templateVars.add(request.getRequestURI()); + + List mediaTypes = Collections.singletonList(MediaType.APPLICATION_JSON_TYPE); + String body = ErrorLogHelper.getRESTAPIErrorResponse( + mediaTypes, exception, templateVars); + return body; + } + + private ResponseEntity 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 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 = ""; @@ -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> 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> 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 void throwIfPriorityAnnotationAbsent(Collection> classes) { - for (Class clazz : classes) { + for (Class 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 diff --git a/aai-traversal/src/test/java/org/onap/aai/entities/AAIErrorResponse.java b/aai-traversal/src/test/java/org/onap/aai/entities/AAIErrorResponse.java deleted file mode 100644 index 6d85ed9..0000000 --- a/aai-traversal/src/test/java/org/onap/aai/entities/AAIErrorResponse.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * ============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; - -public class AAIErrorResponse { - private RequestError requestError; - - public RequestError getRequestError() { - return requestError; - } - - public void setRequestError(RequestError requestError) { - this.requestError = requestError; - } -} diff --git a/aai-traversal/src/test/java/org/onap/aai/entities/RequestError.java b/aai-traversal/src/test/java/org/onap/aai/entities/RequestError.java deleted file mode 100644 index 4de0398..0000000 --- a/aai-traversal/src/test/java/org/onap/aai/entities/RequestError.java +++ /dev/null @@ -1,33 +0,0 @@ -/** - * ============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; - -public class RequestError { - private ServiceException serviceException; - - public ServiceException getServiceException() { - return serviceException; - } - - public void setServiceException(ServiceException serviceException) { - this.serviceException = serviceException; - } -} diff --git a/aai-traversal/src/test/java/org/onap/aai/entities/ServiceException.java b/aai-traversal/src/test/java/org/onap/aai/entities/ServiceException.java deleted file mode 100644 index b9cb000..0000000 --- a/aai-traversal/src/test/java/org/onap/aai/entities/ServiceException.java +++ /dev/null @@ -1,53 +0,0 @@ -/** - * ============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; - -public class ServiceException { - private String messageId; - private String text; - private List variables; - - public String getMessageId() { - return messageId; - } - - public void setMessageId(String messageId) { - this.messageId = messageId; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - public List getVariables() { - return variables; - } - - public void setVariables(List variables) { - this.variables = variables; - } -} 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 ac6b749..a4fb0a7 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 @@ -29,8 +29,11 @@ import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource; @@ -199,9 +202,26 @@ public class DslConsumerTest extends AbstractSpringRestTest { responseEntity.getStatusCode()); // Make sure that there are no two result - assertThat(responseEntity.getBody().toString(), + assertThat(responseEntity.getBody(), is(not(containsString("")))); - assertThat(responseEntity.getBody().toString(), is(containsString(""))); + assertThat(responseEntity.getBody(), is(containsString(""))); + } + + @Test + public void thatWildcardContentTypeCanBeUsed() throws Exception { + + String endpoint = "/aai/v14/dsl?format=console"; + Map dslQueryMap = new HashMap<>(); + dslQueryMap.put("dsl-query", "pserver*('hostname','test-pserver-dsl')"); + String payload = PayloadUtil.getTemplatePayload("dsl-query.json", dslQueryMap); + headers.add("X-Dsl-Version", "V1"); + headers.setAccept(Arrays.asList(MediaType.ALL)); + httpEntity = new HttpEntity(payload, headers); + ResponseEntity responseEntity = + restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); + + JsonObject result = JsonParser.parseString(responseEntity.getBody()).getAsJsonObject(); + assertEquals(1, result.get("results").getAsJsonArray().size()); } @Test @@ -230,9 +250,9 @@ public class DslConsumerTest extends AbstractSpringRestTest { responseEntity.getStatusCode()); // Make sure that there are no two result - assertThat(responseEntity.getBody().toString(), + assertThat(responseEntity.getBody(), is(not(containsString("")))); - assertThat(responseEntity.getBody().toString(), is(containsString(""))); + assertThat(responseEntity.getBody(), is(containsString(""))); } @Test @@ -333,7 +353,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); @@ -361,7 +381,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); @@ -388,7 +408,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); @@ -415,7 +435,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); @@ -443,7 +463,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); @@ -470,7 +490,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); @@ -497,7 +517,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); JsonArray resultsArray = results.get("results").getAsJsonArray(); @@ -540,7 +560,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); JsonArray resultsArray = results.get("results").getAsJsonArray(); @@ -585,7 +605,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); JsonArray resultsArray = results.get("results").getAsJsonArray(); @@ -618,7 +638,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); JsonArray resultsArray = results.get("results").getAsJsonArray(); @@ -645,7 +665,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); JsonArray resultsArray = results.get("results").getAsJsonArray(); @@ -669,7 +689,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); Assert.assertTrue(responseString.contains( "Value ['test'] is not an instance of the expected data type for property key ['number-of-cpus'] and cannot be converted. " + "Expected: class java.lang.Integer, found: class java.lang.String")); @@ -687,7 +707,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); @@ -709,7 +729,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Extract the properties array from the response and compare in assert statements JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); @@ -740,7 +760,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); // pnf should have no results + String responseString = responseEntity.getBody(); // pnf should have no results JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); JsonArray resultsArray = results.get("results").getAsJsonArray(); @@ -778,7 +798,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); JsonObject results = JsonParser.parseString(responseString).getAsJsonObject(); JsonArray resultsArray = results.get("results").getAsJsonArray(); @@ -809,7 +829,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Confirm that the vserver was returned in the response Assert.assertTrue(responseString.contains("\"vserver-id\":\"test-vserver-id-2\"")); @@ -825,7 +845,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - responseString = responseEntity.getBody().toString(); + responseString = responseEntity.getBody(); // Confirm that the vserver was returned in the response Assert.assertTrue(responseString.contains("\"vserver-id\":\"test-vserver-id-2\"")); } @@ -844,7 +864,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Confirm that the l-interface was returned in the response Assert.assertTrue(responseString.contains("\"interface-name\":\"test-interface-name-02\"")); } @@ -863,7 +883,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Confirm that the l-interface was returned in the response Assert.assertTrue(responseString.contains("\"interface-name\":\"test-interface-name-02\"")); } @@ -882,7 +902,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Confirm that the l-interface was returned in the response Assert .assertTrue(!responseString.contains("\"interface-name\":\"test-interface-name-02\"")); @@ -902,7 +922,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Confirm that the l-interface was returned in the response Assert .assertTrue(!responseString.contains("\"interface-name\":\"test-interface-name-02\"")); @@ -922,7 +942,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Confirm that the l-interface was returned in the response Assert .assertTrue(!responseString.contains("\"interface-name\":\"test-interface-name-02\"")); @@ -941,7 +961,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Confirm that the l-interface was returned in the response Assert.assertTrue(responseString.contains("\"interface-name\":\"test-interface-name-02\"")); @@ -956,7 +976,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - responseString = responseEntity.getBody().toString(); + responseString = responseEntity.getBody(); // Confirm that the l-interface was returned in the response Assert.assertTrue(responseString.contains("\"interface-name\":\"test-interface-name-02\"")); @@ -975,7 +995,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Confirm that the oam-network was returned in the response Assert.assertTrue(responseString.contains("\"cvlan-tag\":456")); @@ -989,7 +1009,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - responseString = responseEntity.getBody().toString(); + responseString = responseEntity.getBody(); // Confirm that the oam-network was returned in the response Assert.assertTrue(responseString.contains("\"cvlan-tag\":456")); @@ -1008,7 +1028,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); ResponseEntity responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - String responseString = responseEntity.getBody().toString(); + String responseString = responseEntity.getBody(); // Confirm that the pserver was returned in the response Assert.assertTrue(responseString.contains("\"number-of-cpus\":364")); @@ -1022,7 +1042,7 @@ public class DslConsumerTest extends AbstractSpringRestTest { httpEntity = new HttpEntity(payload, headers); responseEntity = restTemplate.exchange(baseUrl + endpoint, HttpMethod.PUT, httpEntity, String.class); - responseString = responseEntity.getBody().toString(); + responseString = responseEntity.getBody(); // Confirm that the pserver was returned in the response Assert.assertTrue(responseString.contains("\"number-of-cpus\":364")); 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 deleted file mode 100644 index bed964e..0000000 --- a/aai-traversal/src/test/java/org/onap/aai/rest/ExceptionHandlerTest.java +++ /dev/null @@ -1,224 +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 static org.junit.Assert.*; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.core.JsonParser; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.dataformat.xml.XmlMapper; -import com.sun.istack.SAXParseException2; - -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedHashMap; -import javax.ws.rs.core.Response; - -import org.junit.Before; -import org.junit.Test; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.onap.aai.entities.AAIErrorResponse; - -public class ExceptionHandlerTest { - - protected static final MediaType APPLICATION_JSON = MediaType.valueOf("application/json"); - - private static final ObjectMapper objectMapper = new ObjectMapper(); - - @Mock - private HttpHeaders httpHeaders; - - @Mock - private HttpServletRequest request; - - @InjectMocks - private ExceptionHandler handler = new ExceptionHandler(); - - @Before - public void setup() { - MockitoAnnotations.initMocks(this); - - MultivaluedHashMap headersMultiMap = new MultivaluedHashMap<>(); - - headersMultiMap.add("X-FromAppId", "JUNIT"); - headersMultiMap.add("X-TransactionId", UUID.randomUUID().toString()); - headersMultiMap.add("Real-Time", "true"); - headersMultiMap.add("Accept", "application/json"); - headersMultiMap.add("aai-request-context", ""); - - List outputMediaTypes = new ArrayList<>(); - outputMediaTypes.add(APPLICATION_JSON); - when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes); - when(httpHeaders.getRequestHeaders()).thenReturn(headersMultiMap); - when(request.getMethod()).thenReturn("PUT"); - when(request.getRequestURI()).thenReturn("/aai/v14/dsl"); - } - - @Test - public void testConversionOfWebApplicationResponse() throws Exception { - - Exception exception = new WebApplicationException(); - Response response = handler.toResponse(exception); - - assertNotNull(response); - assertNull(response.getEntity()); - assertEquals(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus()); - } - - @Test - public void testConversionOfWebApplicationResponseWhenUmarshalExceptionResultBadRequest() - throws Exception { - - SAXParseException2 mockSaxParseException = mock(SAXParseException2.class); - Exception exception = new WebApplicationException(mockSaxParseException); - Response response = handler.toResponse(exception); - AAIErrorResponse responseEntity = objectMapper.readValue(response.getEntity().toString(), AAIErrorResponse.class); - - assertNotNull(response); - assertNotNull(response.getEntity()); - 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("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)); - } - - @Test - public void testConversionWhenJsonParseExceptionResultBadRequest() throws Exception { - - JsonParser jsonParser = mock(JsonParser.class); - Exception exception = new JsonParseException(jsonParser, ""); - Response response = handler.toResponse(exception); - AAIErrorResponse responseEntity = objectMapper.readValue(response.getEntity().toString(), AAIErrorResponse.class); - - assertNotNull(response); - assertNotNull(response.getEntity()); - 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("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)); - } - - @Test - public void testConversionWhenJsonMappingExceptionResultBadRequest() throws Exception { - JsonParser jsonParser = mock(JsonParser.class); - Exception exception = JsonMappingException.from(jsonParser,""); - Response response = handler.toResponse(exception); - AAIErrorResponse responseEntity = objectMapper.readValue(response.getEntity().toString(), AAIErrorResponse.class); - - assertNotNull(response); - assertNotNull(response.getEntity()); - 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("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)); - } - - @Test - public void testJsonDefaultErrorResponse() - throws Exception { - Exception exception = new Exception(); - Response response = handler.toResponse(exception); - AAIErrorResponse responseEntity = objectMapper.readValue(response.getEntity().toString(), AAIErrorResponse.class); - - assertNotNull(response); - assertNotNull(response.getEntity()); - assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); - 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("/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)); - } - - @Test - public void testXmlDefaultErrorResponse() - throws Exception { - List outputMediaTypes = new ArrayList<>(); - outputMediaTypes.add(MediaType.APPLICATION_XML_TYPE); - when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes); - Exception exception = new Exception(); - Response response = handler.toResponse(exception); - XmlMapper xmlMapper = new XmlMapper(); - AAIErrorResponse responseEntity = xmlMapper.readValue(response.getEntity().toString(), AAIErrorResponse.class); - - assertNotNull(response); - assertNotNull(response.getEntity()); - assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); - 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("/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)); - } - - @Test - public void testConversionWhenUnknownExceptionResultBadRequest() throws Exception { - - Exception exception = mock(Exception.class); - Response response = handler.toResponse(exception); - - when(request.getMethod()).thenReturn("GET"); - - assertNotNull(response); - assertNotNull(response.getEntity()); - assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); - } - - @Test - public void testConversionWhenUnknownExceptionResultBadRequestForXmlResponseType() - throws Exception { - - List outputMediaTypes = new ArrayList<>(); - outputMediaTypes.add(MediaType.valueOf("application/xml")); - when(request.getMethod()).thenReturn("GET"); - when(httpHeaders.getAcceptableMediaTypes()).thenReturn(outputMediaTypes); - - Exception exception = mock(Exception.class); - Response response = handler.toResponse(exception); - - assertNotNull(response); - assertNotNull(response.getEntity()); - assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), response.getStatus()); - } -} diff --git a/aai-traversal/src/test/java/org/onap/aai/rest/SpringExceptionHandlerTest.java b/aai-traversal/src/test/java/org/onap/aai/rest/SpringExceptionHandlerTest.java new file mode 100644 index 0000000..b3d1ac9 --- /dev/null +++ b/aai-traversal/src/test/java/org/onap/aai/rest/SpringExceptionHandlerTest.java @@ -0,0 +1,127 @@ +/** + * ============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 static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import javax.servlet.http.HttpServletRequest; + +import org.janusgraph.core.SchemaViolationException; +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.onap.aai.entities.AAIErrorResponse; +import org.onap.aai.exceptions.AAIException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.context.request.RequestContextHolder; +import org.springframework.web.context.request.ServletRequestAttributes; +import org.springframework.web.context.request.WebRequest; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +public class SpringExceptionHandlerTest { + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + @InjectMocks + private GlobalExceptionHandler springExceptionHandler; + + @Mock RequestContextHolder requestContextHolder; + + @Mock + private WebRequest webRequest; + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + HttpServletRequest request = mock(HttpServletRequest.class); + when(request.getMethod()).thenReturn("PUT"); + when(request.getRequestURI()).thenReturn("/aai/v14/dsl"); + RequestContextHolder.setRequestAttributes(new ServletRequestAttributes(request)); + } + + @Test + public void testHandleJsonParseException() throws JsonMappingException, JsonProcessingException { + JsonParser jsonParser = mock(JsonParser.class); + JsonParseException exception = new JsonParseException(jsonParser, ""); + ResponseEntity response = springExceptionHandler.handleJsonException(exception, webRequest); + AAIErrorResponse responseEntity = objectMapper.readValue(response.getBody(), AAIErrorResponse.class); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + + assertEquals("SVC3102",responseEntity.getRequestError().getServiceException().getMessageId()); + assertEquals("Error parsing input performing %1 on %2 (msg=%3) (ec=%4)",responseEntity.getRequestError().getServiceException().getText()); + 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)); + } + + @Test + public void testHandleSchemaViolationException() throws JsonMappingException, JsonProcessingException { + SchemaViolationException exception = Mockito.mock(SchemaViolationException.class); + ResponseEntity response = springExceptionHandler.handleSchemaViolationException(exception, webRequest); + AAIErrorResponse responseEntity = objectMapper.readValue(response.getBody(), AAIErrorResponse.class); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + + 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("/aai/v14/dsl",responseEntity.getRequestError().getServiceException().getVariables().get(1)); + assertEquals("ERR.5.4.4020",responseEntity.getRequestError().getServiceException().getVariables().get(3)); + } + + @Test + public void testHandleAAIException() throws JsonMappingException, JsonProcessingException { + AAIException exception = new AAIException("AAI_4009"); + ResponseEntity response = springExceptionHandler.handleAAIException(exception, webRequest); + AAIErrorResponse responseEntity = objectMapper.readValue(response.getBody(), AAIErrorResponse.class); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + assertEquals("SVC3000",responseEntity.getRequestError().getServiceException().getMessageId()); + assertEquals("PUT",responseEntity.getRequestError().getServiceException().getVariables().get(0)); + assertEquals("/aai/v14/dsl",responseEntity.getRequestError().getServiceException().getVariables().get(1)); + assertEquals("Invalid X-FromAppId in header",responseEntity.getRequestError().getServiceException().getVariables().get(2)); + assertEquals("4.0.4009",responseEntity.getRequestError().getServiceException().getVariables().get(3)); + } + + @Test + public void testHandleUnknownException() throws Exception { + Exception exception = new Exception(); + ResponseEntity response = springExceptionHandler.handleUnknownException(exception, webRequest); + assertEquals(HttpStatus.BAD_REQUEST, response.getStatusCode()); + AAIErrorResponse responseEntity = objectMapper.readValue(response.getBody(), AAIErrorResponse.class); + 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("/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)); + } +} diff --git a/aai-traversal/src/test/resources/application-test.properties b/aai-traversal/src/test/resources/application-test.properties index 422ea30..b5e5398 100644 --- a/aai-traversal/src/test/resources/application-test.properties +++ b/aai-traversal/src/test/resources/application-test.properties @@ -7,7 +7,7 @@ info.build.version=1.1.0 spring.application.name=aai-traversal spring.jersey.type=filter -server.contextPath=/ +server.servlet.context-path=${schema.uri.base.path} spring.autoconfigure.exclude=\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\ @@ -15,7 +15,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=/ spring.profiles.active=production #The max number of active threads in this pool -- cgit 1.2.3-korg