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;h=019d867a3a60f70bf26801d86703f32a51f89dea;hb=8b971cd42183793e3363e850456282081b2c09ec;hp=383fcb05ce7b4e19660c97a2799add801b5bac90;hpb=22c477621c40c4762cceb67a1d18749bff68fb87;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 383fcb0..019d867 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 @@ -2,8 +2,8 @@ * ============LICENSE_START======================================================= * org.onap.aai * ================================================================================ - * Copyright © 2017 AT&T Intellectual Property. All rights reserved. - * Copyright © 2017 Amdocs + * 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. @@ -17,18 +17,15 @@ * See the License for the specific language governing permissions and * limitations under the License. * ============LICENSE_END========================================================= - * - * ECOMP is a trademark and service mark of AT&T Intellectual Property. */ 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; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; -import edu.emory.mathcs.backport.java.util.Arrays; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; @@ -52,13 +49,15 @@ import org.onap.aai.sa.searchdbabstraction.logging.SearchDbMsgs; import org.onap.aai.sa.searchdbabstraction.util.AggregationParsingUtil; import org.onap.aai.sa.searchdbabstraction.util.DocumentSchemaUtil; import org.onap.aai.sa.searchdbabstraction.util.SearchDbConstants; -import org.openecomp.cl.api.LogFields; -import org.openecomp.cl.api.LogLine; -import org.openecomp.cl.api.Logger; -import org.openecomp.cl.eelf.LoggerFactory; -import org.openecomp.cl.mdc.MdcContext; -import org.openecomp.cl.mdc.MdcOverride; +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.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; @@ -76,6 +75,7 @@ import java.net.ProtocolException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Properties; import java.util.concurrent.atomic.AtomicBoolean; @@ -185,6 +185,27 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { return result; } + @Override + 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()); + if (isSuccess(result)) { + result.setResult("{\"url\": \"" + ApiUtils.buildIndexUri(index) + "\"}"); + } + } catch (DocumentStoreOperationException e) { + result.setFailureCause("Document store operation failure. Cause: " + e.getMessage()); + } + + return result; + } + @Override public OperationResult deleteIndex(String indexName) throws DocumentStoreOperationException { @@ -362,21 +383,62 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { return opResult; } + /** + * 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 { + 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); + + try { + conn.setRequestMethod("PUT"); + } catch (ProtocolException e) { + 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()) + .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, result.getResultCode()), + override, + indexName); + + return result; + } + @Override - public DocumentOperationResult createDocument(String indexName, + 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."); @@ -384,7 +446,7 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { return opResult; } } - + if (document.getId() == null || document.getId().isEmpty()) { return createDocumentWithoutId(indexName, document); } else { @@ -549,20 +611,20 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { } @Override - public DocumentOperationResult updateDocument(String indexName, + 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."); @@ -570,7 +632,7 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { return opResult; } } - + DocumentOperationResult opResult = new DocumentOperationResult(); // Initialize operation result with a failure codes / fault string @@ -785,6 +847,52 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { 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); + + shutdownConnection(conn); + + return opResult; + } + private void attachContent(HttpURLConnection conn, String content) throws DocumentStoreOperationException { OutputStream outputStream = null; @@ -1631,4 +1739,64 @@ public class ElasticSearchHttpController implements DocumentStoreInterface { } -} + 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 () ); + } + } + + + }