From ce701746049abfd94a87b46e43f296faf32d6213 Mon Sep 17 00:00:00 2001 From: Shwetank Dave Date: Thu, 29 Mar 2018 16:55:36 -0400 Subject: Removing AJSC and moving to SpringBoot [AAI-804] Deleting AJSC files. [AAI-804] Adding Spring Boot Dependencies Issue-ID: AAI-804 Change-Id: Ibda01496d56cc4613f6d2be3b8737d823cee342a Signed-off-by: Shwetank Dave --- src/main/java/org/onap/aai/sa/Application.java | 53 ++ .../org/onap/aai/sa/auth/SearchDbServiceAuth.java | 7 +- .../onap/aai/sa/auth/SearchDbServiceAuthCore.java | 17 +- .../java/org/onap/aai/sa/rest/AnalyzerApi.java | 39 +- src/main/java/org/onap/aai/sa/rest/ApiUtils.java | 65 ++- src/main/java/org/onap/aai/sa/rest/BulkApi.java | 53 +- .../java/org/onap/aai/sa/rest/DocumentApi.java | 283 +++++----- src/main/java/org/onap/aai/sa/rest/IndexApi.java | 189 +++---- .../org/onap/aai/sa/rest/SearchServiceApi.java | 235 +++++---- .../elasticsearch/config/ElasticSearchConfig.java | 6 +- .../elasticsearch/dao/DocumentStoreInterface.java | 24 +- .../dao/ElasticSearchHttpController.java | 585 ++++++++++++--------- .../entity/SearchOperationResult.java | 8 +- .../sa/searchdbabstraction/entity/SuggestHit.java | 54 +- .../sa/searchdbabstraction/entity/SuggestHits.java | 36 +- .../searchdbabstraction/logging/SearchDbMsgs.java | 2 +- .../searchapi/SuggestionStatement.java | 112 ++-- .../searchdbabstraction/service/SearchService.java | 6 +- .../util/AggregationParsingUtil.java | 4 +- .../util/SearchDbConstants.java | 29 +- 20 files changed, 1010 insertions(+), 797 deletions(-) create mode 100644 src/main/java/org/onap/aai/sa/Application.java (limited to 'src/main/java') diff --git a/src/main/java/org/onap/aai/sa/Application.java b/src/main/java/org/onap/aai/sa/Application.java new file mode 100644 index 0000000..2ccebd1 --- /dev/null +++ b/src/main/java/org/onap/aai/sa/Application.java @@ -0,0 +1,53 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved. + * Copyright © 2017-2018 Amdocs + * ================================================================================ + * 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.sa; + +// import org.eclipse.jetty.util.security.Password; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +@SpringBootApplication +public class Application { + +// public static String[] deobfuscateArgs(String[] args, String ... attrnames) { +// +// String[] deobfuscatedArgs = args.clone(); +// +// Password.deobfuscate("HI"); +// +// //System.setProperty(arg0, arg1) +// +// return deobfuscatedArgs; +// } +// + public static void main(String[] args) { + + //server.ssl.key-store-password=onapSecret + //server.ssl.key-password=onapSecret +// args = new String[]{"-Dserver.ssl.key-store-password", "onapSecret", +// "-Dserver.ssl.key-password", "onapSecret"}; + + SpringApplication.run(Application.class, args); + + //deobfuscateArgs(args, "server.ssl.key-store-password", "server.ssl.key-password")); + } +} diff --git a/src/main/java/org/onap/aai/sa/auth/SearchDbServiceAuth.java b/src/main/java/org/onap/aai/sa/auth/SearchDbServiceAuth.java index 0d96f9e..59ae82b 100644 --- a/src/main/java/org/onap/aai/sa/auth/SearchDbServiceAuth.java +++ b/src/main/java/org/onap/aai/sa/auth/SearchDbServiceAuth.java @@ -20,8 +20,9 @@ */ package org.onap.aai.sa.auth; -import javax.ws.rs.core.Cookie; -import javax.ws.rs.core.HttpHeaders; + import org.springframework.http.HttpHeaders; + + import javax.servlet.http.Cookie; public class SearchDbServiceAuth { @@ -49,11 +50,9 @@ public class SearchDbServiceAuth { public boolean authCookie(Cookie cookie, String authFunction, StringBuilder username) { - // String result = "no value"; if (cookie == null) { return false; } - return SearchDbServiceAuthCore.authorize(username.toString(), authFunction); } } diff --git a/src/main/java/org/onap/aai/sa/auth/SearchDbServiceAuthCore.java b/src/main/java/org/onap/aai/sa/auth/SearchDbServiceAuthCore.java index 0895c19..bd4f1a5 100644 --- a/src/main/java/org/onap/aai/sa/auth/SearchDbServiceAuthCore.java +++ b/src/main/java/org/onap/aai/sa/auth/SearchDbServiceAuthCore.java @@ -25,24 +25,20 @@ import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; -import org.onap.aai.sa.searchdbabstraction.util.SearchDbConstants; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.sa.searchdbabstraction.util.SearchDbConstants; import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Timer; +import java.util.*; public class SearchDbServiceAuthCore { private static Logger logger = LoggerFactory.getInstance() - .getLogger(SearchDbServiceAuthCore.class.getName()); + .getLogger(SearchDbServiceAuthCore.class.getName()); private static String GlobalAuthFileName = SearchDbConstants.SDB_AUTH_CONFIG_FILENAME; @@ -75,11 +71,10 @@ public class SearchDbServiceAuthCore { public static String getConfigFile() { if (GlobalAuthFileName == null) { - String nc = SearchDbConstants.SDB_AUTH_CONFIG_FILENAME; + String nc = GlobalAuthFileName; if (nc == null) { nc = "/home/aaiadmin/etc/aaipolicy.json"; } - GlobalAuthFileName = nc; } return GlobalAuthFileName; @@ -87,13 +82,10 @@ public class SearchDbServiceAuthCore { public synchronized static void reloadUsers() { users = new HashMap(); - - ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally JSONParser parser = new JSONParser(); try { Object obj = parser.parse(new FileReader(GlobalAuthFileName)); - // aailogger.debug(logline, "Reading from " + GlobalAuthFileName); JsonNode rootNode = mapper.readTree(new File(GlobalAuthFileName)); JsonNode rolesNode = rootNode.path("roles"); @@ -230,7 +222,6 @@ public class SearchDbServiceAuthCore { } public static boolean authorize(String username, String authFunction) { - // logline.init(component, transId, fromAppId, "authorize()"); if (!usersInitialized || (users == null)) { init(); diff --git a/src/main/java/org/onap/aai/sa/rest/AnalyzerApi.java b/src/main/java/org/onap/aai/sa/rest/AnalyzerApi.java index 8a95dc1..de7ba59 100644 --- a/src/main/java/org/onap/aai/sa/rest/AnalyzerApi.java +++ b/src/main/java/org/onap/aai/sa/rest/AnalyzerApi.java @@ -33,10 +33,19 @@ import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.core.Context; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.Response; -@Path("/analyzers") +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +//@Path("/analyzers") +@RestController +@RequestMapping("/services/search-db-service/v1/analyzers") public class AnalyzerApi { private SearchServiceApi searchService = null; @@ -46,16 +55,16 @@ public class AnalyzerApi { private static Logger auditLogger = LoggerFactory.getInstance() .getAuditLogger(IndexApi.class.getName()); - public AnalyzerApi(SearchServiceApi searchService) { + public AnalyzerApi( @Qualifier("searchServiceApi") SearchServiceApi searchService) { this.searchService = searchService; } @GET - public Response processGet(@Context HttpServletRequest request, + public ResponseEntity processGet(@Context HttpServletRequest request, @Context HttpHeaders headers, ApiUtils apiUtils) { - Response.Status responseCode = Response.Status.INTERNAL_SERVER_ERROR; + HttpStatus responseCode = HttpStatus.INTERNAL_SERVER_ERROR; String responseString = "Undefined error"; // Initialize the MDC Context for logging purposes. @@ -68,14 +77,14 @@ public class AnalyzerApi { if (!searchService.validateRequest(headers, request, ApiUtils.Action.GET, ApiUtils.SEARCH_AUTH_POLICY_NAME)) { logger.warn(SearchDbMsgs.GET_ANALYZERS_FAILURE, "Authentication failure."); - return Response.status(Response.Status.FORBIDDEN).entity("Authentication failure.").build(); + return ResponseEntity.status(HttpStatus.FORBIDDEN).contentType ( MediaType.APPLICATION_JSON ).body("Authentication failure."); } } catch (Exception e) { logger.warn(SearchDbMsgs.GET_ANALYZERS_FAILURE, "Unexpected authentication failure - cause: " + e.getMessage()); - return Response.status(Response.Status.FORBIDDEN).entity("Authentication failure.").build(); + return ResponseEntity.status(HttpStatus.FORBIDDEN).contentType ( MediaType.APPLICATION_JSON ).body("Authentication failure."); } @@ -83,7 +92,7 @@ public class AnalyzerApi { try { responseString = buildAnalyzerList(ElasticSearchHttpController.getInstance() .getAnalysisConfig()); - responseCode = Response.Status.OK; + responseCode = HttpStatus.OK; } catch (Exception e) { @@ -93,17 +102,17 @@ public class AnalyzerApi { } // Build the HTTP response. - Response response = Response.status(responseCode).entity(responseString).build(); + ResponseEntity response = ResponseEntity.status(responseCode).contentType ( MediaType.APPLICATION_JSON ).body(responseString); // Generate our audit log. auditLogger.info(SearchDbMsgs.PROCESS_REST_REQUEST, new LogFields() - .setField(LogLine.DefinedFields.RESPONSE_CODE, responseCode.getStatusCode()) - .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, responseCode.getStatusCode()), + .setField(LogLine.DefinedFields.RESPONSE_CODE, responseCode.value ()) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, responseCode.value()), (request != null) ? request.getMethod() : "Unknown", - (request != null) ? request.getRequestURL().toString() : "Unknown", - (request != null) ? request.getRemoteHost() : "Unknown", - Integer.toString(response.getStatus())); + (request != null) ? request.getRequestURL ().toString () : "Unknown", + (request != null) ? request.getRemoteHost () : "Unknown", + Integer.toString(response.getStatusCodeValue ())); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. diff --git a/src/main/java/org/onap/aai/sa/rest/ApiUtils.java b/src/main/java/org/onap/aai/sa/rest/ApiUtils.java index 0d173a4..baa63b8 100644 --- a/src/main/java/org/onap/aai/sa/rest/ApiUtils.java +++ b/src/main/java/org/onap/aai/sa/rest/ApiUtils.java @@ -20,15 +20,16 @@ */ package org.onap.aai.sa.rest; -import org.onap.aai.sa.searchdbabstraction.util.SearchDbConstants; import org.onap.aai.cl.mdc.MdcContext; +import org.onap.aai.sa.searchdbabstraction.util.SearchDbConstants; import org.slf4j.MDC; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; -import java.util.UUID; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.Response; +import java.util.UUID; +// Spring Imports public class ApiUtils { @@ -37,10 +38,7 @@ public class ApiUtils { public enum Action { POST, GET, PUT, DELETE - } - - ; - + }; /** * This method uses the contents of the supplied HTTP headers and request @@ -49,25 +47,45 @@ public class ApiUtils { * @param httpReq - HTTP request structure. * @param headers - HTTP headers */ - protected static void initMdcContext(HttpServletRequest httpReq, HttpHeaders headers) { +// protected static void initMdcContext(HttpServletRequest httpReq, HttpHeaders headers) { +// +// // Auto generate a transaction if we were not provided one. +// String transId = null; +// if (headers != null) { +// // transId = headers.getRequestHeaders().getFirst("X-TransactionId"); +// transId = headers.getFirst("X-TransactionId"); +// +// if ((transId == null) || (transId.equals(""))) { +// transId = UUID.randomUUID().toString(); +// } +// } +// +// String fromIp = (httpReq != null) ? httpReq.getRemoteAddr() : ""; +// String fromApp = (headers != null) ? headers.getFirst("X-FromAppId") : ""; +// +// MdcContext.initialize(transId, SearchDbConstants.SDB_SERVICE_NAME, "", fromApp, fromIp); +// } + + protected static void initMdcContext ( HttpServletRequest httpReq, HttpHeaders headers) { // Auto generate a transaction if we were not provided one. String transId = null; if (headers != null) { - transId = headers.getRequestHeaders().getFirst("X-TransactionId"); + // transId = headers.getRequestHeaders().getFirst("X-TransactionId"); + transId = headers.getFirst("X-TransactionId"); if ((transId == null) || (transId.equals(""))) { transId = UUID.randomUUID().toString(); } } - String fromIp = (httpReq != null) ? httpReq.getRemoteAddr() : ""; - String fromApp = (headers != null) ? headers.getRequestHeaders().getFirst("X-FromAppId") : ""; + + String fromIp = (httpReq != null) ? httpReq.getRemoteHost () : ""; + String fromApp = (headers != null) ? headers.getFirst("X-FromAppId") : ""; MdcContext.initialize(transId, SearchDbConstants.SDB_SERVICE_NAME, "", fromApp, fromIp); } - protected static void clearMdcContext() { MDC.clear(); } @@ -104,10 +122,10 @@ public class ApiUtils { if (requireId) { return (tokens.length == 8) && (tokens[4].equals("indexes") - && (tokens[6].equals("documents"))); + && (tokens[6].equals("documents"))); } else { return ((tokens.length == 8) || (tokens.length == 7)) - && (tokens[4].equals("indexes") && (tokens[6].equals("documents"))); + && (tokens[4].equals("indexes") && (tokens[6].equals("documents"))); } } @@ -158,17 +176,22 @@ public class ApiUtils { // recognized in the javax library. We need to manually translate these to human-readable // strings. String statusString = "Unknown"; - Response.Status status = Response.Status.fromStatusCode(httpStatusCode); + HttpStatus status = null; + + try { + status = HttpStatus.valueOf ( httpStatusCode ); + } catch (IllegalArgumentException e) {} + if (status == null) { switch (httpStatusCode) { - case 207: - statusString = "Multi Status"; - break; - default: + case 207: + statusString = "Multi Status"; + break; + default: } } else { - statusString = status.toString(); + statusString = status.getReasonPhrase (); } return statusString; diff --git a/src/main/java/org/onap/aai/sa/rest/BulkApi.java b/src/main/java/org/onap/aai/sa/rest/BulkApi.java index 2f5a408..ea3e897 100644 --- a/src/main/java/org/onap/aai/sa/rest/BulkApi.java +++ b/src/main/java/org/onap/aai/sa/rest/BulkApi.java @@ -23,29 +23,28 @@ package org.onap.aai.sa.rest; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.fge.jsonschema.main.JsonSchema; import com.github.fge.jsonschema.main.JsonSchemaFactory; - -import org.onap.aai.sa.searchdbabstraction.elasticsearch.dao.DocumentStoreInterface; -import org.onap.aai.sa.searchdbabstraction.elasticsearch.exception.DocumentStoreOperationException; -import org.onap.aai.sa.searchdbabstraction.entity.OperationResult; -import org.onap.aai.sa.searchdbabstraction.logging.SearchDbMsgs; import org.onap.aai.cl.api.LogFields; import org.onap.aai.cl.api.LogLine; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.dao.DocumentStoreInterface; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.exception.DocumentStoreOperationException; +import org.onap.aai.sa.searchdbabstraction.entity.OperationResult; +import org.onap.aai.sa.searchdbabstraction.logging.SearchDbMsgs; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.concurrent.atomic.AtomicBoolean; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.Path; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.Response; /** * This class encapsulates the REST end points associated with performing * bulk operations against the document store. */ -@Path("/bulk") public class BulkApi { /** @@ -92,8 +91,8 @@ public class BulkApi { * @param headers - HTTP headers. * @return - A standard REST response structure. */ - public Response processPost(String operations, - HttpServletRequest request, + public ResponseEntity processPost(String operations, + HttpServletRequest request, HttpHeaders headers, DocumentStoreInterface documentStore, ApiUtils apiUtils) { @@ -119,7 +118,7 @@ public class BulkApi { ApiUtils.Action.POST, ApiUtils.SEARCH_AUTH_POLICY_NAME)) { logger.warn(SearchDbMsgs.BULK_OPERATION_FAILURE, "Authentication failure."); - return buildResponse(Response.Status.FORBIDDEN.getStatusCode(), + return buildResponse(HttpStatus.FORBIDDEN.value (), "Authentication failure.", request, apiUtils); } @@ -133,7 +132,7 @@ public class BulkApi { logger.debug("Stack Trace:\n" + e.getStackTrace()); } - return buildResponse(Response.Status.FORBIDDEN.getStatusCode(), + return buildResponse(HttpStatus.FORBIDDEN.value (), "Authentication failure - cause " + e.getMessage(), request, apiUtils); @@ -164,7 +163,7 @@ public class BulkApi { // Populate the result code and entity string for our HTTP response // and return the response to the client.. - return buildResponse(javax.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode(), + return buildResponse(HttpStatus.BAD_REQUEST.value(), "Unable to marshal operations: " + e.getMessage(), request, apiUtils); @@ -178,7 +177,7 @@ public class BulkApi { // Populate the result code and entity string for our HTTP response // and return the response to the client.. - return buildResponse(javax.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode(), + return buildResponse(HttpStatus.BAD_REQUEST.value(), "Empty operations list in bulk request", request, apiUtils); @@ -202,18 +201,18 @@ public class BulkApi { } // Populate the result code and entity string for our HTTP response. - resultCode = javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(); + resultCode = HttpStatus.INTERNAL_SERVER_ERROR.value (); resultString = "Unexpected failure processing bulk operations: " + e.getMessage(); } // Build our HTTP response. - Response response = Response.status(resultCode).entity(resultString).build(); + ResponseEntity response = ResponseEntity.status(resultCode).contentType ( MediaType.APPLICATION_JSON ).body(resultString); // Log the result. - if ((response.getStatus() >= 200) && (response.getStatus() < 300)) { + if ((response.getStatusCodeValue () >= 200) && (response.getStatusCodeValue () < 300)) { logger.info(SearchDbMsgs.PROCESSED_BULK_OPERATIONS); } else { - logger.warn(SearchDbMsgs.BULK_OPERATION_FAILURE, (String) response.getEntity()); + logger.warn(SearchDbMsgs.BULK_OPERATION_FAILURE, (String) response.getBody ()); } // Finally, return the HTTP response to the client. @@ -229,10 +228,10 @@ public class BulkApi { * @param request - The HTTP request to extract data from for the audit log. * @return - An HTTP response object. */ - private Response buildResponse(int resultCode, String resultString, - HttpServletRequest request, ApiUtils apiUtils) { + private ResponseEntity buildResponse(int resultCode, String resultString, + HttpServletRequest request, ApiUtils apiUtils) { - Response response = Response.status(resultCode).entity(resultString).build(); + ResponseEntity response = ResponseEntity.status(resultCode).contentType ( MediaType.APPLICATION_JSON ) .body(resultString); // Generate our audit log. auditLogger.info(SearchDbMsgs.PROCESS_REST_REQUEST, @@ -240,10 +239,10 @@ public class BulkApi { .setField(LogLine.DefinedFields.RESPONSE_CODE, resultCode) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, ApiUtils.getHttpStatusString(resultCode)), - (request != null) ? request.getMethod() : "Unknown", - (request != null) ? request.getRequestURL().toString() : "Unknown", - (request != null) ? request.getRemoteHost() : "Unknown", - Integer.toString(response.getStatus())); + (request != null) ? request.getMethod().toString () : "Unknown", + (request != null) ? request.getRequestURL ().toString () : "Unknown", + (request != null) ? request.getRemoteHost () : "Unknown", + Integer.toString(response.getStatusCodeValue ())); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. 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 63109ef..ac7610b 100644 --- a/src/main/java/org/onap/aai/sa/rest/DocumentApi.java +++ b/src/main/java/org/onap/aai/sa/rest/DocumentApi.java @@ -23,7 +23,10 @@ package org.onap.aai.sa.rest; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; - +import org.onap.aai.cl.api.LogFields; +import org.onap.aai.cl.api.LogLine; +import org.onap.aai.cl.api.Logger; +import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.sa.searchdbabstraction.elasticsearch.dao.DocumentStoreDataEntityImpl; import org.onap.aai.sa.searchdbabstraction.elasticsearch.dao.DocumentStoreInterface; import org.onap.aai.sa.searchdbabstraction.entity.AggregationResults; @@ -32,35 +35,37 @@ 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; -import org.onap.aai.cl.eelf.LoggerFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; +//import javax.ws.rs.core.HttpHeaders; +//import javax.ws.rs.core.MediaType; +//import javax.ws.rs.core.Response; +//import javax.ws.rs.core.Response.Status; +// Spring Imports 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) { + public ResponseEntity processPost(String content, HttpServletRequest request, HttpHeaders headers, + HttpServletResponse httpResponse, String index, + DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); @@ -69,7 +74,7 @@ public class DocumentApi { ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(Include.NON_EMPTY); if (content == null) { - return handleError(request, content, Status.BAD_REQUEST); + return handleError(request, content, HttpStatus.BAD_REQUEST); } boolean isValid; @@ -77,20 +82,20 @@ 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); + return handleError(request, content, HttpStatus.FORBIDDEN); } if (!isValid) { - return handleError(request, content, Status.FORBIDDEN); + return handleError(request, content, HttpStatus.FORBIDDEN); } 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()); @@ -103,8 +108,9 @@ public class DocumentApi { if (httpResponse != null) { httpResponse.setHeader(RESPONSE_HEADER_RESOURCE_VERSION, result.getResultVersion()); } - Response response = Response.status(result.getResultCode()).entity(output).build(); - logResult(request, Response.Status.fromStatusCode(response.getStatus())); + ResponseEntity response = ResponseEntity.status(result.getResultCode()).contentType ( MediaType.APPLICATION_JSON ).body(output); + logResult(request, HttpStatus.valueOf ( response.getStatusCodeValue () )); + logResult(request, HttpStatus.valueOf ( response.getStatusCodeValue () )); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. @@ -112,13 +118,13 @@ public class DocumentApi { return response; } catch (Exception e) { - return handleError(request, e.getMessage(), Status.INTERNAL_SERVER_ERROR); + return handleError(request, e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } - public Response processPut(String content, HttpServletRequest request, HttpHeaders headers, - HttpServletResponse httpResponse, String index, String id, - DocumentStoreInterface documentStore) { + public ResponseEntity processPut(String content, HttpServletRequest request, HttpHeaders headers, + HttpServletResponse httpResponse, String index, + String id, DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); @@ -127,7 +133,7 @@ public class DocumentApi { ObjectMapper mapper = new ObjectMapper(); mapper.setSerializationInclusion(Include.NON_EMPTY); if (content == null) { - return handleError(request, content, Status.BAD_REQUEST); + return handleError(request, content, HttpStatus.BAD_REQUEST); } boolean isValid; @@ -135,17 +141,17 @@ 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); + return handleError(request, content, HttpStatus.FORBIDDEN); } if (!isValid) { - return handleError(request, content, Status.FORBIDDEN); + return handleError(request, content, HttpStatus.FORBIDDEN); } - String resourceVersion = - headers.getRequestHeaders().getFirst(REQUEST_HEADER_RESOURCE_VERSION); + String resourceVersion = headers.getFirst(REQUEST_HEADER_RESOURCE_VERSION); DocumentStoreDataEntityImpl document = new DocumentStoreDataEntityImpl(); document.setId(id); @@ -170,8 +176,8 @@ public class DocumentApi { if (httpResponse != null) { httpResponse.setHeader(RESPONSE_HEADER_RESOURCE_VERSION, result.getResultVersion()); } - Response response = Response.status(result.getResultCode()).entity(output).build(); - logResult(request, Response.Status.fromStatusCode(response.getStatus())); + ResponseEntity response = ResponseEntity.status(result.getResultCode()).contentType ( MediaType.APPLICATION_JSON ).body(output); + logResult(request, HttpStatus.valueOf ( response.getStatusCodeValue () )); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. @@ -179,13 +185,13 @@ public class DocumentApi { return response; } catch (Exception e) { - return handleError(request, e.getMessage(), Status.INTERNAL_SERVER_ERROR); + return handleError(request, e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } - public Response processDelete(String content, HttpServletRequest request, HttpHeaders headers, - HttpServletResponse httpResponse, String index, String id, - DocumentStoreInterface documentStore) { + public ResponseEntity processDelete(String content, HttpServletRequest request, HttpHeaders headers, + HttpServletResponse httpResponse, String index, String id, + DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); @@ -198,20 +204,20 @@ 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); + return handleError(request, content, HttpStatus.FORBIDDEN); } if (!isValid) { - return handleError(request, content, Status.FORBIDDEN); + return handleError(request, content, HttpStatus.FORBIDDEN); } - String resourceVersion = - headers.getRequestHeaders().getFirst(REQUEST_HEADER_RESOURCE_VERSION); + String resourceVersion = headers.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); + HttpStatus.BAD_REQUEST); } DocumentStoreDataEntityImpl document = new DocumentStoreDataEntityImpl(); @@ -229,14 +235,14 @@ public class DocumentApi { if (httpResponse != null) { httpResponse.setHeader(RESPONSE_HEADER_RESOURCE_VERSION, result.getResultVersion()); } - Response response; + ResponseEntity response; if (output == null) { - response = Response.status(result.getResultCode()).build(); + response = ResponseEntity.status(result.getResultCode()).build(); } else { - response = Response.status(result.getResultCode()).entity(output).build(); + response = ResponseEntity.status(result.getResultCode()).contentType ( MediaType.APPLICATION_JSON ).body(output); } - logResult(request, Response.Status.fromStatusCode(response.getStatus())); + logResult(request, HttpStatus.valueOf ( response.getStatusCodeValue () )); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. @@ -244,13 +250,13 @@ public class DocumentApi { return response; } catch (Exception e) { - return handleError(request, e.getMessage(), Status.INTERNAL_SERVER_ERROR); + return handleError(request, e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } - public Response processGet(String content, HttpServletRequest request, HttpHeaders headers, - HttpServletResponse httpResponse, String index, String id, - DocumentStoreInterface documentStore) { + public ResponseEntity processGet(String content, HttpServletRequest request, HttpHeaders headers, + HttpServletResponse httpResponse, String index, String id, + DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); @@ -263,17 +269,17 @@ 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); + return handleError(request, content, HttpStatus.FORBIDDEN); } if (!isValid) { - return handleError(request, content, Status.FORBIDDEN); + return handleError(request, content, HttpStatus.FORBIDDEN); } - String resourceVersion = - headers.getRequestHeaders().getFirst(REQUEST_HEADER_RESOURCE_VERSION); + String resourceVersion = headers.getFirst(REQUEST_HEADER_RESOURCE_VERSION); DocumentStoreDataEntityImpl document = new DocumentStoreDataEntityImpl(); document.setId(id); @@ -291,8 +297,8 @@ public class DocumentApi { if (httpResponse != null) { httpResponse.setHeader(RESPONSE_HEADER_RESOURCE_VERSION, result.getResultVersion()); } - Response response = Response.status(result.getResultCode()).entity(output).build(); - logResult(request, Response.Status.fromStatusCode(response.getStatus())); + ResponseEntity response = ResponseEntity.status(result.getResultCode()).contentType ( MediaType.APPLICATION_JSON ).body(output); + logResult(request, HttpStatus.valueOf ( response.getStatusCodeValue () )); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. @@ -300,12 +306,13 @@ public class DocumentApi { return response; } catch (Exception e) { - return handleError(request, e.getMessage(), Status.INTERNAL_SERVER_ERROR); + return handleError(request, e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } - public Response processSearchWithGet(String content, HttpServletRequest request, - HttpHeaders headers, String index, String queryText, DocumentStoreInterface documentStore) { + public ResponseEntity processSearchWithGet(String content, HttpServletRequest request, + HttpHeaders headers, String index, + String queryText, DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); @@ -319,26 +326,27 @@ 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); + return handleError(request, content, HttpStatus.FORBIDDEN); } if (!isValid) { - return handleError(request, content, Status.FORBIDDEN); + return handleError(request, content, HttpStatus.FORBIDDEN); } 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()) : result.getFailureCause(); } - Response response = Response.status(result.getResultCode()).entity(output).build(); + ResponseEntity response = ResponseEntity.status(result.getResultCode()).contentType ( MediaType.APPLICATION_JSON ).body(output); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. @@ -346,32 +354,34 @@ public class DocumentApi { return response; } catch (Exception e) { - return handleError(request, e.getMessage(), Status.INTERNAL_SERVER_ERROR); + return handleError(request, e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } - public Response queryWithGetWithPayload(String content, HttpServletRequest request, - HttpHeaders headers, String index, DocumentStoreInterface documentStore) { + public ResponseEntity queryWithGetWithPayload(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, "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); } return processQuery(index, content, request, headers, documentStore); } - public Response processSearchWithPost(String content, HttpServletRequest request, - HttpHeaders headers, String index, DocumentStoreInterface documentStore) { + public ResponseEntity processSearchWithPost(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() : ""); + logger.info(SearchDbMsgs.PROCESS_PAYLOAD_QUERY, "POST", (request != null) + ? request.getRequestURL ().toString () : ""); if (logger.isDebugEnabled()) { logger.debug("Request Body: " + content); } @@ -379,14 +389,15 @@ public class DocumentApi { return processQuery(index, content, request, headers, documentStore); } - public Response processSuggestQueryWithPost(String content, HttpServletRequest request, - HttpHeaders headers, String index, DocumentStoreInterface documentStore) { + + public ResponseEntity 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() : ""); + (request != null) ? request.getRequestURL().toString() : ""); if (logger.isDebugEnabled()) { logger.debug("Request Body: " + content); } @@ -395,17 +406,17 @@ public class DocumentApi { } /** - * 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) { + private ResponseEntity processQuery(String index, String content, HttpServletRequest request, + HttpHeaders headers, DocumentStoreInterface documentStore) { try { ObjectMapper mapper = new ObjectMapper(); @@ -413,7 +424,7 @@ public class DocumentApi { // Make sure that we were supplied a payload before proceeding. if (content == null) { - return handleError(request, content, Status.BAD_REQUEST); + return handleError(request, content, HttpStatus.BAD_REQUEST); } // Validate that the request has the appropriate authorization. @@ -423,12 +434,14 @@ public class DocumentApi { ApiUtils.SEARCH_AUTH_POLICY_NAME); } catch (Exception e) { - logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "processQuery", e.getMessage()); - return handleError(request, content, Status.FORBIDDEN); + logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, + "processQuery", + e.getMessage()); + return handleError(request, content, HttpStatus.FORBIDDEN); } if (!isValid) { - return handleError(request, content, Status.FORBIDDEN); + return handleError(request, content, HttpStatus.FORBIDDEN); } SearchStatement searchStatement; @@ -439,13 +452,13 @@ public class DocumentApi { searchStatement = mapper.readValue(content, SearchStatement.class); } catch (Exception e) { - return handleError(request, e.getMessage(), Status.BAD_REQUEST); + return handleError(request, e.getMessage(), HttpStatus.BAD_REQUEST); } // 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); @@ -454,7 +467,7 @@ public class DocumentApi { ? mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getError()) : result.getFailureCause(); } - Response response = Response.status(result.getResultCode()).entity(output).build(); + ResponseEntity response = ResponseEntity.status(result.getResultCode()).contentType ( MediaType.APPLICATION_JSON ).body(output); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. @@ -463,10 +476,11 @@ public class DocumentApi { return response; } catch (Exception e) { - return handleError(request, e.getMessage(), Status.INTERNAL_SERVER_ERROR); + return handleError(request, e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR); } } + /** * Common handler for query requests. This is called by both the GET with payload and POST with * payload variants of the query endpoint. @@ -477,8 +491,8 @@ public class DocumentApi { * @param headers - The HTTP headers. * @return - A standard HTTP response. */ - private Response processSuggestQuery(String index, String content, HttpServletRequest request, - HttpHeaders headers, DocumentStoreInterface documentStore) { + private ResponseEntity processSuggestQuery(String index, String content, HttpServletRequest request, + HttpHeaders headers, DocumentStoreInterface documentStore) { try { ObjectMapper mapper = new ObjectMapper(); @@ -486,22 +500,22 @@ public class DocumentApi { // Make sure that we were supplied a payload before proceeding. if (content == null) { - return handleError(request, content, Status.BAD_REQUEST); + return handleError(request, content, HttpStatus.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); + ApiUtils.SEARCH_AUTH_POLICY_NAME); } catch (Exception e) { logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "processQuery", e.getMessage()); - return handleError(request, content, Status.FORBIDDEN); + return handleError(request, content, HttpStatus.FORBIDDEN); } if (!isValid) { - return handleError(request, content, Status.FORBIDDEN); + return handleError(request, content, HttpStatus.FORBIDDEN); } SuggestionStatement suggestionStatement; @@ -512,22 +526,22 @@ public class DocumentApi { suggestionStatement = mapper.readValue(content, SuggestionStatement.class); } catch (Exception e) { - return handleError(request, e.getMessage(), Status.BAD_REQUEST); + return handleError(request, e.getMessage(), HttpStatus.BAD_REQUEST); } // Now, submit the search statement, translated into // ElasticSearch syntax, to the document store DAO. SearchOperationResult result = - documentStore.suggestionQueryWithPayload(index, suggestionStatement.toElasticSearch()); + 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(); + ? mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getError()) + : result.getFailureCause(); } - Response response = Response.status(result.getResultCode()).entity(output).build(); + ResponseEntity response = ResponseEntity.status(result.getResultCode()).body(output); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. @@ -536,82 +550,83 @@ public class DocumentApi { return response; } catch (Exception e) { - return handleError(request, e.getMessage(), Status.INTERNAL_SERVER_ERROR); + return handleError(request, e.getMessage(), HttpStatus.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. + * 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 = - headers.getRequestHeaders().getFirst(REQUEST_HEADER_ALLOW_IMPLICIT_INDEX_CREATION); - - if ((implicitIndexCreationHeader != null) && (implicitIndexCreationHeader.equals("true"))) { + String implicitIndexCreationHeader = + headers.getFirst(REQUEST_HEADER_ALLOW_IMPLICIT_INDEX_CREATION); + + if( (implicitIndexCreationHeader != null) && (implicitIndexCreationHeader.equals("true")) ) { createIndexIfNotPresent = true; } - + return createIndexIfNotPresent; } private String prepareOutput(ObjectMapper mapper, SearchOperationResult result) - throws JsonProcessingException { + throws JsonProcessingException { StringBuffer output = new StringBuffer(); output.append("{\r\n\"searchResult\":"); output.append( - mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getSearchResult())); + 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)); + .writerWithDefaultPrettyPrinter().writeValueAsString(aggs)); } output.append("\r\n}"); return output.toString(); } private String prepareSuggestOutput(ObjectMapper mapper, SearchOperationResult result) - throws JsonProcessingException { + throws JsonProcessingException { StringBuffer output = new StringBuffer(); output.append("{\r\n\"searchResult\":"); output.append( - mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getSuggestResult())); + mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getSuggestResult())); AggregationResults aggs = result.getAggregationResult(); if (aggs != null) { output.append(",\r\n\"aggregationResult\":"); output.append(mapper.setSerializationInclusion(Include.NON_NULL) - .writerWithDefaultPrettyPrinter().writeValueAsString(aggs)); + .writerWithDefaultPrettyPrinter().writeValueAsString(aggs)); } output.append("\r\n}"); return output.toString(); } - private Response handleError(HttpServletRequest request, String message, Status status) { + private ResponseEntity handleError( HttpServletRequest request, String message, HttpStatus status) { logResult(request, status); - return Response.status(status).entity(message).type(MediaType.APPLICATION_JSON).build(); + return ResponseEntity.status(status).contentType ( MediaType.APPLICATION_JSON ).body(message); } - void logResult(HttpServletRequest request, Response.Status status) { + void logResult(HttpServletRequest request, HttpStatus status) { - logger.info(SearchDbMsgs.PROCESS_REST_REQUEST, (request != null) ? request.getMethod() : "", - (request != null) ? request.getRequestURL().toString() : "", - (request != null) ? request.getRemoteHost() : "", Integer.toString(status.getStatusCode())); + logger.info(SearchDbMsgs.PROCESS_REST_REQUEST, (request != null) ? request.getMethod().toString () : "", + (request != null) ? request.getRequestURL ().toString () : "", + (request != null) ? request.getRemoteHost () : "", Integer.toString(status.value ())); auditLogger.info(SearchDbMsgs.PROCESS_REST_REQUEST, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, status.getStatusCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, status.value()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, status.getReasonPhrase()), - (request != null) ? request.getMethod() : "", - (request != null) ? request.getRequestURL().toString() : "", - (request != null) ? request.getRemoteHost() : "", Integer.toString(status.getStatusCode())); + (request != null) ? request.getMethod().toString () : "", + (request != null) ? request.getRequestURL ().toString () : "", + (request != null) ? request.getRemoteHost () : "", Integer.toString(status.value())); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. diff --git a/src/main/java/org/onap/aai/sa/rest/IndexApi.java b/src/main/java/org/onap/aai/sa/rest/IndexApi.java index 36570dc..d43fa8b 100644 --- a/src/main/java/org/onap/aai/sa/rest/IndexApi.java +++ b/src/main/java/org/onap/aai/sa/rest/IndexApi.java @@ -32,12 +32,18 @@ import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.sa.rest.DocumentFieldSchema; import org.onap.aai.sa.rest.DocumentSchema; +import org.slf4j.MDC; import java.io.FileNotFoundException; import java.io.IOException; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.core.HttpHeaders; -import javax.ws.rs.core.Response; + +// Spring Imports +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.HttpStatus; +// import org.springframework.http.server.HttpServletRequest; /** @@ -46,8 +52,8 @@ import javax.ws.rs.core.Response; */ public class IndexApi { + private static final String HEADER_VALIDATION_SUCCESS = "SUCCESS"; - protected SearchServiceApi searchService = null; /** @@ -57,9 +63,9 @@ public class IndexApi { // Set up the loggers. private static Logger logger = LoggerFactory.getInstance() - .getLogger(IndexApi.class.getName()); + .getLogger(IndexApi.class.getName()); private static Logger auditLogger = LoggerFactory.getInstance() - .getAuditLogger(IndexApi.class.getName()); + .getAuditLogger(IndexApi.class.getName()); public IndexApi(SearchServiceApi searchService) { @@ -92,15 +98,15 @@ public class IndexApi { * @param index - The name of the index to create. * @return - A Standard REST response */ - public Response processCreateIndex(String documentSchema, - HttpServletRequest request, - HttpHeaders headers, - String index, - DocumentStoreInterface documentStore) { + public ResponseEntity processCreateIndex (String documentSchema, + HttpServletRequest request, + HttpHeaders headers, + String index, + DocumentStoreInterface documentStore) { int resultCode = 500; String resultString = "Unexpected error"; - + // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); @@ -109,16 +115,16 @@ public class IndexApi { try { if (!searchService.validateRequest(headers, request, - ApiUtils.Action.POST, ApiUtils.SEARCH_AUTH_POLICY_NAME)) { + ApiUtils.Action.POST, ApiUtils.SEARCH_AUTH_POLICY_NAME)) { logger.warn(SearchDbMsgs.INDEX_CREATE_FAILURE, index, "Authentication failure."); - return errorResponse(Response.Status.FORBIDDEN, "Authentication failure.", request); + return errorResponse(HttpStatus.FORBIDDEN, "Authentication failure.", request); } } catch (Exception e) { logger.warn(SearchDbMsgs.INDEX_CREATE_FAILURE, index, - "Unexpected authentication failure - cause: " + e.getMessage()); - return errorResponse(Response.Status.FORBIDDEN, "Authentication failure.", request); + "Unexpected authentication failure - cause: " + e.getMessage()); + return errorResponse(HttpStatus.FORBIDDEN, "Authentication failure.", request); } @@ -126,7 +132,7 @@ public class IndexApi { // it is present. if (documentSchema == null) { logger.warn(SearchDbMsgs.INDEX_CREATE_FAILURE, index, "Missing document schema payload"); - return errorResponse(Response.Status.fromStatusCode(resultCode), "Missing payload", request); + return errorResponse(HttpStatus.valueOf(resultCode), "Missing payload", request); } try { @@ -146,27 +152,28 @@ public class IndexApi { // translate that int a 201. resultCode = (result.getResultCode() == 200) ? 201 : result.getResultCode(); resultString = (result.getFailureCause() == null) - ? result.getResult() : result.getFailureCause(); + ? result.getResult() : result.getFailureCause(); } catch (com.fasterxml.jackson.core.JsonParseException - | com.fasterxml.jackson.databind.JsonMappingException e) { + | com.fasterxml.jackson.databind.JsonMappingException e) { // We were unable to marshal the supplied json string into a valid // document schema, so return an appropriate error response. - resultCode = javax.ws.rs.core.Response.Status.BAD_REQUEST.getStatusCode(); + resultCode = HttpStatus.BAD_REQUEST.value(); resultString = "Malformed schema: " + e.getMessage(); } catch (IOException e) { // We'll treat this is a general internal error. - resultCode = javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR.getStatusCode(); + resultCode = HttpStatus.INTERNAL_SERVER_ERROR.value(); resultString = "IO Failure: " + e.getMessage(); } - Response response = Response.status(resultCode).entity(resultString).build(); + ResponseEntity response = ResponseEntity.status(resultCode).contentType ( MediaType.APPLICATION_JSON ).body(resultString); + // Log the result. - if ((response.getStatus() >= 200) && (response.getStatus() < 300)) { + if ((response.getStatusCodeValue() >= 200) && (response.getStatusCodeValue() < 300)) { logger.info(SearchDbMsgs.CREATED_INDEX, index); } else { logger.warn(SearchDbMsgs.INDEX_CREATE_FAILURE, index, resultString); @@ -174,14 +181,16 @@ public class IndexApi { // Generate our audit log. auditLogger.info(SearchDbMsgs.PROCESS_REST_REQUEST, - new LogFields() - .setField(LogLine.DefinedFields.RESPONSE_CODE, resultCode) - .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, - Response.Status.fromStatusCode(resultCode).toString()), - (request != null) ? request.getMethod() : "Unknown", - (request != null) ? request.getRequestURL().toString() : "Unknown", - (request != null) ? request.getRemoteHost() : "Unknown", - Integer.toString(response.getStatus())); + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, resultCode) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, + HttpStatus.valueOf(resultCode).toString()), + (request != null) ? request.getMethod().toString () : "Unknown", + (request != null) ? request.getRequestURL ().toString () : "Unknown", + (request != null) ? request.getRemoteHost () : "Unknown", + Integer.toString(response.getStatusCodeValue ())); + + // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. @@ -190,27 +199,28 @@ public class IndexApi { // Finally, return the response. return response; } - + /** - * This function accepts any JSON and will "blindly" write it to the + * This function accepts any JSON and will "blindly" write it to the * document store. - * + * * Note, eventually this "dynamic" flow should follow the same JSON-Schema * validation procedure as the normal create index flow. - * + * * @param dynamicSchema - The JSON string that will be sent to the document store. * @param index - The name of the index to be created. * @param documentStore - The document store specific interface. * @return The result of the document store interface's operation. */ - public Response processCreateDynamicIndex(String dynamicSchema, HttpServletRequest request, - HttpHeaders headers, String index, DocumentStoreInterface documentStore) { + public ResponseEntity processCreateDynamicIndex(String dynamicSchema, HttpServletRequest request, + HttpHeaders headers, String index, DocumentStoreInterface documentStore) { + + ResponseEntity response = null; - Response response = null; + ResponseEntity validationResponse = validateRequest(request, headers, index, SearchDbMsgs.INDEX_CREATE_FAILURE); - Response validationResponse = validateRequest(request, headers, index, SearchDbMsgs.INDEX_CREATE_FAILURE); - if (validationResponse.getStatus() != Response.Status.OK.getStatusCode()) { + if (validationResponse.getStatusCodeValue () != HttpStatus.OK.value ()) { response = validationResponse; } else { OperationResult result = documentStore.createDynamicIndex(index, dynamicSchema); @@ -218,13 +228,12 @@ public class IndexApi { int resultCode = (result.getResultCode() == 200) ? 201 : result.getResultCode(); String resultString = (result.getFailureCause() == null) ? result.getResult() : result.getFailureCause(); - response = Response.status(resultCode).entity(resultString).build(); + response = ResponseEntity.status(resultCode).body(resultString); } return response; } - /** * Processes a client request to remove an index from the document store. * Note that this implicitly deletes all documents contained within that index. @@ -232,63 +241,60 @@ public class IndexApi { * @param index - The index to be deleted. * @return - A standard REST response. */ - public Response processDelete(String index, - HttpServletRequest request, - HttpHeaders headers, - DocumentStoreInterface documentStore) { + public ResponseEntity processDelete(String index, + HttpServletRequest request, + HttpHeaders headers, + DocumentStoreInterface documentStore) { // Initialize the MDC Context for logging purposes. ApiUtils.initMdcContext(request, headers); // Set a default response in case something unexpected goes wrong. - Response response = Response.status(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR) - .entity("Unknown") - .build(); + ResponseEntity response = ResponseEntity.status ( HttpStatus.INTERNAL_SERVER_ERROR ).body ( "Unknown" ); // Validate that the request is correctly authenticated before going // any further. try { if (!searchService.validateRequest(headers, request, ApiUtils.Action.POST, - ApiUtils.SEARCH_AUTH_POLICY_NAME)) { + ApiUtils.SEARCH_AUTH_POLICY_NAME)) { logger.warn(SearchDbMsgs.INDEX_CREATE_FAILURE, index, "Authentication failure."); - return errorResponse(Response.Status.FORBIDDEN, "Authentication failure.", request); + return errorResponse(HttpStatus.FORBIDDEN, "Authentication failure.", request); } } catch (Exception e) { logger.warn(SearchDbMsgs.INDEX_CREATE_FAILURE, index, - "Unexpected authentication failure - cause: " + e.getMessage()); - return errorResponse(Response.Status.FORBIDDEN, "Authentication failure.", request); + "Unexpected authentication failure - cause: " + e.getMessage()); + return errorResponse(HttpStatus.FORBIDDEN, "Authentication failure.", request); } + try { // Send the request to the document store. response = responseFromOperationResult(documentStore.deleteIndex(index)); } catch (DocumentStoreOperationException e) { - response = Response.status(javax.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR) - .entity(e.getMessage()) - .build(); + response = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType ( MediaType.APPLICATION_JSON ).body(e.getMessage()); } - + // Log the result. - if ((response.getStatus() >= 200) && (response.getStatus() < 300)) { + if ((response.getStatusCodeValue() >= 200) && (response.getStatusCodeValue() < 300)) { logger.info(SearchDbMsgs.DELETED_INDEX, index); } else { - logger.warn(SearchDbMsgs.INDEX_DELETE_FAILURE, index, (String) response.getEntity()); + logger.warn(SearchDbMsgs.INDEX_DELETE_FAILURE, index, (String) response.getBody ()); } // Generate our audit log. auditLogger.info(SearchDbMsgs.PROCESS_REST_REQUEST, - new LogFields() - .setField(LogLine.DefinedFields.RESPONSE_CODE, response.getStatus()) - .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, - response.getStatusInfo().getReasonPhrase()), - (request != null) ? request.getMethod() : "Unknown", - (request != null) ? request.getRequestURL().toString() : "Unknown", - (request != null) ? request.getRemoteHost() : "Unknown", - Integer.toString(response.getStatus())); + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, response.getStatusCodeValue()) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, + response.getStatusCode ().getReasonPhrase()), + (request != null) ? request.getMethod().toString () : "Unknown", + (request != null) ? request.getRequestURL ().toString () : "Unknown", + (request != null) ? request.getRemoteHost () : "Unknown", + Integer.toString(response.getStatusCodeValue())); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. @@ -309,8 +315,8 @@ public class IndexApi { * @throws IOException */ public String generateDocumentMappings(String documentSchema) - throws com.fasterxml.jackson.core.JsonParseException, - com.fasterxml.jackson.databind.JsonMappingException, IOException { + throws com.fasterxml.jackson.core.JsonParseException, + com.fasterxml.jackson.databind.JsonMappingException, IOException { // Unmarshal the json content into a document schema object. ObjectMapper mapper = new ObjectMapper(); @@ -338,7 +344,7 @@ public class IndexApi { // If the index field was specified, then append it. if (field.getSearchable() != null) { sb.append(", \"index\": \"").append(field.getSearchable() - ? "analyzed" : "not_analyzed").append("\""); + ? "analyzed" : "not_analyzed").append("\""); } // If a search analyzer was specified, then append it. @@ -366,65 +372,64 @@ public class IndexApi { /** - * Converts an {@link OperationResult} to a standard REST {@link Response} + * Converts an {@link OperationResult} to a standard REST {@link ResponseEntity} * object. * * @param result - The {@link OperationResult} to be converted. - * @return - The equivalent {@link Response} object. + * @return - The equivalent {@link ResponseEntity} object. */ - public Response responseFromOperationResult(OperationResult result) { + public ResponseEntity responseFromOperationResult(OperationResult result) { if ((result.getResultCode() >= 200) && (result.getResultCode() < 300)) { - return Response.status(result.getResultCode()).entity(result.getResult()).build(); + return ResponseEntity.status(result.getResultCode()).contentType ( MediaType.APPLICATION_JSON ).body(result.getResult()); } else { if (result.getFailureCause() != null) { - return Response.status(result.getResultCode()).entity(result.getFailureCause()).build(); + return ResponseEntity.status(result.getResultCode()).contentType ( MediaType.APPLICATION_JSON ).body(result.getFailureCause()); } else { - return Response.status(result.getResultCode()).entity(result.getResult()).build(); + return ResponseEntity.status(result.getResultCode()).contentType ( MediaType.APPLICATION_JSON ).body(result.getResult()); } } } - public Response errorResponse(Response.Status status, String msg, HttpServletRequest request) { + public ResponseEntity errorResponse(HttpStatus status, String msg, HttpServletRequest request) { // Generate our audit log. auditLogger.info(SearchDbMsgs.PROCESS_REST_REQUEST, - new LogFields() - .setField(LogLine.DefinedFields.RESPONSE_CODE, status.getStatusCode()) - .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, status.getReasonPhrase()), - (request != null) ? request.getMethod() : "Unknown", - (request != null) ? request.getRequestURL().toString() : "Unknown", - (request != null) ? request.getRemoteHost() : "Unknown", - Integer.toString(status.getStatusCode())); + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, status.value ()) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, status.getReasonPhrase()), + (request != null) ? request.getMethod().toString () : "Unknown", + (request != null) ? request.getRequestURL ().toString () : "Unknown", + (request != null) ? request.getRemoteHost () : "Unknown", + Integer.toString(status.value ())); // Clear the MDC context so that no other transaction inadvertently // uses our transaction id. ApiUtils.clearMdcContext(); - return Response.status(status) - .entity(msg) - .build(); + return ResponseEntity.status(status).contentType ( MediaType.APPLICATION_JSON ).body(msg); } - + + /** * A helper method used for validating/authenticating an incoming request. - * + * * @param request - The http request that will be validated. * @param headers - The http headers that will be validated. * @param index - The name of the index that the document store request is being made against. * @param failureMsgEnum - The logging message to be used upon validation failure. * @return A success or failure response */ - private Response validateRequest(HttpServletRequest request, HttpHeaders headers, String index, SearchDbMsgs failureMsgEnum) { + private ResponseEntity validateRequest(HttpServletRequest request, HttpHeaders headers, String index, SearchDbMsgs failureMsgEnum) { try { if (!searchService.validateRequest(headers, request, ApiUtils.Action.POST, ApiUtils.SEARCH_AUTH_POLICY_NAME)) { logger.warn(failureMsgEnum, index, "Authentication failure."); - return errorResponse(Response.Status.FORBIDDEN, "Authentication failure.", request); + return errorResponse(HttpStatus.FORBIDDEN, "Authentication failure.", request); } } catch (Exception e) { logger.warn(failureMsgEnum, index, "Unexpected authentication failure - cause: " + e.getMessage()); - return errorResponse(Response.Status.FORBIDDEN, "Authentication failure.", request); + return errorResponse(HttpStatus.FORBIDDEN, "Authentication failure.", request); } - return Response.status(Response.Status.OK).entity(HEADER_VALIDATION_SUCCESS).build(); + return ResponseEntity.status(HttpStatus.OK).body(HEADER_VALIDATION_SUCCESS); } } diff --git a/src/main/java/org/onap/aai/sa/rest/SearchServiceApi.java b/src/main/java/org/onap/aai/sa/rest/SearchServiceApi.java index 99b4615..9552658 100644 --- a/src/main/java/org/onap/aai/sa/rest/SearchServiceApi.java +++ b/src/main/java/org/onap/aai/sa/rest/SearchServiceApi.java @@ -24,27 +24,28 @@ import org.onap.aai.sa.auth.SearchDbServiceAuth; import org.onap.aai.sa.rest.ApiUtils.Action; import org.onap.aai.sa.searchdbabstraction.elasticsearch.dao.DocumentStoreInterface; import org.onap.aai.sa.searchdbabstraction.elasticsearch.dao.ElasticSearchHttpController; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.*; -import java.security.cert.X509Certificate; import javax.security.auth.x500.X500Principal; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.ws.rs.Consumes; -import javax.ws.rs.DELETE; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -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 java.security.cert.X509Certificate; + +// import javax.servlet.http.HttpServletRequest; +@Component +@EnableWebSecurity +@RestController +@RequestMapping("/services/search-db-service/v1") public class SearchServiceApi { /** - * The Data Access Object that we will use to interact with the document store. + * The Data Access Object that we will use to interact with the + * document store. */ protected DocumentStoreInterface documentStore = null; protected ApiUtils apiUtils = null; @@ -58,6 +59,7 @@ public class SearchServiceApi { init(); } + /** * Performs all one-time initialization required for the end point. */ @@ -69,152 +71,179 @@ public class SearchServiceApi { apiUtils = new ApiUtils(); } - @PUT - @Path("/indexes/{index}") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processCreateIndex(String requestBody, @Context HttpServletRequest request, - @Context HttpHeaders headers, @PathParam("index") String index) { + @RequestMapping(value = "/indexes/{index}", + method = RequestMethod.PUT, + produces = { "application/json" }) + public ResponseEntity processCreateIndex(@RequestBody String requestBody, + HttpServletRequest request, + @RequestHeader HttpHeaders headers, + @PathVariable("index") String index) { // Forward the request to our index API to create the index. IndexApi indexApi = new IndexApi(this); return indexApi.processCreateIndex(requestBody, request, headers, index, documentStore); } - @PUT - @Path("/indexes/dynamic/{index}") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processCreateDynamicIndex(String requestBody, @Context HttpServletRequest request, - @Context HttpHeaders headers, @PathParam("index") String index) { - - // Forward the request to our index API to create the index. - IndexApi indexApi = new IndexApi(this); - return indexApi.processCreateDynamicIndex(requestBody, request, headers, index, documentStore); - } - - @DELETE - @Path("/indexes/{index}") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processDeleteIndex(String requestBody, @Context HttpServletRequest request, - @Context HttpHeaders headers, @PathParam("index") String index) { + @RequestMapping(value = "/indexes/{index}", + method = RequestMethod.DELETE, + consumes = {"application/json"}, + produces = {"application/json"}) + public ResponseEntity processDeleteIndex(String requestBody, + HttpServletRequest request, + @RequestHeader HttpHeaders headers, + @PathVariable ("index") String index) { // Forward the request to our index API to delete the index. IndexApi indexApi = new IndexApi(this); return indexApi.processDelete(index, request, headers, documentStore); } - @GET - @Path("/indexes/{index}/documents/{id}") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processGetDocument(String requestBody, @Context HttpServletRequest request, - @Context HttpServletResponse httpResponse, @Context HttpHeaders headers, - @PathParam("index") String index, @PathParam("id") String id) { - // Forward the request to our document API to retrieve the document. + @RequestMapping(value = "/indexes/{index}/documents", + method = RequestMethod.POST, + consumes = {"application/json"}) + public ResponseEntity processCreateDocWithoutId(String requestBody, + HttpServletRequest request, + HttpServletResponse httpResponse, + @RequestHeader HttpHeaders headers, + @PathVariable ("index") String index) { + + // Forward the request to our document API to create the document. DocumentApi documentApi = new DocumentApi(this); - return documentApi.processGet(requestBody, request, headers, httpResponse, index, id, - documentStore); + return documentApi.processPost(requestBody, request, headers, httpResponse, + index, documentStore); } - @POST - @Path("/indexes/{index}/documents") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processCreateDocWithoutId(String requestBody, @Context HttpServletRequest request, - @Context HttpServletResponse httpResponse, @Context HttpHeaders headers, - @PathParam("index") String index) { + @RequestMapping(value = "/indexes/{index}/documents/{id}", + method = RequestMethod.PUT, + consumes = {"application/json"}) + public ResponseEntity processUpsertDoc(String requestBody, + HttpServletRequest request, + HttpServletResponse httpResponse, + @RequestHeader HttpHeaders headers, + @PathVariable ("index") String index, + @PathVariable ("id") String id) { - // Forward the request to our document API to create the document. + // Forward the request to our document API to upsert the document. DocumentApi documentApi = new DocumentApi(this); - return documentApi.processPost(requestBody, request, headers, httpResponse, index, - documentStore); + return documentApi.processPut(requestBody, request, headers, httpResponse, + index, id, documentStore); } - @PUT - @Path("/indexes/{index}/documents/{id}") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processUpsertDoc(String requestBody, @Context HttpServletRequest request, - @Context HttpServletResponse httpResponse, @Context HttpHeaders headers, - @PathParam("index") String index, @PathParam("id") String id) { + @RequestMapping(value = "/indexes/{index}/documents/{id}", + method = RequestMethod.GET) + public ResponseEntity processGetDocument(String requestBody, + HttpServletRequest request, + HttpServletResponse httpResponse, + @RequestHeader HttpHeaders headers, + @PathVariable ("index") String index, + @PathVariable ("id") String id) { - // Forward the request to our document API to upsert the document. + // Forward the request to our document API to retrieve the document. DocumentApi documentApi = new DocumentApi(this); - return documentApi.processPut(requestBody, request, headers, httpResponse, index, id, - documentStore); + return documentApi.processGet(requestBody, request, headers, httpResponse, + index, id, documentStore); } - @DELETE - @Path("/indexes/{index}/documents/{id}") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processDeleteDoc(String requestBody, @Context HttpServletRequest request, - @Context HttpServletResponse httpResponse, @Context HttpHeaders headers, - @PathParam("index") String index, @PathParam("id") String id) { + @RequestMapping(value = "/indexes/{index}/documents/{id}", + method = RequestMethod.DELETE, + consumes = {"application/json"}) + public ResponseEntity processDeleteDoc(String requestBody, + HttpServletRequest request, + HttpServletResponse httpResponse, + @RequestHeader HttpHeaders headers, + @PathVariable ("index") String index, + @PathVariable ("id") String id) { // Forward the request to our document API to delete the document. DocumentApi documentApi = new DocumentApi(this); - return documentApi.processDelete(requestBody, request, headers, httpResponse, index, id, - documentStore); + return documentApi.processDelete(requestBody, request, headers, httpResponse, + index, id, documentStore); } - @GET - @Path("/indexes/{index}/query/{queryText}") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processInlineQuery(String requestBody, @Context HttpServletRequest request, - @Context HttpHeaders headers, @PathParam("index") String index, - @PathParam("queryText") String queryText) { + @RequestMapping(value = "/indexes/{index}/query/{queryText}", + method = RequestMethod.GET, + consumes = {"application/json"}) + public ResponseEntity processInlineQuery(String requestBody, + HttpServletRequest request, + @RequestHeader HttpHeaders headers, + @PathVariable ("index") String index, + @PathVariable ("queryText") String queryText) { // Forward the request to our document API to delete the document. DocumentApi documentApi = new DocumentApi(this); - return documentApi.processSearchWithGet(requestBody, request, headers, index, queryText, - documentStore); + return documentApi.processSearchWithGet(requestBody, request, headers, + index, queryText, documentStore); } - @GET - @Path("/indexes/{index}/query") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processQueryWithGet(String requestBody, @Context HttpServletRequest request, - @Context HttpHeaders headers, @PathParam("index") String index) { + @RequestMapping(value = "/indexes/{index}/query", + method = RequestMethod.GET, + consumes = {"application/json"}) + public ResponseEntity processQueryWithGet(String requestBody, + HttpServletRequest request, + @RequestHeader HttpHeaders headers, + @PathVariable ("index") String index) { // Forward the request to our document API to delete the document. DocumentApi documentApi = new DocumentApi(this); return documentApi.queryWithGetWithPayload(requestBody, request, headers, index, documentStore); } - @POST - @Path("/indexes/{index}/query") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processQuery(String requestBody, @Context HttpServletRequest request, - @Context HttpHeaders headers, @PathParam("index") String index) { + @RequestMapping(value = "/indexes/{index}/query", + method = RequestMethod.POST, + consumes = {"application/json"}) + public ResponseEntity processQuery(String requestBody, + HttpServletRequest request, + @RequestHeader HttpHeaders headers, + @PathVariable ("index") String index) { // Forward the request to our document API to delete the document. DocumentApi documentApi = new DocumentApi(this); return documentApi.processSearchWithPost(requestBody, request, headers, index, documentStore); } - @POST - @Path("/indexes/{index}/suggest") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processSuggestQuery(String requestBody, @Context HttpServletRequest request, - @Context HttpHeaders headers, @PathParam("index") String index) { - + @RequestMapping(value = "/indexes/{index}/suggest", + method = RequestMethod.POST, + consumes = {"application/json"}) + public ResponseEntity processSuggestQuery(String requestBody, HttpServletRequest request, + @RequestHeader HttpHeaders headers, @PathVariable("index") String index) { // Forward the request to our document API to query suggestions in the // document. DocumentApi documentApi = new DocumentApi(this); return documentApi.processSuggestQueryWithPost(requestBody, request, headers, index, - documentStore); + documentStore); + } + + @RequestMapping(value = "/indexes/dynamic/{index}", + method = RequestMethod.PUT, + consumes = {"application/json"}) + public ResponseEntity processCreateDynamicIndex(String requestBody, + HttpServletRequest request, + @RequestHeader HttpHeaders headers, + @PathVariable ("index") String index) { + + // Forward the request to our index API to create the index. + IndexApi indexApi = new IndexApi(this); + return indexApi.processCreateDynamicIndex(requestBody, request, headers, index, documentStore); } - @POST - @Path("/bulk") - @Consumes({MediaType.APPLICATION_JSON}) - public Response processBulkRequest(String requestBody, @Context HttpServletRequest request, - @Context HttpHeaders headers, @PathParam("index") String index) { + @RequestMapping(value = "/bulk", + method = RequestMethod.POST, + consumes = {"application/json"}) + public ResponseEntity processBulkRequest(String requestBody, + HttpServletRequest request, + @RequestHeader HttpHeaders headers) { // Forward the request to our document API to delete the document. BulkApi bulkApi = new BulkApi(this); - return bulkApi.processPost(requestBody, request, headers, documentStore, apiUtils); + ResponseEntity dbugResp = bulkApi.processPost(requestBody, request, headers, documentStore, apiUtils); + return dbugResp; } - protected boolean validateRequest(HttpHeaders headers, HttpServletRequest req, Action action, - String authPolicyFunctionName) throws Exception { + protected boolean validateRequest(HttpHeaders headers, + HttpServletRequest req, + Action action, + String authPolicyFunctionName) throws Exception { SearchDbServiceAuth serviceAuth = new SearchDbServiceAuth(); @@ -235,7 +264,7 @@ public class SearchServiceApi { } String status = serviceAuth.authUser(headers, authUser.toLowerCase(), - action.toString() + ":" + authPolicyFunctionName); + action.toString() + ":" + authPolicyFunctionName); if (!status.equals("OK")) { return false; } diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/config/ElasticSearchConfig.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/config/ElasticSearchConfig.java index b55c8a6..0cf2f2a 100644 --- a/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/config/ElasticSearchConfig.java +++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/config/ElasticSearchConfig.java @@ -36,9 +36,9 @@ public class ElasticSearchConfig { public ElasticSearchConfig(Properties props) { - setClusterName(props.getProperty(ES_CLUSTER_NAME)); - setIpAddress(props.getProperty(ES_IP_ADDRESS)); - setHttpPort(props.getProperty(ES_HTTP_PORT)); + setClusterName(props.getProperty(ES_CLUSTER_NAME)); + setIpAddress(props.getProperty(ES_IP_ADDRESS)); + setHttpPort(props.getProperty(ES_HTTP_PORT)); setJavaApiPort(JAVA_API_PORT_DEFAULT); } diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/DocumentStoreInterface.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/DocumentStoreInterface.java index a3a8e8e..a9d5678 100644 --- a/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/DocumentStoreInterface.java +++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/DocumentStoreInterface.java @@ -20,6 +20,7 @@ */ package org.onap.aai.sa.searchdbabstraction.elasticsearch.dao; + import org.onap.aai.sa.rest.BulkRequest; import org.onap.aai.sa.searchdbabstraction.elasticsearch.exception.DocumentStoreOperationException; import org.onap.aai.sa.searchdbabstraction.entity.DocumentOperationResult; @@ -27,6 +28,7 @@ import org.onap.aai.sa.searchdbabstraction.entity.OperationResult; import org.onap.aai.sa.searchdbabstraction.entity.SearchOperationResult; import org.onap.aai.sa.rest.DocumentSchema; + public interface DocumentStoreInterface { public OperationResult createIndex(String index, DocumentSchema documentSchema); @@ -35,11 +37,15 @@ public interface DocumentStoreInterface { public OperationResult deleteIndex(String indexName) throws DocumentStoreOperationException; - public DocumentOperationResult createDocument(String indexName, DocumentStoreDataEntity document, - boolean allowImplicitIndexCreation) throws DocumentStoreOperationException; + public DocumentOperationResult createDocument(String indexName, + DocumentStoreDataEntity document, + boolean allowImplicitIndexCreation) throws DocumentStoreOperationException; - public DocumentOperationResult updateDocument(String indexName, DocumentStoreDataEntity document, - boolean allowImplicitIndexCreation) throws DocumentStoreOperationException; + public DocumentOperationResult updateDocument(String indexName, + DocumentStoreDataEntity document, + boolean allowImplicitIndexCreation) throws DocumentStoreOperationException; + + public SearchOperationResult suggestionQueryWithPayload(String indexName, String query) throws DocumentStoreOperationException; public DocumentOperationResult deleteDocument(String indexName, DocumentStoreDataEntity document) throws DocumentStoreOperationException; @@ -53,14 +59,14 @@ public interface DocumentStoreInterface { public SearchOperationResult searchWithPayload(String indexName, String query) throws DocumentStoreOperationException; - public SearchOperationResult suggestionQueryWithPayload(String indexName, String query) - throws DocumentStoreOperationException; /** - * Forwards a set of operations to the document store as a single, bulk request. + * Forwards a set of operations to the document store as a single, bulk + * request. * - * @param anIndex - The index to apply the operations to. - * @param operations - A java object containing the set of operations to be performed. + * @param anIndex - The index to apply the operations to. + * @param operations - A java object containing the set of operations to + * be performed. * @return - An operation result. * @throws DocumentStoreOperationException */ diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpController.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpController.java index 00f66e0..ad32129 100644 --- a/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpController.java +++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpController.java @@ -20,7 +20,7 @@ */ package org.onap.aai.sa.searchdbabstraction.elasticsearch.dao; -import com.att.aft.dme2.internal.google.common.base.Throwables; +import com.google.common.base.Throwables; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.core.JsonParseException; import com.fasterxml.jackson.core.JsonProcessingException; @@ -46,8 +46,6 @@ import org.onap.aai.sa.searchdbabstraction.entity.OperationResult; import org.onap.aai.sa.searchdbabstraction.entity.SearchHit; import org.onap.aai.sa.searchdbabstraction.entity.SearchHits; import org.onap.aai.sa.searchdbabstraction.entity.SearchOperationResult; -import org.onap.aai.sa.searchdbabstraction.entity.SuggestHit; -import org.onap.aai.sa.searchdbabstraction.entity.SuggestHits; import org.onap.aai.sa.searchdbabstraction.logging.SearchDbMsgs; import org.onap.aai.sa.searchdbabstraction.util.AggregationParsingUtil; import org.onap.aai.sa.searchdbabstraction.util.DocumentSchemaUtil; @@ -59,6 +57,8 @@ import org.onap.aai.cl.eelf.LoggerFactory; import org.onap.aai.cl.mdc.MdcContext; import org.onap.aai.cl.mdc.MdcOverride; import org.onap.aai.sa.rest.DocumentSchema; +import org.onap.aai.sa.searchdbabstraction.entity.SuggestHit; +import org.onap.aai.sa.searchdbabstraction.entity.SuggestHits; import java.io.BufferedReader; import java.io.File; @@ -81,9 +81,10 @@ import java.util.Properties; import java.util.concurrent.atomic.AtomicBoolean; import javax.ws.rs.core.Response.Status; + /** - * This class has the Elasticsearch implementation of the DB operations defined in - * DocumentStoreInterface. + * This class has the Elasticsearch implementation of the + * DB operations defined in DocumentStoreInterface. */ public class ElasticSearchHttpController implements DocumentStoreInterface { @@ -98,10 +99,10 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { private static final String INTERNAL_SERVER_ERROR_ELASTIC_SEARCH_OPERATION_FAULT = "Internal Error: ElasticSearch operation fault occurred"; - private static final Logger logger = - LoggerFactory.getInstance().getLogger(ElasticSearchHttpController.class.getName()); - private static final Logger metricsLogger = - LoggerFactory.getInstance().getMetricsLogger(ElasticSearchHttpController.class.getName()); + private static final Logger logger = LoggerFactory.getInstance() + .getLogger(ElasticSearchHttpController.class.getName()); + private static final Logger metricsLogger = LoggerFactory.getInstance() + .getMetricsLogger(ElasticSearchHttpController.class.getName()); private final ElasticSearchConfig config; private static final String DEFAULT_TYPE = "default"; @@ -122,7 +123,8 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { properties.load(new FileInputStream(file)); } catch (Exception e) { logger.error(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, - "ElasticSearchHTTPController.getInstance", e.getLocalizedMessage()); + "ElasticSearchHTTPController.getInstance", + e.getLocalizedMessage()); } ElasticSearchConfig config = new ElasticSearchConfig(properties); @@ -142,11 +144,12 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { checkConnection(); logger.info(SearchDbMsgs.ELASTIC_SEARCH_CONNECTION_SUCCESS, getFullUrl("", false)); } catch (Exception e) { - logger.error(SearchDbMsgs.ELASTIC_SEARCH_CONNECTION_FAILURE, null, e, getFullUrl("", false), - e.getMessage()); + logger.error(SearchDbMsgs.ELASTIC_SEARCH_CONNECTION_FAILURE, null, e, + getFullUrl("", false), e.getMessage()); } } + public AnalysisConfiguration getAnalysisConfig() { return analysisConfig; } @@ -161,7 +164,9 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Submit the request to ElasticSearch to create the index using a // default document type. - result = createTable(index, DEFAULT_TYPE, analysisConfig.getEsIndexSettings(), + result = createTable(index, + DEFAULT_TYPE, + analysisConfig.getEsIndexSettings(), DocumentSchemaUtil.generateDocumentMappings(documentSchema)); // ElasticSearch will return us a 200 code on success when we @@ -169,8 +174,7 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { result.setResultCode((result.getResultCode() == 200) ? 201 : result.getResultCode()); if (isSuccess(result)) { result.setResult("{\"url\": \"" + ApiUtils.buildIndexUri(index) + "\"}"); - // result.setResult("{\"index\": \"" + index + ", \"type\": \"" - // + DEFAULT_TYPE + "\"}"); + //result.setResult("{\"index\": \"" + index + ", \"type\": \"" + DEFAULT_TYPE + "\"}"); } } catch (DocumentStoreOperationException e) { @@ -202,10 +206,11 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { return result; } + @Override public OperationResult deleteIndex(String indexName) throws DocumentStoreOperationException { - // Initialize operation result with a failure codes / fault string + //Initialize operation result with a failure codes / fault string OperationResult opResult = new OperationResult(); opResult.setResultCode(500); opResult.setResult(INTERNAL_SERVER_ERROR_ELASTIC_SEARCH_OPERATION_FAULT); @@ -229,15 +234,18 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Generate a metrics log so we can track how long the operation took. metricsLogger.info(SearchDbMsgs.DELETE_INDEX_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResult()), - override, indexName); + override, + indexName); shutdownConnection(conn); return opResult; } + private OperationResult checkConnection() throws Exception { String fullUrl = getFullUrl("/_cluster/health", false); @@ -283,8 +291,7 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { try { inputstream = connection.getInputStream(); } catch (IOException e) { - logger.debug(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "shutdownConnection", - e.getLocalizedMessage()); + logger.debug(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "shutdownConnection", e.getLocalizedMessage()); } finally { if (inputstream != null) { try { @@ -299,8 +306,7 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { try { outputstream = connection.getOutputStream(); } catch (IOException e) { - logger.debug(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "shutdownConnection", - e.getLocalizedMessage()); + logger.debug(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "shutdownConnection", e.getLocalizedMessage()); } finally { if (outputstream != null) { try { @@ -315,9 +321,10 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { connection.disconnect(); } - // @Override - protected OperationResult createTable(String indexName, String typeName, String indexSettings, - String indexMappings) throws DocumentStoreOperationException { + //@Override + protected OperationResult createTable(String indexName, String typeName, + String indexSettings, String indexMappings) + throws DocumentStoreOperationException { if (indexSettings == null) { logger.debug("No settings provided."); @@ -367,24 +374,25 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Generate a metrics log so we can track how long the operation took. metricsLogger.info(SearchDbMsgs.CREATE_INDEX_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResultCode()), - override, indexName); + override, + indexName); return opResult; } /** - * Will send the passed in JSON payload to Elasticsearch using the provided index name in an - * attempt to create the index. - * + * Will send the passed in JSON payload to Elasticsearch using the + * provided index name in an attempt to create the index. + * * @param indexName - The name of the index to be created * @param settingsAndMappings - The actual JSON object that will define the index * @return - The operation result of writing into Elasticsearch * @throws DocumentStoreOperationException */ - protected OperationResult createTable(String indexName, String settingsAndMappings) - throws DocumentStoreOperationException { + protected OperationResult createTable(String indexName, String settingsAndMappings) throws DocumentStoreOperationException { OperationResult result = new OperationResult(); result.setResultCode(500); result.setResult(INTERNAL_SERVER_ERROR_ELASTIC_SEARCH_OPERATION_FAULT); @@ -407,29 +415,27 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Generate a metrics log so we can track how long the operation took. metricsLogger.info(SearchDbMsgs.CREATE_INDEX_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getResultCode()) - .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, result.getResultCode()), - override, indexName); - - shutdownConnection(conn); + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, result.getResultCode()) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, result.getResultCode()), + override, + indexName); return result; } @Override - public DocumentOperationResult createDocument(String indexName, DocumentStoreDataEntity document, - boolean allowImplicitIndexCreation) throws DocumentStoreOperationException { - - if (!allowImplicitIndexCreation) { - - // Before we do anything, make sure that the specified index - // actually exists in the - // document store - we don't want to rely on ElasticSearch to fail - // the document - // create because it could be configured to implicitly create a - // non-existent index, - // which can lead to hard-to-debug behaviour with queries down the - // road. + public DocumentOperationResult createDocument(String indexName, + DocumentStoreDataEntity document, + boolean allowImplicitIndexCreation) + throws DocumentStoreOperationException { + + if(!allowImplicitIndexCreation) { + + // Before we do anything, make sure that the specified index actually exists in the + // document store - we don't want to rely on ElasticSearch to fail the document + // create because it could be configured to implicitly create a non-existent index, + // which can lead to hard-to-debug behaviour with queries down the road. OperationResult indexExistsResult = checkIndexExistence(indexName); if ((indexExistsResult.getResultCode() < 200) || (indexExistsResult.getResultCode() >= 300)) { @@ -449,16 +455,17 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { } private DocumentOperationResult createDocumentWithId(String indexName, - DocumentStoreDataEntity document) throws DocumentStoreOperationException { + DocumentStoreDataEntity document) + throws DocumentStoreOperationException { // check if the document already exists DocumentOperationResult opResult = checkDocumentExistence(indexName, document.getId()); + if (opResult.getResultCode() != Status.NOT_FOUND.getStatusCode()) { if (opResult.getResultCode() == Status.OK.getStatusCode()) { opResult.setFailureCause("A document with the same id already exists."); } else { - opResult.setFailureCause( - "Failed to verify a document with the specified id does not already exist."); + opResult.setFailureCause("Failed to verify a document with the specified id does not already exist."); } opResult.setResultCode(Status.CONFLICT.getStatusCode()); return opResult; @@ -472,8 +479,8 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Grab the current time so we can use it to generate a metrics log. MdcOverride override = getStartTime(new MdcOverride()); - String fullUrl = - getFullUrl("/" + indexName + "/" + DEFAULT_TYPE + "/" + document.getId(), false); + String fullUrl = getFullUrl("/" + indexName + "/" + DEFAULT_TYPE + + "/" + document.getId(), false); HttpURLConnection conn = initializeConnection(fullUrl); try { @@ -492,9 +499,11 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Generate a metrics log so we can track how long the operation took. metricsLogger.info(SearchDbMsgs.CREATE_DOCUMENT_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResult()), - override, indexName); + override, + indexName); shutdownConnection(conn); @@ -503,7 +512,8 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { } private DocumentOperationResult createDocumentWithoutId(String indexName, - DocumentStoreDataEntity document) throws DocumentStoreOperationException { + DocumentStoreDataEntity document) + throws DocumentStoreOperationException { DocumentOperationResult response = new DocumentOperationResult(); // Initialize operation result with a failure codes / fault string @@ -532,9 +542,11 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Generate a metrics log so we can track how long the operation took. metricsLogger.info(SearchDbMsgs.CREATE_DOCUMENT_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, response.getResultCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, response.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, response.getResult()), - override, indexName); + override, + indexName); shutdownConnection(conn); @@ -549,7 +561,8 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { attachContent(conn, doc.getContentInJson()); } - private DocumentOperationResult checkDocumentExistence(String indexName, String docId) + private DocumentOperationResult checkDocumentExistence(String indexName, + String docId) throws DocumentStoreOperationException { DocumentOperationResult opResult = new DocumentOperationResult(); @@ -576,8 +589,7 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { resultCode = conn.getResponseCode(); } catch (IOException e) { shutdownConnection(conn); - throw new DocumentStoreOperationException( - "Failed to get the response code from the connection.", e); + throw new DocumentStoreOperationException("Failed to get the response code from the connection.", e); } logger.debug("Response Code : " + resultCode); @@ -586,9 +598,12 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Generate a metrics log so we can track how long the operation took. metricsLogger.info(SearchDbMsgs.GET_DOCUMENT_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResult()), - override, indexName, docId); + override, + indexName, + docId); shutdownConnection(conn); @@ -596,19 +611,17 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { } @Override - public DocumentOperationResult updateDocument(String indexName, DocumentStoreDataEntity document, - boolean allowImplicitIndexCreation) throws DocumentStoreOperationException { - - if (!allowImplicitIndexCreation) { - - // Before we do anything, make sure that the specified index - // actually exists in the - // document store - we don't want to rely on ElasticSearch to fail - // the document - // create because it could be configured to implicitly create a - // non-existent index, - // which can lead to hard-to-debug behaviour with queries down the - // road. + public DocumentOperationResult updateDocument(String indexName, + DocumentStoreDataEntity document, + boolean allowImplicitIndexCreation) + throws DocumentStoreOperationException { + + if(!allowImplicitIndexCreation) { + + // Before we do anything, make sure that the specified index actually exists in the + // document store - we don't want to rely on ElasticSearch to fail the document + // create because it could be configured to implicitly create a non-existent index, + // which can lead to hard-to-debug behaviour with queries down the road. OperationResult indexExistsResult = checkIndexExistence(indexName); if ((indexExistsResult.getResultCode() < 200) || (indexExistsResult.getResultCode() >= 300)) { @@ -649,9 +662,12 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Generate a metrics log so we can track how long the operation took. metricsLogger.info(SearchDbMsgs.UPDATE_DOCUMENT_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResult()), - override, indexName, document.getId()); + override, + indexName, + document.getId()); shutdownConnection(conn); @@ -685,8 +701,7 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { handleResponse(conn, opResult); buildDocumentResult(opResult, indexName); - // supress the etag and url in response for delete as they are not - // required + //supress the etag and url in response for delete as they are not required if (opResult.getDocument() != null) { opResult.getDocument().setEtag(null); opResult.getDocument().setUrl(null); @@ -694,9 +709,12 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Generate a metrics log so we can track how long the operation took. metricsLogger.info(SearchDbMsgs.DELETE_DOCUMENT_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResult()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResult()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResultCode()), - override, indexName, document.getId()); + override, + indexName, + document.getId()); shutdownConnection(conn); @@ -731,9 +749,12 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Generate a metrics log so we can track how long the operation took. metricsLogger.info(SearchDbMsgs.GET_DOCUMENT_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResult()), - override, indexName, document.getId()); + override, + indexName, + document.getId()); shutdownConnection(conn); @@ -767,10 +788,14 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { handleResponse(conn, opResult); buildSearchResult(opResult, indexName); + metricsLogger.info(SearchDbMsgs.QUERY_DOCUMENT_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResult()), - override, indexName, queryString); + override, + indexName, + queryString); return opResult; } @@ -810,17 +835,21 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { buildSearchResult(opResult, indexName); metricsLogger.info(SearchDbMsgs.QUERY_DOCUMENT_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResult()), - override, indexName, query); + override, + indexName, + query); shutdownConnection(conn); return opResult; } + public SearchOperationResult suggestionQueryWithPayload(String indexName, String query) - throws DocumentStoreOperationException { + throws DocumentStoreOperationException { SearchOperationResult opResult = new SearchOperationResult(); @@ -855,9 +884,9 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { buildSuggestResult(opResult, indexName); metricsLogger.info(SearchDbMsgs.QUERY_DOCUMENT_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) - .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResult()), - override, indexName, query); + new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResult()), + override, indexName, query); shutdownConnection(conn); @@ -917,16 +946,14 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { resultCode = conn.getResponseCode(); } catch (IOException e) { shutdownConnection(conn); - throw new DocumentStoreOperationException( - "Failed to get the response code from the connection.", e); + throw new DocumentStoreOperationException("Failed to get the response code from the connection.", e); } logger.debug("Response Code : " + resultCode); InputStream inputStream = null; - if (!(resultCode >= 200 && resultCode <= 299)) { // 2xx response - // indicates success + if (!(resultCode >= 200 && resultCode <= 299)) { // 2xx response indicates success inputStream = conn.getErrorStream(); } else { try { @@ -985,8 +1012,9 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { } /** - * This convenience method gets the current system time and stores it in an attribute in the - * supplied {@link MdcOverride} object so that it can be used later by the metrics logger. + * This convenience method gets the current system time and stores + * it in an attribute in the supplied {@link MdcOverride} object so + * that it can be used later by the metrics logger. * * @param override - The {@link MdcOverride} object to update. * @return - The supplied {@link MdcOverride} object. @@ -1004,7 +1032,7 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Return the MdcOverride object that we were passed. // This looks odd, but it allows us to do stuff like: // - // MdcOverride ov = getStartTime(new MdcOverride()) + // MdcOverride ov = getStartTime(new MdcOverride()) // // which is quite handy, but also allows us to pass in an existing // MdcOverride object which already has some attributes set. @@ -1016,10 +1044,12 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { return isSuccessCode(result.getResultCode()); } + private boolean isSuccessCode(int statusCode) { return ((statusCode >= 200) && (statusCode < 300)); } + @Override public OperationResult performBulkOperations(BulkRequest[] requests) throws DocumentStoreOperationException { @@ -1074,34 +1104,32 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { logger.debug(Throwables.getStackTraceAsString(e)); } - throw new DocumentStoreOperationException( - "Failed to open connection to document store. Cause: " + e.getMessage(), e); + throw new DocumentStoreOperationException("Failed to open connection to document store. Cause: " + + e.getMessage(), e); } StringBuilder bulkResult = new StringBuilder(128); try { // Create an output stream to write our request to. - OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream());; + OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream()); + ; if (logger.isDebugEnabled()) { logger.debug("ESController: Sending 'BULK' request to " + conn.getURL()); - logger.debug( - "ESController: operations: " + esOperationSet.toString().replaceAll("\n", "\\n")); + logger.debug("ESController: operations: " + esOperationSet.toString().replaceAll("\n", + "\\n")); } - // Write the resulting request string to our output stream. - // (this sends the request to ES?) + // Write the resulting request string to our output stream. (this sends the request to ES?) out.write(esOperationSet.toString()); out.close(); - // Open an input stream on our connection in order to read back - // the results. + // Open an input stream on our connection in order to read back the results. InputStream is = conn.getInputStream(); InputStreamReader inputstreamreader = new InputStreamReader(is); BufferedReader bufferedreader = new BufferedReader(inputstreamreader); - // Read the contents of the input stream into our result - // string... + // Read the contents of the input stream into our result string... String esResponseString = null; while ((esResponseString = bufferedreader.readLine()) != null) { @@ -1117,13 +1145,13 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { logger.debug(sw.toString()); } - throw new DocumentStoreOperationException( - "Failure interacting with document store. Cause: " + e.getMessage(), e); + throw new DocumentStoreOperationException("Failure interacting with document store. Cause: " + + e.getMessage(), e); } if (logger.isDebugEnabled()) { - logger.debug( - "ESController: Received result string from ElasticSearch: = " + bulkResult.toString()); + logger.debug("ESController: Received result string from ElasticSearch: = " + + bulkResult.toString()); } // ...and marshal the resulting string into a Java object. @@ -1137,8 +1165,8 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { logger.debug(Throwables.getStackTraceAsString(e)); } - throw new DocumentStoreOperationException( - "Failed to marshal response body. Cause: " + e.getMessage(), e); + throw new DocumentStoreOperationException("Failed to marshal response body. Cause: " + + e.getMessage(), e); } } @@ -1151,29 +1179,31 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // dumped into the metrics log, so concatenate it. String resultStringForMetricsLog = result.getResult(); if ((result.getResultCode() >= 200) && (result.getResultCode() < 300)) { - resultStringForMetricsLog = - resultStringForMetricsLog.substring(0, Math.max(resultStringForMetricsLog.length(), 85)) - + "..."; + resultStringForMetricsLog = resultStringForMetricsLog.substring(0, + Math.max(resultStringForMetricsLog.length(), 85)) + "..."; } metricsLogger.info(SearchDbMsgs.BULK_OPERATIONS_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getResultCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, result.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, resultStringForMetricsLog), override); return result; } + /** - * This method converts a {@link BulkRequest} object into a json structure which can be understood - * by ElasticSearch. + * This method converts a {@link BulkRequest} object into a json structure + * which can be understood by ElasticSearch. * * @param request - The request to be performed. - * @param sb - The string builder to append the json data to + * @param sb - The string builder to append the json data to * @throws DocumentStoreOperationException */ private boolean buildEsOperation(BulkRequest request, StringBuilder sb, - List fails) throws DocumentStoreOperationException { + List fails) + throws DocumentStoreOperationException { boolean retVal = true; OperationResult indexExistsResult = null; @@ -1187,8 +1217,11 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Make sure that we were supplied a document payload. if (request.getOperation().getDocument() == null) { - fails.add(generateRejectionEntry(request.getOperationType(), "Missing document payload", - request.getIndex(), request.getId(), 400, + fails.add(generateRejectionEntry(request.getOperationType(), + "Missing document payload", + request.getIndex(), + request.getId(), + 400, request.getOperation().getMetaData().getUrl())); return false; } @@ -1198,21 +1231,24 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { if (!ApiUtils.validateDocumentUri(request.getOperation().getMetaData().getUrl(), false)) { fails.add(generateRejectionEntry(request.getOperationType(), "Invalid document URL: " + request.getOperation().getMetaData().getUrl(), - request.getIndex(), "", 400, request.getOperation().getMetaData().getUrl())); + request.getIndex(), + "", + 400, + request.getOperation().getMetaData().getUrl())); return false; } // Validate that the specified index actually exists before we // try to perform the create. - if (!indexExists( - ApiUtils.extractIndexFromUri(request.getOperation().getMetaData().getUrl()))) { - - fails - .add(generateRejectionEntry(request.getOperationType(), - "Specified resource does not exist: " - + request.getOperation().getMetaData().getUrl(), - request.getIndex(), request.getId(), 404, - request.getOperation().getMetaData().getUrl())); + if (!indexExists(ApiUtils.extractIndexFromUri(request.getOperation().getMetaData().getUrl()))) { + + fails.add(generateRejectionEntry(request.getOperationType(), + "Specified resource does not exist: " + + request.getOperation().getMetaData().getUrl(), + request.getIndex(), + request.getId(), + 404, + request.getOperation().getMetaData().getUrl())); return false; } @@ -1220,13 +1256,16 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // include it in the bulk operation to Elastic Search if (request.getId() == null) { - sb.append( - String.format(BULK_CREATE_WITHOUT_INDEX_TEMPLATE, request.getIndex(), DEFAULT_TYPE)); + sb.append(String.format(BULK_CREATE_WITHOUT_INDEX_TEMPLATE, + request.getIndex(), + DEFAULT_TYPE)); // Otherwise, we just leave that parameter off and ElasticSearch // will generate one for us. } else { - sb.append(String.format(BULK_CREATE_WITH_INDEX_TEMPLATE, request.getIndex(), DEFAULT_TYPE, + sb.append(String.format(BULK_CREATE_WITH_INDEX_TEMPLATE, + request.getIndex(), + DEFAULT_TYPE, request.getId())); } @@ -1245,8 +1284,11 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Make sure that we were supplied a document payload. if (request.getOperation().getDocument() == null) { - fails.add(generateRejectionEntry(request.getOperationType(), "Missing document payload", - request.getIndex(), request.getId(), 400, + fails.add(generateRejectionEntry(request.getOperationType(), + "Missing document payload", + request.getIndex(), + request.getId(), + 400, request.getOperation().getMetaData().getUrl())); return false; } @@ -1256,7 +1298,10 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { if (!ApiUtils.validateDocumentUri(request.getOperation().getMetaData().getUrl(), true)) { fails.add(generateRejectionEntry(request.getOperationType(), "Invalid document URL: " + request.getOperation().getMetaData().getUrl(), - request.getIndex(), "", 400, request.getOperation().getMetaData().getUrl())); + request.getIndex(), + "", + 400, + request.getOperation().getMetaData().getUrl())); return false; } @@ -1264,12 +1309,13 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // try to perform the update. if (!indexExists(request.getIndex())) { - fails - .add(generateRejectionEntry(request.getOperationType(), - "Specified resource does not exist: " - + request.getOperation().getMetaData().getUrl(), - request.getIndex(), request.getId(), 404, - request.getOperation().getMetaData().getUrl())); + fails.add(generateRejectionEntry(request.getOperationType(), + "Specified resource does not exist: " + + request.getOperation().getMetaData().getUrl(), + request.getIndex(), + request.getId(), + 404, + request.getOperation().getMetaData().getUrl())); return false; } @@ -1277,29 +1323,35 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // exists before we try to perform the update. if (!documentExists(request.getIndex(), request.getId())) { - fails - .add(generateRejectionEntry(request.getOperationType(), - "Specified resource does not exist: " - + request.getOperation().getMetaData().getUrl(), - request.getIndex(), request.getId(), 404, - request.getOperation().getMetaData().getUrl())); + fails.add(generateRejectionEntry(request.getOperationType(), + "Specified resource does not exist: " + + request.getOperation().getMetaData().getUrl(), + request.getIndex(), + request.getId(), + 404, + request.getOperation().getMetaData().getUrl())); return false; } - // It is mandatory that a version be supplied for an update - // operation, + // It is mandatory that a version be supplied for an update operation, // so validate that now. if (request.getOperation().getMetaData().getEtag() == null) { fails.add(generateRejectionEntry(request.getOperationType(), - "Missing mandatory ETag field", request.getIndex(), request.getId(), 400, + "Missing mandatory ETag field", + request.getIndex(), + request.getId(), + 400, request.getOperation().getMetaData().getUrl())); return false; } // Generate the update request... - sb.append(String.format(BULK_IMPORT_INDEX_TEMPLATE, request.getIndex(), DEFAULT_TYPE, - request.getId(), request.getOperation().getMetaData().getEtag())); + sb.append(String.format(BULK_IMPORT_INDEX_TEMPLATE, + request.getIndex(), + DEFAULT_TYPE, + request.getId(), + request.getOperation().getMetaData().getEtag())); // ...and append the document that we want to update. try { @@ -1317,7 +1369,10 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { if (!ApiUtils.validateDocumentUri(request.getOperation().getMetaData().getUrl(), true)) { fails.add(generateRejectionEntry(request.getOperationType(), "Invalid document URL: " + request.getOperation().getMetaData().getUrl(), - request.getIndex(), "", 400, request.getOperation().getMetaData().getUrl())); + request.getIndex(), + "", + 400, + request.getOperation().getMetaData().getUrl())); return false; } @@ -1325,12 +1380,13 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // try to perform the delete. if (!indexExists(request.getIndex())) { - fails - .add(generateRejectionEntry(request.getOperationType(), - "Specified resource does not exist: " - + request.getOperation().getMetaData().getUrl(), - request.getIndex(), request.getId(), 404, - request.getOperation().getMetaData().getUrl())); + fails.add(generateRejectionEntry(request.getOperationType(), + "Specified resource does not exist: " + + request.getOperation().getMetaData().getUrl(), + request.getIndex(), + request.getId(), + 404, + request.getOperation().getMetaData().getUrl())); return false; } @@ -1338,29 +1394,35 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // exists before we try to perform the delete. if (!documentExists(request.getIndex(), request.getId())) { - fails - .add(generateRejectionEntry(request.getOperationType(), - "Specified resource does not exist: " - + request.getOperation().getMetaData().getUrl(), - request.getIndex(), request.getId(), 404, - request.getOperation().getMetaData().getUrl())); + fails.add(generateRejectionEntry(request.getOperationType(), + "Specified resource does not exist: " + + request.getOperation().getMetaData().getUrl(), + request.getIndex(), + request.getId(), + 404, + request.getOperation().getMetaData().getUrl())); return false; } - // It is mandatory that a version be supplied for a delete - // operation, + // It is mandatory that a version be supplied for a delete operation, // so validate that now. if (request.getOperation().getMetaData().getEtag() == null) { fails.add(generateRejectionEntry(request.getOperationType(), - "Missing mandatory ETag field", request.getIndex(), request.getId(), 400, + "Missing mandatory ETag field", + request.getIndex(), + request.getId(), + 400, request.getOperation().getMetaData().getUrl())); return false; } // Generate the delete request. - sb.append(String.format(BULK_DELETE_TEMPLATE, request.getIndex(), DEFAULT_TYPE, - request.getId(), request.getOperation().getMetaData().getEtag())); + sb.append(String.format(BULK_DELETE_TEMPLATE, + request.getIndex(), + DEFAULT_TYPE, + request.getId(), + request.getOperation().getMetaData().getEtag())); break; default: } @@ -1384,16 +1446,21 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { } /** - * This method constructs a status entry for a bulk operation which has been rejected before even - * sending it to the document store. + * This method constructs a status entry for a bulk operation which has + * been rejected before even sending it to the document store. * * @param rejectReason - A message describing why the operation was rejected. - * @param anId - The identifier associated with the document being acted on. - * @param statusCode - An HTTP status code. + * @param anId - The identifier associated with the document being + * acted on. + * @param statusCode - An HTTP status code. * @return - A result set item. */ - private ElasticSearchResultItem generateRejectionEntry(OperationType opType, String rejectReason, - String index, String anId, int statusCode, String originalUrl) { + private ElasticSearchResultItem generateRejectionEntry(OperationType opType, + String rejectReason, + String index, + String anId, + int statusCode, + String originalUrl) { ElasticSearchError err = new ElasticSearchError(); err.setReason(rejectReason); @@ -1423,11 +1490,14 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { return rejectionResult; } + /** - * This method takes the json structure returned from ElasticSearch in response to a bulk - * operations request and marshals it into a Java object. + * This method takes the json structure returned from ElasticSearch in + * response to a bulk operations request and marshals it into a Java + * object. * - * @param jsonResult - The bulk operations response returned from ElasticSearch. + * @param jsonResult - The bulk operations response returned from + * ElasticSearch. * @return - The marshalled response. * @throws JsonParseException * @throws JsonMappingException @@ -1451,15 +1521,16 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { return null; } + /** - * This method takes the marshalled ElasticSearch bulk response and converts it into a generic - * response payload. + * This method takes the marshalled ElasticSearch bulk response and + * converts it into a generic response payload. * * @param esResult - ElasticSearch bulk operations response. * @return - A generic result set. */ private String buildGenericBulkResultSet(ElasticSearchBulkOperationResult esResult, - List rejectedOps) { + List rejectedOps) { int totalOps = 0; int totalSuccess = 0; @@ -1468,8 +1539,8 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { if (logger.isDebugEnabled()) { logger.debug("ESController: Build generic result set. ES Results: " - + ((esResult != null) ? esResult.toString() : "[]") + " Rejected Ops: " - + rejectedOps.toString()); + + ((esResult != null) ? esResult.toString() : "[]") + + " Rejected Ops: " + rejectedOps.toString()); } // Build a combined list of result items from the results returned @@ -1505,19 +1576,24 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { } // Now, build the result string and return it. - String responseBody = "{ \"total_operations\": " + totalOps + ", " + "\"total_success\": " - + totalSuccess + ", " + "\"total_fails\": " + totalFails + ", " + "\"results\": [" - + resultsBuilder.toString() + "]}"; + String responseBody = "{ \"total_operations\": " + totalOps + ", " + + "\"total_success\": " + totalSuccess + ", " + + "\"total_fails\": " + totalFails + ", " + + "\"results\": [" + + resultsBuilder.toString() + + "]}"; return responseBody; } + /** - * This method queryies ElasticSearch to determine if the supplied index is present in the - * document store. + * This method queryies ElasticSearch to determine if the supplied + * index is present in the document store. * * @param indexName - The index to look for. - * @return - An operation result indicating the success or failure of the check. + * @return - An operation result indicating the success or failure of + * the check. * @throws DocumentStoreOperationException */ public OperationResult checkIndexExistence(String indexName) @@ -1548,8 +1624,7 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { resultCode = conn.getResponseCode(); } catch (IOException e) { shutdownConnection(conn); - throw new DocumentStoreOperationException( - "Failed to get the response code from the connection.", e); + throw new DocumentStoreOperationException("Failed to get the response code from the connection.", e); } logger.debug("Response Code : " + resultCode); @@ -1557,15 +1632,18 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Generate a metrics log so we can track how long the operation took. metricsLogger.info(SearchDbMsgs.CHECK_INDEX_TIME, - new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) + new LogFields() + .setField(LogLine.DefinedFields.RESPONSE_CODE, opResult.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, opResult.getResultCode()), - override, indexName); + override, + indexName); shutdownConnection(conn); return opResult; } + private void buildDocumentResult(DocumentOperationResult result, String index) throws DocumentStoreOperationException { @@ -1587,16 +1665,17 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { // Error response object JSONObject error = (JSONObject) root.get("error"); if (error != null) { - result.setError( - new ErrorResult(error.get("type").toString(), error.get("reason").toString())); + result.setError(new ErrorResult(error.get("type").toString(), + error.get("reason").toString())); } } } catch (Exception e) { - throw new DocumentStoreOperationException( - "Failed to parse Elastic Search response." + result.getResult()); + throw new DocumentStoreOperationException("Failed to parse Elastic Search response." + + result.getResult()); } + } private String buildDocumentResponseUrl(String index, String id) { @@ -1627,8 +1706,8 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { doc.setEtag((hit.get("_version") != null) ? hit.get("_version").toString() : ""); } - doc.setUrl(buildDocumentResponseUrl(index, - (hit.get("_id") != null) ? hit.get("_id").toString() : "")); + doc.setUrl(buildDocumentResponseUrl(index, (hit.get("_id") != null) + ? hit.get("_id").toString() : "")); doc.setContent((JSONObject) hit.get("_source")); searchHit.setDocument(doc); searchHitArray.add(searchHit); @@ -1649,75 +1728,75 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { } else { JSONObject error = (JSONObject) root.get("error"); if (error != null) { - result.setError( - new ErrorResult(error.get("type").toString(), error.get("reason").toString())); + result.setError(new ErrorResult(error.get("type").toString(), + error.get("reason").toString())); } } } catch (Exception e) { - throw new DocumentStoreOperationException( - "Failed to parse Elastic Search response." + result.getResult()); + throw new DocumentStoreOperationException("Failed to parse Elastic Search response." + + result.getResult()); } } private void buildSuggestResult(SearchOperationResult result, String index) - throws DocumentStoreOperationException { + throws DocumentStoreOperationException { - JSONParser parser = new JSONParser(); + JSONParser parser = new JSONParser (); JSONObject root; try { - root = (JSONObject) parser.parse(result.getResult()); - if (result.getResultCode() >= 200 && result.getResultCode() <= 299) { - JSONArray hitArray = (JSONArray) root.get("suggest-vnf"); - JSONObject hitdata = (JSONObject) hitArray.get(0); - JSONArray optionsArray = (JSONArray) hitdata.get("options"); - SuggestHits suggestHits = new SuggestHits(); - suggestHits.setTotalHits(String.valueOf(optionsArray.size())); - - ArrayList suggestHitArray = new ArrayList(); - - for (int i = 0; i < optionsArray.size(); i++) { - JSONObject hit = (JSONObject) optionsArray.get(i); - - SuggestHit suggestHit = new SuggestHit(); - suggestHit.setScore((hit.get("score") != null) ? hit.get("score").toString() : ""); - suggestHit.setText((hit.get("text") != null) ? hit.get("text").toString() : ""); - Document doc = new Document(); - if (hit.get("_version") != null) { - doc.setEtag((hit.get("_version") != null) ? hit.get("_version").toString() : ""); + root = (JSONObject) parser.parse ( result.getResult () ); + if (result.getResultCode () >= 200 && result.getResultCode () <= 299) { + JSONArray hitArray = (JSONArray) root.get ( "suggest-vnf" ); + JSONObject hitdata = (JSONObject) hitArray.get ( 0 ); + JSONArray optionsArray = (JSONArray) hitdata.get ( "options" ); + SuggestHits suggestHits = new SuggestHits (); + suggestHits.setTotalHits ( String.valueOf ( optionsArray.size () ) ); + + ArrayList suggestHitArray = new ArrayList (); + + for (int i = 0; i < optionsArray.size (); i++) { + JSONObject hit = (JSONObject) optionsArray.get ( i ); + + SuggestHit suggestHit = new SuggestHit (); + suggestHit.setScore ( (hit.get ( "score" ) != null) ? hit.get ( "score" ).toString () : "" ); + suggestHit.setText ( (hit.get ( "text" ) != null) ? hit.get ( "text" ).toString () : "" ); + Document doc = new Document (); + if (hit.get ( "_version" ) != null) { + doc.setEtag ( (hit.get ( "_version" ) != null) ? hit.get ( "_version" ).toString () : "" ); } - doc.setUrl(buildDocumentResponseUrl(index, - (hit.get("_id") != null) ? hit.get("_id").toString() : "")); + doc.setUrl ( buildDocumentResponseUrl ( index, + (hit.get ( "_id" ) != null) ? hit.get ( "_id" ).toString () : "" ) ); - doc.setContent((JSONObject) hit.get("payload")); - suggestHit.setDocument(doc); - suggestHitArray.add(suggestHit); + doc.setContent ( (JSONObject) hit.get ( "payload" ) ); + suggestHit.setDocument ( doc ); + suggestHitArray.add ( suggestHit ); } - suggestHits.setHits(suggestHitArray.toArray(new SuggestHit[suggestHitArray.size()])); - result.setSuggestResult(suggestHits); + suggestHits.setHits ( suggestHitArray.toArray ( new SuggestHit[suggestHitArray.size ()] ) ); + result.setSuggestResult ( suggestHits ); - JSONObject aggregations = (JSONObject) root.get("aggregations"); + JSONObject aggregations = (JSONObject) root.get ( "aggregations" ); if (aggregations != null) { AggregationResult[] aggResults = - AggregationParsingUtil.parseAggregationResults(aggregations); - AggregationResults aggs = new AggregationResults(); - aggs.setAggregations(aggResults); - result.setAggregationResult(aggs); + AggregationParsingUtil.parseAggregationResults ( aggregations ); + AggregationResults aggs = new AggregationResults (); + aggs.setAggregations ( aggResults ); + result.setAggregationResult ( aggs ); } // success } else { - JSONObject error = (JSONObject) root.get("error"); + JSONObject error = (JSONObject) root.get ( "error" ); if (error != null) { - result.setError( - new ErrorResult(error.get("type").toString(), error.get("reason").toString())); + result.setError ( + new ErrorResult ( error.get ( "type" ).toString (), error.get ( "reason" ).toString () ) ); } } } catch (Exception e) { - throw new DocumentStoreOperationException( - "Failed to parse Elastic Search response." + result.getResult()); + throw new DocumentStoreOperationException ( + "Failed to parse Elastic Search response." + result.getResult () ); } - } -} + + } diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SearchOperationResult.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SearchOperationResult.java index 31482c4..cdb9ee3 100644 --- a/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SearchOperationResult.java +++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SearchOperationResult.java @@ -46,14 +46,12 @@ public class SearchOperationResult extends OperationResult { this.searchResult = hits; } - public void setSuggestResult(SuggestHits hits) { - this.suggestResult = hits; - } + public void setSuggestResult(SuggestHits hits) { this.suggestResult = hits; } @Override public String toString() { - return "SearchOperationResult [searchResult=" + searchResult + ", aggregationResult=" - + aggregationResult + ", suggestResult=" + suggestResult; + return "SearchOperationResult [searchResult=" + searchResult + + ", aggregationResult=" + aggregationResult + ", suggestResult=" + suggestResult; } } diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SuggestHit.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SuggestHit.java index f1c69a9..82a6c93 100644 --- a/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SuggestHit.java +++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SuggestHit.java @@ -18,40 +18,40 @@ * limitations under the License. * ============LICENSE_END========================================================= */ -package org.onap.aai.sa.searchdbabstraction.entity; + package org.onap.aai.sa.searchdbabstraction.entity; public class SuggestHit { - private String score; - private String text; - Document document; + private String score; + private String text; + Document document; - public String getScore() { - return score; - } + public String getScore() { + return score; + } - public void setScore(String score) { - this.score = score; - } + public void setScore(String score) { + this.score = score; + } - public String getText() { - return text; - } + public String getText() { + return text; + } - public void setText(String text) { - this.text = text; - } + public void setText(String text) { + this.text = text; + } - public Document getDocument() { - return document; - } + public Document getDocument() { + return document; + } - public void setDocument(Document document) { - this.document = document; - } + public void setDocument(Document document) { + this.document = document; + } - @Override - public String toString() { - return "SearchHit [text=" + text + ",score=" + score + ", document=" + document + "]"; - } -} + @Override + public String toString() { + return "SearchHit [text=" + text + ",score=" + score + ", document=" + document + "]"; + } +} \ No newline at end of file diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SuggestHits.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SuggestHits.java index 6c65465..ecc4f25 100644 --- a/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SuggestHits.java +++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SuggestHits.java @@ -24,27 +24,27 @@ import java.util.Arrays; public class SuggestHits { - private String totalHits; - private SuggestHit[] hits; + private String totalHits; + private SuggestHit[] hits; - public String getTotalHits() { - return totalHits; - } + public String getTotalHits() { + return totalHits; + } - public void setTotalHits(String totalHits) { - this.totalHits = totalHits; - } + public void setTotalHits(String totalHits) { + this.totalHits = totalHits; + } - public SuggestHit[] getHits() { - return hits; - } + public SuggestHit[] getHits() { + return hits; + } - public void setHits(SuggestHit[] hits) { - this.hits = hits; - } + public void setHits(SuggestHit[] hits) { + this.hits = hits; + } - @Override - public String toString() { - return "SuggestHit [totalHits=" + totalHits + ", hits=" + Arrays.toString(hits) + "]"; - } + @Override + public String toString() { + return "SuggestHit [totalHits=" + totalHits + ", hits=" + Arrays.toString(hits) + "]"; + } } diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/logging/SearchDbMsgs.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/logging/SearchDbMsgs.java index 9ba8fef..def336a 100644 --- a/src/main/java/org/onap/aai/sa/searchdbabstraction/logging/SearchDbMsgs.java +++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/logging/SearchDbMsgs.java @@ -20,8 +20,8 @@ */ package org.onap.aai.sa.searchdbabstraction.logging; -import com.att.eelf.i18n.EELFResourceManager; import org.onap.aai.cl.eelf.LogMessageEnum; +import com.att.eelf.i18n.EELFResourceManager; public enum SearchDbMsgs implements LogMessageEnum { diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/searchapi/SuggestionStatement.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/searchapi/SuggestionStatement.java index 0631281..69cddb0 100644 --- a/src/main/java/org/onap/aai/sa/searchdbabstraction/searchapi/SuggestionStatement.java +++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/searchapi/SuggestionStatement.java @@ -34,61 +34,61 @@ import com.fasterxml.jackson.annotation.JsonProperty; */ public class SuggestionStatement { - @JsonProperty("results-size") - private Integer size; - - @JsonProperty("suggest-field") - private String field; - - @JsonProperty("suggest-text") - private String text; - - public Integer getSize() { - return size; - } - - public void setSize(Integer size) { - this.size = size; - } - - public String getField() { - return field; - } - - public void setField(String field) { - this.field = field; - } - - public String getText() { - return text; - } - - public void setText(String text) { - this.text = text; - } - - /** - * This method returns a string which represents this statement in syntax that is understandable - * by ElasticSearch and is suitable for inclusion in an ElasticSearch query string. - * - * @return - ElasticSearch syntax string. - */ - public String toElasticSearch() { - - StringBuilder sb = new StringBuilder(); - - sb.append("{"); - sb.append("\"suggest-vnf\": {"); - sb.append("\"text\": ").append("\"" + text + "\"").append(", "); - sb.append("\"completion\": {"); - sb.append("\"field\": ").append("\"" + field + "\"").append(", "); - sb.append("\"size\": ").append(size); - sb.append("}"); - sb.append("}"); - sb.append("}"); - - Logger.debug("Generated raw ElasticSearch suggest statement: " + sb.toString()); - return sb.toString(); - } + @JsonProperty("results-size") + private Integer size; + + @JsonProperty("suggest-field") + private String field; + + @JsonProperty("suggest-text") + private String text; + + public Integer getSize() { + return size; + } + + public void setSize(Integer size) { + this.size = size; + } + + public String getField() { + return field; + } + + public void setField(String field) { + this.field = field; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + /** + * This method returns a string which represents this statement in syntax that is understandable + * by ElasticSearch and is suitable for inclusion in an ElasticSearch query string. + * + * @return - ElasticSearch syntax string. + */ + public String toElasticSearch() { + + StringBuilder sb = new StringBuilder(); + + sb.append("{"); + sb.append("\"suggest-vnf\": {"); + sb.append("\"text\": ").append("\"" + text + "\"").append(", "); + sb.append("\"completion\": {"); + sb.append("\"field\": ").append("\"" + field + "\"").append(", "); + sb.append("\"size\": ").append(size); + sb.append("}"); + sb.append("}"); + sb.append("}"); + + Logger.debug("Generated raw ElasticSearch suggest statement: " + sb.toString()); + return sb.toString(); + } } diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/service/SearchService.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/service/SearchService.java index 7b16a35..afbdae8 100644 --- a/src/main/java/org/onap/aai/sa/searchdbabstraction/service/SearchService.java +++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/service/SearchService.java @@ -26,6 +26,7 @@ import org.onap.aai.sa.searchdbabstraction.logging.SearchDbMsgs; import org.onap.aai.sa.searchdbabstraction.util.SearchDbConstants; import org.onap.aai.cl.api.Logger; import org.onap.aai.cl.eelf.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; import java.io.FileInputStream; import java.util.Properties; @@ -36,6 +37,9 @@ public class SearchService { static Logger logger = LoggerFactory.getInstance().getLogger(SearchService.class.getName()); + @Autowired + private ElasticSearchConfig esConfig; + public SearchService() { try { start(); @@ -47,8 +51,6 @@ public class SearchService { protected void start() throws Exception { Properties configProperties = new Properties(); configProperties.load(new FileInputStream(SearchDbConstants.ES_CONFIG_FILE)); - ElasticSearchConfig esConfig = new ElasticSearchConfig(configProperties); - esController = new ElasticSearchHttpController(esConfig); logger.info(SearchDbMsgs.SERVICE_STARTED); } diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/util/AggregationParsingUtil.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/util/AggregationParsingUtil.java index 53e02bf..76cf227 100644 --- a/src/main/java/org/onap/aai/sa/searchdbabstraction/util/AggregationParsingUtil.java +++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/util/AggregationParsingUtil.java @@ -31,7 +31,7 @@ import java.util.Set; public class AggregationParsingUtil { public static AggregationResult[] parseAggregationResults(JSONObject aggregations) - throws JsonProcessingException { + throws JsonProcessingException { // Obtain the set of aggregation names Set keySet = aggregations.keySet(); @@ -65,7 +65,7 @@ public class AggregationParsingUtil { } private static AggregationBucket[] parseAggregationBuckets(JSONArray buckets) - throws JsonProcessingException { + throws JsonProcessingException { AggregationBucket[] aggBuckets = new AggregationBucket[buckets.size()]; for (int i = 0; i < buckets.size(); i++) { AggregationBucket aggBucket = new AggregationBucket(); diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/util/SearchDbConstants.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/util/SearchDbConstants.java index 7b9e0c9..bd7d58b 100644 --- a/src/main/java/org/onap/aai/sa/searchdbabstraction/util/SearchDbConstants.java +++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/util/SearchDbConstants.java @@ -22,30 +22,35 @@ package org.onap.aai.sa.searchdbabstraction.util; public class SearchDbConstants { public static final String SDB_FILESEP = (System.getProperty("file.separator") == null) ? "/" - : System.getProperty("file.separator"); + : System.getProperty("file.separator"); public static final String SDB_BUNDLECONFIG_NAME = - (System.getProperty("BUNDLECONFIG_DIR") == null) - ? "bundleconfig" : System.getProperty("BUNDLECONFIG_DIR"); - + (System.getProperty("BUNDLECONFIG_DIR") == null) + ? "bundleconfig" : System.getProperty("BUNDLECONFIG_DIR"); +// public static final String SDB_HOME_BUNDLECONFIG = (System.getProperty("AJSC_HOME") == null) - ? SDB_FILESEP + "opt" + SDB_FILESEP + "app" + SDB_FILESEP + "searchdb" - + SDB_FILESEP + SDB_BUNDLECONFIG_NAME - : System.getProperty("AJSC_HOME") + SDB_FILESEP + SDB_BUNDLECONFIG_NAME; - + ? SDB_FILESEP + "opt" + SDB_FILESEP + "app" + SDB_FILESEP + "searchdb" + + SDB_FILESEP + SDB_BUNDLECONFIG_NAME + : System.getProperty("AJSC_HOME") + SDB_FILESEP + SDB_BUNDLECONFIG_NAME; +// public static final String SDB_HOME_ETC = - SDB_HOME_BUNDLECONFIG + SDB_FILESEP + "etc" + SDB_FILESEP; + SDB_HOME_BUNDLECONFIG + SDB_FILESEP + "etc" + SDB_FILESEP; public static final String SDB_CONFIG_APP_LOCATION = SDB_HOME_ETC + "appprops" + SDB_FILESEP; // Elastic Search related public static final String SDB_SPECIFIC_CONFIG = (System.getProperty("CONFIG_HOME") == null) - ? SDB_CONFIG_APP_LOCATION : System.getProperty("CONFIG_HOME") + SDB_FILESEP; + ? SDB_CONFIG_APP_LOCATION : System.getProperty("CONFIG_HOME") + SDB_FILESEP; public static final String ES_CONFIG_FILE = SDB_SPECIFIC_CONFIG + SDB_FILESEP - + "elastic-search.properties"; + + "elastic-search.properties"; public static final String SDB_AUTH = SDB_SPECIFIC_CONFIG + "auth" + SDB_FILESEP; public static final String SDB_AUTH_CONFIG_FILENAME = SDB_AUTH + "search_policy.json"; public static final String SDB_FILTER_CONFIG_FILE = SDB_SPECIFIC_CONFIG + "filter-config.json"; public static final String SDB_ANALYSIS_CONFIG_FILE = - SDB_SPECIFIC_CONFIG + "analysis-config.json"; + SDB_SPECIFIC_CONFIG + "analysis-config.json"; + +// public static final String SDB_HOME_SEARCHCONFIG = (System.getProperty("app.config") == null) +// ? System.getProperty("user.dir") + SDB_FILESEP + "config" + SDB_FILESEP + "searchdb" +// + SDB_FILESEP + "elastic-search.properties" +// : System.getProperty("app.config") + SDB_FILESEP + "searchdb" + SDB_FILESEP + "elastic-search.properties"; // Logging related public static final String SDB_SERVICE_NAME = "SearchDataService"; -- cgit 1.2.3-korg