X-Git-Url: https://gerrit.onap.org/r/gitweb?a=blobdiff_plain;f=src%2Fmain%2Fjava%2Forg%2Fonap%2Faai%2Fsa%2Fsearchdbabstraction%2Felasticsearch%2Fdao%2FElasticSearchHttpController.java;fp=src%2Fmain%2Fjava%2Forg%2Fonap%2Faai%2Fsa%2Fsearchdbabstraction%2Felasticsearch%2Fdao%2FElasticSearchHttpController.java;h=00f66e0aa65cd7773400ae2de32e8c808224f756;hb=06d31abe3065205c87447687ad87c05e602c97d7;hp=ef141ec86b20af21a5f366f5ed5dff50b0ad5dc2;hpb=1d1fbefced829fed4f3d6bb4123f9df8c9cb8d3c;p=aai%2Fsearch-data-service.git 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 ef141ec..00f66e0 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 @@ -46,6 +46,8 @@ 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; @@ -79,10 +81,9 @@ 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 { @@ -97,10 +98,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"; @@ -121,8 +122,7 @@ 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,12 +142,11 @@ 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; } @@ -162,9 +161,7 @@ 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 @@ -172,7 +169,8 @@ 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) { @@ -187,10 +185,10 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { public OperationResult createDynamicIndex(String index, String dynamicSchema) { OperationResult result = new OperationResult(); result.setResultCode(500); - + try { result = createTable(index, dynamicSchema); - + // ElasticSearch will return us a 200 code on success when we // want to report a 201, so translate the result here. result.setResultCode((result.getResultCode() == 200) ? 201 : result.getResultCode()); @@ -200,14 +198,14 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { } catch (DocumentStoreOperationException e) { result.setFailureCause("Document store operation failure. Cause: " + e.getMessage()); } - + 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); @@ -231,18 +229,15 @@ 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); @@ -288,7 +283,8 @@ 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 { @@ -303,7 +299,8 @@ 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 { @@ -318,10 +315,9 @@ 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."); @@ -371,32 +367,31 @@ 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); - + // Grab the current time so we can use it to generate a metrics log. MdcOverride override = getStartTime(new MdcOverride()); - + String fullUrl = getFullUrl("/" + indexName + "/", false); HttpURLConnection conn = initializeConnection(fullUrl); @@ -406,36 +401,38 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { shutdownConnection(conn); throw new DocumentStoreOperationException("Failed to set HTTP request method to PUT.", e); } - + attachContent(conn, settingsAndMappings); handleResponse(conn, result); - + // 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()) + new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, result.getResultCode()) .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, result.getResultCode()), - override, - indexName); - + override, indexName); + + shutdownConnection(conn); + 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)) { - + DocumentOperationResult opResult = new DocumentOperationResult(); opResult.setResultCode(Status.NOT_FOUND.getStatusCode()); opResult.setResult("Document Index '" + indexName + "' does not exist."); @@ -443,7 +440,7 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { return opResult; } } - + if (document.getId() == null || document.getId().isEmpty()) { return createDocumentWithoutId(indexName, document); } else { @@ -452,17 +449,16 @@ 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; @@ -476,8 +472,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 { @@ -496,11 +492,9 @@ 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); @@ -509,8 +503,7 @@ 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 @@ -539,11 +532,9 @@ 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); @@ -558,8 +549,7 @@ 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(); @@ -586,7 +576,8 @@ 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); @@ -595,12 +586,9 @@ 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); @@ -608,20 +596,22 @@ 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)) { - + DocumentOperationResult opResult = new DocumentOperationResult(); opResult.setResultCode(Status.NOT_FOUND.getStatusCode()); opResult.setResult("Document Index '" + indexName + "' does not exist."); @@ -629,7 +619,7 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { return opResult; } } - + DocumentOperationResult opResult = new DocumentOperationResult(); // Initialize operation result with a failure codes / fault string @@ -659,12 +649,9 @@ 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); @@ -698,7 +685,8 @@ 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); @@ -706,12 +694,9 @@ 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); @@ -746,12 +731,9 @@ 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); @@ -785,14 +767,10 @@ 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; } @@ -832,12 +810,54 @@ 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); + + shutdownConnection(conn); + + return opResult; + } + + public SearchOperationResult suggestionQueryWithPayload(String indexName, String query) + throws DocumentStoreOperationException { + + SearchOperationResult opResult = new SearchOperationResult(); + + if (logger.isDebugEnabled()) { + logger.debug("Querying Suggestion index: " + indexName + " with query string: " + query); + } + + // Initialize operation result with a failure codes / fault string + opResult.setResultCode(500); + opResult.setResult(INTERNAL_SERVER_ERROR_ELASTIC_SEARCH_OPERATION_FAULT); + + String fullUrl = getFullUrl("/" + indexName + "/_suggest", false); + + // Grab the current time so we can use it to generate a metrics log. + MdcOverride override = getStartTime(new MdcOverride()); + + HttpURLConnection conn = initializeConnection(fullUrl); + + try { + conn.setRequestMethod("POST"); + } catch (ProtocolException e) { + shutdownConnection(conn); + throw new DocumentStoreOperationException("Failed to set HTTP request method to POST.", e); + } + + attachContent(conn, query); + + logger.debug("\nsearch(), Sending 'POST' request to URL : " + conn.getURL()); + logger.debug("Request body = Elasticsearch query = " + query); + + handleResponse(conn, opResult); + 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); + override, indexName, query); shutdownConnection(conn); @@ -897,14 +917,16 @@ 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 { @@ -963,9 +985,8 @@ 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. @@ -983,7 +1004,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. @@ -995,12 +1016,10 @@ 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 { @@ -1055,32 +1074,34 @@ 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) { @@ -1096,13 +1117,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. @@ -1116,8 +1137,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); } } @@ -1130,31 +1151,29 @@ 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; @@ -1168,11 +1187,8 @@ 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; } @@ -1182,24 +1198,21 @@ 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; } @@ -1207,16 +1220,13 @@ 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())); } @@ -1235,11 +1245,8 @@ 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; } @@ -1249,10 +1256,7 @@ 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; } @@ -1260,13 +1264,12 @@ 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; } @@ -1274,35 +1277,29 @@ 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 { @@ -1320,10 +1317,7 @@ 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; } @@ -1331,13 +1325,12 @@ 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; } @@ -1345,35 +1338,29 @@ 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: } @@ -1397,21 +1384,16 @@ 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); @@ -1441,14 +1423,11 @@ 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 @@ -1472,16 +1451,15 @@ 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; @@ -1490,8 +1468,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 @@ -1527,24 +1505,19 @@ 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) @@ -1575,7 +1548,8 @@ 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); @@ -1583,18 +1557,15 @@ 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 { @@ -1616,17 +1587,16 @@ 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) { @@ -1657,8 +1627,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); @@ -1679,13 +1649,73 @@ 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()); + } + + } + + private void buildSuggestResult(SearchOperationResult result, String index) + throws DocumentStoreOperationException { + + 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() : ""); + } + doc.setUrl(buildDocumentResponseUrl(index, + (hit.get("_id") != null) ? hit.get("_id").toString() : "")); + + doc.setContent((JSONObject) hit.get("payload")); + suggestHit.setDocument(doc); + suggestHitArray.add(suggestHit); + } + suggestHits.setHits(suggestHitArray.toArray(new SuggestHit[suggestHitArray.size()])); + result.setSuggestResult(suggestHits); + + JSONObject aggregations = (JSONObject) root.get("aggregations"); + if (aggregations != null) { + AggregationResult[] aggResults = + AggregationParsingUtil.parseAggregationResults(aggregations); + AggregationResults aggs = new AggregationResults(); + aggs.setAggregations(aggResults); + result.setAggregationResult(aggs); + } + + // success + } else { + JSONObject error = (JSONObject) root.get("error"); + if (error != null) { + 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()); } }