diff options
Diffstat (limited to 'src/main/java/org/onap/aai/sa/rest/DocumentApi.java')
-rw-r--r-- | src/main/java/org/onap/aai/sa/rest/DocumentApi.java | 224 |
1 files changed, 158 insertions, 66 deletions
diff --git a/src/main/java/org/onap/aai/sa/rest/DocumentApi.java b/src/main/java/org/onap/aai/sa/rest/DocumentApi.java index 0ec29a2..63109ef 100644 --- a/src/main/java/org/onap/aai/sa/rest/DocumentApi.java +++ b/src/main/java/org/onap/aai/sa/rest/DocumentApi.java @@ -31,6 +31,7 @@ import org.onap.aai.sa.searchdbabstraction.entity.DocumentOperationResult; import org.onap.aai.sa.searchdbabstraction.entity.SearchOperationResult; import org.onap.aai.sa.searchdbabstraction.logging.SearchDbMsgs; import org.onap.aai.sa.searchdbabstraction.searchapi.SearchStatement; +import org.onap.aai.sa.searchdbabstraction.searchapi.SuggestionStatement; import org.onap.aai.cl.api.LogFields; import org.onap.aai.cl.api.LogLine; import org.onap.aai.cl.api.Logger; @@ -47,20 +48,19 @@ public class DocumentApi { private static final String REQUEST_HEADER_RESOURCE_VERSION = "If-Match"; private static final String RESPONSE_HEADER_RESOURCE_VERSION = "ETag"; private static final String REQUEST_HEADER_ALLOW_IMPLICIT_INDEX_CREATION = "X-CreateIndex"; - + protected SearchServiceApi searchService = null; private Logger logger = LoggerFactory.getInstance().getLogger(DocumentApi.class.getName()); - private Logger auditLogger = LoggerFactory.getInstance() - .getAuditLogger(DocumentApi.class.getName()); + private Logger auditLogger = + LoggerFactory.getInstance().getAuditLogger(DocumentApi.class.getName()); public DocumentApi(SearchServiceApi searchService) { this.searchService = searchService; } public Response processPost(String content, HttpServletRequest request, HttpHeaders headers, - HttpServletResponse httpResponse, String index, - DocumentStoreInterface documentStore) { + HttpServletResponse httpResponse, String index, DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); @@ -77,8 +77,7 @@ public class DocumentApi { isValid = searchService.validateRequest(headers, request, ApiUtils.Action.POST, ApiUtils.SEARCH_AUTH_POLICY_NAME); } catch (Exception e) { - logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, - "DocumentApi.processPost", + logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "DocumentApi.processPost", e.getMessage()); return handleError(request, content, Status.FORBIDDEN); } @@ -90,7 +89,8 @@ public class DocumentApi { DocumentStoreDataEntityImpl document = new DocumentStoreDataEntityImpl(); document.setContent(content); - DocumentOperationResult result = documentStore.createDocument(index, document, implicitlyCreateIndex(headers)); + DocumentOperationResult result = + documentStore.createDocument(index, document, implicitlyCreateIndex(headers)); String output = null; if (result.getResultCode() >= 200 && result.getResultCode() <= 299) { output = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getDocument()); @@ -117,8 +117,8 @@ public class DocumentApi { } public Response processPut(String content, HttpServletRequest request, HttpHeaders headers, - HttpServletResponse httpResponse, String index, - String id, DocumentStoreInterface documentStore) { + HttpServletResponse httpResponse, String index, String id, + DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); @@ -135,8 +135,7 @@ public class DocumentApi { isValid = searchService.validateRequest(headers, request, ApiUtils.Action.PUT, ApiUtils.SEARCH_AUTH_POLICY_NAME); } catch (Exception e) { - logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, - "DocumentApi.processPut", + logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "DocumentApi.processPut", e.getMessage()); return handleError(request, content, Status.FORBIDDEN); } @@ -145,8 +144,8 @@ public class DocumentApi { return handleError(request, content, Status.FORBIDDEN); } - String resourceVersion = headers.getRequestHeaders() - .getFirst(REQUEST_HEADER_RESOURCE_VERSION); + String resourceVersion = + headers.getRequestHeaders().getFirst(REQUEST_HEADER_RESOURCE_VERSION); DocumentStoreDataEntityImpl document = new DocumentStoreDataEntityImpl(); document.setId(id); @@ -185,8 +184,8 @@ public class DocumentApi { } public Response processDelete(String content, HttpServletRequest request, HttpHeaders headers, - HttpServletResponse httpResponse, String index, String id, - DocumentStoreInterface documentStore) { + HttpServletResponse httpResponse, String index, String id, + DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); @@ -199,8 +198,7 @@ public class DocumentApi { isValid = searchService.validateRequest(headers, request, ApiUtils.Action.DELETE, ApiUtils.SEARCH_AUTH_POLICY_NAME); } catch (Exception e) { - logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, - "DocumentApi.processDelete", + logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "DocumentApi.processDelete", e.getMessage()); return handleError(request, content, Status.FORBIDDEN); } @@ -209,8 +207,8 @@ public class DocumentApi { return handleError(request, content, Status.FORBIDDEN); } - String resourceVersion = headers.getRequestHeaders() - .getFirst(REQUEST_HEADER_RESOURCE_VERSION); + String resourceVersion = + headers.getRequestHeaders().getFirst(REQUEST_HEADER_RESOURCE_VERSION); if (resourceVersion == null || resourceVersion.isEmpty()) { return handleError(request, "Request header 'If-Match' missing", javax.ws.rs.core.Response.Status.BAD_REQUEST); @@ -251,8 +249,8 @@ public class DocumentApi { } public Response processGet(String content, HttpServletRequest request, HttpHeaders headers, - HttpServletResponse httpResponse, String index, String id, - DocumentStoreInterface documentStore) { + HttpServletResponse httpResponse, String index, String id, + DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); @@ -265,8 +263,7 @@ public class DocumentApi { isValid = searchService.validateRequest(headers, request, ApiUtils.Action.GET, ApiUtils.SEARCH_AUTH_POLICY_NAME); } catch (Exception e) { - logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, - "DocumentApi.processGet", + logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "DocumentApi.processGet", e.getMessage()); return handleError(request, content, Status.FORBIDDEN); } @@ -275,8 +272,8 @@ public class DocumentApi { return handleError(request, content, Status.FORBIDDEN); } - String resourceVersion = headers.getRequestHeaders() - .getFirst(REQUEST_HEADER_RESOURCE_VERSION); + String resourceVersion = + headers.getRequestHeaders().getFirst(REQUEST_HEADER_RESOURCE_VERSION); DocumentStoreDataEntityImpl document = new DocumentStoreDataEntityImpl(); document.setId(id); @@ -308,8 +305,7 @@ public class DocumentApi { } public Response processSearchWithGet(String content, HttpServletRequest request, - HttpHeaders headers, String index, - String queryText, DocumentStoreInterface documentStore) { + HttpHeaders headers, String index, String queryText, DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); @@ -323,8 +319,7 @@ public class DocumentApi { isValid = searchService.validateRequest(headers, request, ApiUtils.Action.GET, ApiUtils.SEARCH_AUTH_POLICY_NAME); } catch (Exception e) { - logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, - "processSearchWithGet", + logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "processSearchWithGet", e.getMessage()); return handleError(request, content, Status.FORBIDDEN); } @@ -336,8 +331,8 @@ public class DocumentApi { SearchOperationResult result = documentStore.search(index, queryText); String output = null; if (result.getResultCode() >= 200 && result.getResultCode() <= 299) { - output = mapper.writerWithDefaultPrettyPrinter() - .writeValueAsString(result.getSearchResult()); + output = + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getSearchResult()); } else { output = result.getError() != null ? mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getError()) @@ -356,14 +351,13 @@ public class DocumentApi { } public Response queryWithGetWithPayload(String content, HttpServletRequest request, - HttpHeaders headers, String index, - DocumentStoreInterface documentStore) { + HttpHeaders headers, String index, DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); - logger.info(SearchDbMsgs.PROCESS_PAYLOAD_QUERY, "GET", (request != null) - ? request.getRequestURL().toString() : ""); + logger.info(SearchDbMsgs.PROCESS_PAYLOAD_QUERY, "GET", + (request != null) ? request.getRequestURL().toString() : ""); if (logger.isDebugEnabled()) { logger.debug("Request Body: " + content); } @@ -371,14 +365,13 @@ public class DocumentApi { } public Response processSearchWithPost(String content, HttpServletRequest request, - HttpHeaders headers, String index, - DocumentStoreInterface documentStore) { + HttpHeaders headers, String index, DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); - logger.info(SearchDbMsgs.PROCESS_PAYLOAD_QUERY, "POST", (request != null) - ? request.getRequestURL().toString() : ""); + logger.info(SearchDbMsgs.PROCESS_PAYLOAD_QUERY, "POST", + (request != null) ? request.getRequestURL().toString() : ""); if (logger.isDebugEnabled()) { logger.debug("Request Body: " + content); } @@ -386,18 +379,33 @@ public class DocumentApi { return processQuery(index, content, request, headers, documentStore); } + public Response processSuggestQueryWithPost(String content, HttpServletRequest request, + HttpHeaders headers, String index, DocumentStoreInterface documentStore) { + + // Initialize the MDC Context for logging purposes. + ApiUtils.initMdcContext(request, headers); + + logger.info(SearchDbMsgs.PROCESS_PAYLOAD_QUERY, "POST", + (request != null) ? request.getRequestURL().toString() : ""); + if (logger.isDebugEnabled()) { + logger.debug("Request Body: " + content); + } + + return processSuggestQuery(index, content, request, headers, documentStore); + } + /** - * Common handler for query requests. This is called by both the GET with - * payload and POST with payload variants of the query endpoint. + * Common handler for query requests. This is called by both the GET with payload and POST with + * payload variants of the query endpoint. * - * @param index - The index to be queried against. + * @param index - The index to be queried against. * @param content - The payload containing the query structure. * @param request - The HTTP request. * @param headers - The HTTP headers. * @return - A standard HTTP response. */ private Response processQuery(String index, String content, HttpServletRequest request, - HttpHeaders headers, DocumentStoreInterface documentStore) { + HttpHeaders headers, DocumentStoreInterface documentStore) { try { ObjectMapper mapper = new ObjectMapper(); @@ -415,9 +423,7 @@ public class DocumentApi { ApiUtils.SEARCH_AUTH_POLICY_NAME); } catch (Exception e) { - logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, - "processQuery", - e.getMessage()); + logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "processQuery", e.getMessage()); return handleError(request, content, Status.FORBIDDEN); } @@ -438,8 +444,8 @@ public class DocumentApi { // Now, submit the search statement, translated into // ElasticSearch syntax, to the document store DAO. - SearchOperationResult result = documentStore.searchWithPayload(index, - searchStatement.toElasticSearch()); + SearchOperationResult result = + documentStore.searchWithPayload(index, searchStatement.toElasticSearch()); String output = null; if (result.getResultCode() >= 200 && result.getResultCode() <= 299) { output = prepareOutput(mapper, result); @@ -461,37 +467,124 @@ public class DocumentApi { } } - /** - * Checks the supplied HTTP headers to see if we should allow the underlying document - * store to implicitly create the index referenced in a document PUT or POST if it - * does not already exist in the data store. + * Common handler for query requests. This is called by both the GET with payload and POST with + * payload variants of the query endpoint. + * + * @param index - The index to be queried against. + * @param content - The payload containing the query structure. + * @param request - The HTTP request. + * @param headers - The HTTP headers. + * @return - A standard HTTP response. + */ + private Response processSuggestQuery(String index, String content, HttpServletRequest request, + HttpHeaders headers, DocumentStoreInterface documentStore) { + + try { + ObjectMapper mapper = new ObjectMapper(); + mapper.setSerializationInclusion(Include.NON_EMPTY); + + // Make sure that we were supplied a payload before proceeding. + if (content == null) { + return handleError(request, content, Status.BAD_REQUEST); + } + + // Validate that the request has the appropriate authorization. + boolean isValid; + try { + isValid = searchService.validateRequest(headers, request, ApiUtils.Action.POST, + ApiUtils.SEARCH_AUTH_POLICY_NAME); + + } catch (Exception e) { + logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "processQuery", e.getMessage()); + return handleError(request, content, Status.FORBIDDEN); + } + + if (!isValid) { + return handleError(request, content, Status.FORBIDDEN); + } + + SuggestionStatement suggestionStatement; + + try { + // Marshall the supplied request payload into a search statement + // object. + suggestionStatement = mapper.readValue(content, SuggestionStatement.class); + + } catch (Exception e) { + return handleError(request, e.getMessage(), Status.BAD_REQUEST); + } + + // Now, submit the search statement, translated into + // ElasticSearch syntax, to the document store DAO. + SearchOperationResult result = + documentStore.suggestionQueryWithPayload(index, suggestionStatement.toElasticSearch()); + String output = null; + if (result.getResultCode() >= 200 && result.getResultCode() <= 299) { + output = prepareSuggestOutput(mapper, result); + } else { + output = result.getError() != null + ? mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getError()) + : result.getFailureCause(); + } + Response response = Response.status(result.getResultCode()).entity(output).build(); + + // Clear the MDC context so that no other transaction inadvertently + // uses our transaction id. + ApiUtils.clearMdcContext(); + + return response; + + } catch (Exception e) { + return handleError(request, e.getMessage(), Status.INTERNAL_SERVER_ERROR); + } + } + + /** + * Checks the supplied HTTP headers to see if we should allow the underlying document store to + * implicitly create the index referenced in a document PUT or POST if it does not already exist + * in the data store. * * @param headers - The HTTP headers to examine. * - * @return - true if the headers indicate that missing indices should be implicitly created, - * false otherwise. + * @return - true if the headers indicate that missing indices should be implicitly created, false + * otherwise. */ private boolean implicitlyCreateIndex(HttpHeaders headers) { - + boolean createIndexIfNotPresent = false; - String implicitIndexCreationHeader = + String implicitIndexCreationHeader = headers.getRequestHeaders().getFirst(REQUEST_HEADER_ALLOW_IMPLICIT_INDEX_CREATION); - - if( (implicitIndexCreationHeader != null) && (implicitIndexCreationHeader.equals("true")) ) { + + if ((implicitIndexCreationHeader != null) && (implicitIndexCreationHeader.equals("true"))) { createIndexIfNotPresent = true; } - + return createIndexIfNotPresent; } - - + private String prepareOutput(ObjectMapper mapper, SearchOperationResult result) throws JsonProcessingException { StringBuffer output = new StringBuffer(); output.append("{\r\n\"searchResult\":"); - output.append(mapper.writerWithDefaultPrettyPrinter() - .writeValueAsString(result.getSearchResult())); + output.append( + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getSearchResult())); + AggregationResults aggs = result.getAggregationResult(); + if (aggs != null) { + output.append(",\r\n\"aggregationResult\":"); + output.append(mapper.setSerializationInclusion(Include.NON_NULL) + .writerWithDefaultPrettyPrinter().writeValueAsString(aggs)); + } + output.append("\r\n}"); + return output.toString(); + } + + private String prepareSuggestOutput(ObjectMapper mapper, SearchOperationResult result) + throws JsonProcessingException { + StringBuffer output = new StringBuffer(); + output.append("{\r\n\"searchResult\":"); + output.append( + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getSuggestResult())); AggregationResults aggs = result.getAggregationResult(); if (aggs != null) { output.append(",\r\n\"aggregationResult\":"); @@ -514,8 +607,7 @@ public class DocumentApi { (request != null) ? request.getRemoteHost() : "", Integer.toString(status.getStatusCode())); auditLogger.info(SearchDbMsgs.PROCESS_REST_REQUEST, - new LogFields() - .setField(LogLine.DefinedFields.RESPONSE_CODE, status.getStatusCode()) + new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, status.getStatusCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, status.getReasonPhrase()), (request != null) ? request.getMethod() : "", (request != null) ? request.getRequestURL().toString() : "", |