*/
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;
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.ElasticSearchPayloadTranslator;
import org.onap.aai.sa.searchdbabstraction.util.SearchDbConstants;
import org.onap.aai.cl.api.LogFields;
import org.onap.aai.cl.api.LogLine;
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;
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;
-import javax.ws.rs.core.Response.Status;
+
+import org.springframework.http.HttpStatus;
+
/**
//result.setResult("{\"index\": \"" + index + ", \"type\": \"" + DEFAULT_TYPE + "\"}");
}
- } catch (DocumentStoreOperationException e) {
+ } catch (DocumentStoreOperationException | IOException e) {
result.setFailureCause("Document store operation failure. Cause: " + e.getMessage());
}
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());
} catch (DocumentStoreOperationException e) {
result.setFailureCause("Document store operation failure. Cause: " + e.getMessage());
}
-
+
return result;
}
+
@Override
public OperationResult deleteIndex(String indexName) throws DocumentStoreOperationException {
try {
conn.setRequestMethod("PUT");
+ conn.setRequestProperty("Content-Type", "application/json");
} catch (ProtocolException e) {
shutdownConnection(conn);
throw new DocumentStoreOperationException("Failed to set HTTP request method to PUT.", e);
sb.append(indexMappings);
sb.append("}}");
- attachContent(conn, sb.toString());
+ try {
+ attachContent(conn, ElasticSearchPayloadTranslator.translateESPayload(sb.toString()));
+ } catch(IOException e) {
+ throw new DocumentStoreOperationException("Error in translating Index payload to make it ES compliant.", e);
+ }
logger.debug("\ncreateTable(), Sending 'PUT' request to URL : " + conn.getURL());
logger.debug("Request content: " + sb.toString());
return opResult;
}
- /**
- * Will send the passed in JSON payload to Elasticsearch using the
+ /**
+ * 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
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");
+ conn.setRequestProperty("Content-Type", "application/json");
} catch (ProtocolException e) {
shutdownConnection(conn);
throw new DocumentStoreOperationException("Failed to set HTTP request method to PUT.", e);
}
-
- attachContent(conn, settingsAndMappings);
+
+ try {
+ attachContent(conn, ElasticSearchPayloadTranslator.translateESPayload(settingsAndMappings));
+ } catch(IOException e) {
+ throw new DocumentStoreOperationException("Error in translating DynamicIndex payload to make it ES compliant.", e);
+ }
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);
-
+ 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.setResultCode(HttpStatus.NOT_FOUND.value());
opResult.setResult("Document Index '" + indexName + "' does not exist.");
opResult.setFailureCause("Document Index '" + indexName + "' does not exist.");
return opResult;
}
}
-
+
if (document.getId() == null || document.getId().isEmpty()) {
return createDocumentWithoutId(indexName, document);
} else {
DocumentOperationResult opResult = checkDocumentExistence(indexName, document.getId());
- if (opResult.getResultCode() != Status.NOT_FOUND.getStatusCode()) {
- if (opResult.getResultCode() == Status.OK.getStatusCode()) {
+ if (opResult.getResultCode() != HttpStatus.NOT_FOUND.value()) {
+ if (opResult.getResultCode() == HttpStatus.CONFLICT.value()) {
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.setResultCode(Status.CONFLICT.getStatusCode());
+ opResult.setResultCode(HttpStatus.CONFLICT.value());
return opResult;
}
private void attachDocument(HttpURLConnection conn, DocumentStoreDataEntity doc)
throws DocumentStoreOperationException {
- conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+// conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+ conn.setRequestProperty("Content-Type", "application/json");
conn.setRequestProperty("Connection", "Close");
-
- attachContent(conn, doc.getContentInJson());
+
+ try {
+ attachContent(conn, ElasticSearchPayloadTranslator.translateESPayload(doc.getContentInJson()));
+ } catch(IOException e) {
+ throw new DocumentStoreOperationException("Error in translating Document payload to make it ES compliant.", e);
+ }
}
private DocumentOperationResult checkDocumentExistence(String indexName,
}
@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.setResultCode(HttpStatus.NOT_FOUND.value());
opResult.setResult("Document Index '" + indexName + "' does not exist.");
opResult.setFailureCause("Document Index '" + indexName + "' does not exist.");
return opResult;
}
}
-
+
DocumentOperationResult opResult = new DocumentOperationResult();
// Initialize operation result with a failure codes / fault string
try {
conn.setRequestMethod("PUT");
+ conn.setRequestProperty("Content-Type", "application/json");
} catch (ProtocolException e) {
shutdownConnection(conn);
throw new DocumentStoreOperationException("Failed to set HTTP request method to PUT.", e);
try {
conn.setRequestMethod("POST");
+ conn.setRequestProperty("Content-Type", "application/json");
} catch (ProtocolException e) {
shutdownConnection(conn);
throw new DocumentStoreOperationException("Failed to set HTTP request method to POST.", e);
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");
+ conn.setRequestProperty("Content-Type", "application/json");
+ } 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;
throw new DocumentStoreOperationException("Failed getting the response body payload.", e);
}
- if (resultCode == Status.CONFLICT.getStatusCode()) {
- opResult.setResultCode(Status.PRECONDITION_FAILED.getStatusCode());
+ if (resultCode == HttpStatus.CONFLICT.value()) {
+ opResult.setResultCode(HttpStatus.PRECONDITION_FAILED.value());
} else {
opResult.setResultCode(resultCode);
}
}
-}
+ 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<SuggestHit> suggestHitArray = new ArrayList<SuggestHit> ();
+
+ 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 () );
+ }
+ }
+
+
+ }