add endpoint to query suggestion via ES 47/36747/6
authorrenealr <reneal.rogers@amdocs.com>
Mon, 19 Mar 2018 14:50:27 +0000 (10:50 -0400)
committerrenealr <reneal.rogers@amdocs.com>
Mon, 19 Mar 2018 18:50:39 +0000 (14:50 -0400)
Added logic to ensure that search data service is able
to handle suggests type request

Issue-ID: AAI-896

Change-Id: I11b3e8dadc5f7023017f01055c24e9c014813eb5
Signed-off-by: renealr <reneal.rogers@amdocs.com>
src/main/java/org/onap/aai/sa/rest/DocumentApi.java
src/main/java/org/onap/aai/sa/rest/SearchServiceApi.java
src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/DocumentStoreInterface.java
src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpController.java
src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SearchOperationResult.java
src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SuggestHit.java [new file with mode: 0644]
src/main/java/org/onap/aai/sa/searchdbabstraction/entity/SuggestHits.java [new file with mode: 0644]
src/main/java/org/onap/aai/sa/searchdbabstraction/searchapi/SuggestionStatement.java [new file with mode: 0644]
src/test/java/org/onap/aai/sa/rest/StubEsController.java
src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpControllerTest.java

index 0ec29a2..63109ef 100644 (file)
@@ -31,6 +31,7 @@ import org.onap.aai.sa.searchdbabstraction.entity.DocumentOperationResult;
 import org.onap.aai.sa.searchdbabstraction.entity.SearchOperationResult;
 import org.onap.aai.sa.searchdbabstraction.logging.SearchDbMsgs;
 import org.onap.aai.sa.searchdbabstraction.searchapi.SearchStatement;
+import org.onap.aai.sa.searchdbabstraction.searchapi.SuggestionStatement;
 import org.onap.aai.cl.api.LogFields;
 import org.onap.aai.cl.api.LogLine;
 import org.onap.aai.cl.api.Logger;
@@ -47,20 +48,19 @@ public class DocumentApi {
   private static final String REQUEST_HEADER_RESOURCE_VERSION = "If-Match";
   private static final String RESPONSE_HEADER_RESOURCE_VERSION = "ETag";
   private static final String REQUEST_HEADER_ALLOW_IMPLICIT_INDEX_CREATION = "X-CreateIndex";
-  
+
   protected SearchServiceApi searchService = null;
 
   private Logger logger = LoggerFactory.getInstance().getLogger(DocumentApi.class.getName());
-  private Logger auditLogger = LoggerFactory.getInstance()
-      .getAuditLogger(DocumentApi.class.getName());
+  private Logger auditLogger =
+      LoggerFactory.getInstance().getAuditLogger(DocumentApi.class.getName());
 
   public DocumentApi(SearchServiceApi searchService) {
     this.searchService = searchService;
   }
 
   public Response processPost(String content, HttpServletRequest request, HttpHeaders headers,
-                              HttpServletResponse httpResponse, String index,
-                              DocumentStoreInterface documentStore) {
+      HttpServletResponse httpResponse, String index, DocumentStoreInterface documentStore) {
 
     // Initialize the MDC Context for logging purposes.
     ApiUtils.initMdcContext(request, headers);
@@ -77,8 +77,7 @@ public class DocumentApi {
         isValid = searchService.validateRequest(headers, request, ApiUtils.Action.POST,
             ApiUtils.SEARCH_AUTH_POLICY_NAME);
       } catch (Exception e) {
-        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL,
-            "DocumentApi.processPost",
+        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "DocumentApi.processPost",
             e.getMessage());
         return handleError(request, content, Status.FORBIDDEN);
       }
@@ -90,7 +89,8 @@ public class DocumentApi {
       DocumentStoreDataEntityImpl document = new DocumentStoreDataEntityImpl();
       document.setContent(content);
 
-      DocumentOperationResult result = documentStore.createDocument(index, document, implicitlyCreateIndex(headers));
+      DocumentOperationResult result =
+          documentStore.createDocument(index, document, implicitlyCreateIndex(headers));
       String output = null;
       if (result.getResultCode() >= 200 && result.getResultCode() <= 299) {
         output = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getDocument());
@@ -117,8 +117,8 @@ public class DocumentApi {
   }
 
   public Response processPut(String content, HttpServletRequest request, HttpHeaders headers,
-                             HttpServletResponse httpResponse, String index,
-                             String id, DocumentStoreInterface documentStore) {
+      HttpServletResponse httpResponse, String index, String id,
+      DocumentStoreInterface documentStore) {
 
     // Initialize the MDC Context for logging purposes.
     ApiUtils.initMdcContext(request, headers);
@@ -135,8 +135,7 @@ public class DocumentApi {
         isValid = searchService.validateRequest(headers, request, ApiUtils.Action.PUT,
             ApiUtils.SEARCH_AUTH_POLICY_NAME);
       } catch (Exception e) {
-        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL,
-            "DocumentApi.processPut",
+        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "DocumentApi.processPut",
             e.getMessage());
         return handleError(request, content, Status.FORBIDDEN);
       }
@@ -145,8 +144,8 @@ public class DocumentApi {
         return handleError(request, content, Status.FORBIDDEN);
       }
 
-      String resourceVersion = headers.getRequestHeaders()
-          .getFirst(REQUEST_HEADER_RESOURCE_VERSION);
+      String resourceVersion =
+          headers.getRequestHeaders().getFirst(REQUEST_HEADER_RESOURCE_VERSION);
 
       DocumentStoreDataEntityImpl document = new DocumentStoreDataEntityImpl();
       document.setId(id);
@@ -185,8 +184,8 @@ public class DocumentApi {
   }
 
   public Response processDelete(String content, HttpServletRequest request, HttpHeaders headers,
-                                HttpServletResponse httpResponse, String index, String id,
-                                DocumentStoreInterface documentStore) {
+      HttpServletResponse httpResponse, String index, String id,
+      DocumentStoreInterface documentStore) {
 
     // Initialize the MDC Context for logging purposes.
     ApiUtils.initMdcContext(request, headers);
@@ -199,8 +198,7 @@ public class DocumentApi {
         isValid = searchService.validateRequest(headers, request, ApiUtils.Action.DELETE,
             ApiUtils.SEARCH_AUTH_POLICY_NAME);
       } catch (Exception e) {
-        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL,
-            "DocumentApi.processDelete",
+        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "DocumentApi.processDelete",
             e.getMessage());
         return handleError(request, content, Status.FORBIDDEN);
       }
@@ -209,8 +207,8 @@ public class DocumentApi {
         return handleError(request, content, Status.FORBIDDEN);
       }
 
-      String resourceVersion = headers.getRequestHeaders()
-          .getFirst(REQUEST_HEADER_RESOURCE_VERSION);
+      String resourceVersion =
+          headers.getRequestHeaders().getFirst(REQUEST_HEADER_RESOURCE_VERSION);
       if (resourceVersion == null || resourceVersion.isEmpty()) {
         return handleError(request, "Request header 'If-Match' missing",
             javax.ws.rs.core.Response.Status.BAD_REQUEST);
@@ -251,8 +249,8 @@ public class DocumentApi {
   }
 
   public Response processGet(String content, HttpServletRequest request, HttpHeaders headers,
-                             HttpServletResponse httpResponse, String index, String id,
-                             DocumentStoreInterface documentStore) {
+      HttpServletResponse httpResponse, String index, String id,
+      DocumentStoreInterface documentStore) {
 
     // Initialize the MDC Context for logging purposes.
     ApiUtils.initMdcContext(request, headers);
@@ -265,8 +263,7 @@ public class DocumentApi {
         isValid = searchService.validateRequest(headers, request, ApiUtils.Action.GET,
             ApiUtils.SEARCH_AUTH_POLICY_NAME);
       } catch (Exception e) {
-        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL,
-            "DocumentApi.processGet",
+        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "DocumentApi.processGet",
             e.getMessage());
         return handleError(request, content, Status.FORBIDDEN);
       }
@@ -275,8 +272,8 @@ public class DocumentApi {
         return handleError(request, content, Status.FORBIDDEN);
       }
 
-      String resourceVersion = headers.getRequestHeaders()
-          .getFirst(REQUEST_HEADER_RESOURCE_VERSION);
+      String resourceVersion =
+          headers.getRequestHeaders().getFirst(REQUEST_HEADER_RESOURCE_VERSION);
 
       DocumentStoreDataEntityImpl document = new DocumentStoreDataEntityImpl();
       document.setId(id);
@@ -308,8 +305,7 @@ public class DocumentApi {
   }
 
   public Response processSearchWithGet(String content, HttpServletRequest request,
-                                       HttpHeaders headers, String index,
-                                       String queryText, DocumentStoreInterface documentStore) {
+      HttpHeaders headers, String index, String queryText, DocumentStoreInterface documentStore) {
 
     // Initialize the MDC Context for logging purposes.
     ApiUtils.initMdcContext(request, headers);
@@ -323,8 +319,7 @@ public class DocumentApi {
         isValid = searchService.validateRequest(headers, request, ApiUtils.Action.GET,
             ApiUtils.SEARCH_AUTH_POLICY_NAME);
       } catch (Exception e) {
-        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL,
-            "processSearchWithGet",
+        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "processSearchWithGet",
             e.getMessage());
         return handleError(request, content, Status.FORBIDDEN);
       }
@@ -336,8 +331,8 @@ public class DocumentApi {
       SearchOperationResult result = documentStore.search(index, queryText);
       String output = null;
       if (result.getResultCode() >= 200 && result.getResultCode() <= 299) {
-        output = mapper.writerWithDefaultPrettyPrinter()
-            .writeValueAsString(result.getSearchResult());
+        output =
+            mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getSearchResult());
       } else {
         output = result.getError() != null
             ? mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getError())
@@ -356,14 +351,13 @@ public class DocumentApi {
   }
 
   public Response queryWithGetWithPayload(String content, HttpServletRequest request,
-                                          HttpHeaders headers, String index,
-                                          DocumentStoreInterface documentStore) {
+      HttpHeaders headers, String index, DocumentStoreInterface documentStore) {
 
     // Initialize the MDC Context for logging purposes.
     ApiUtils.initMdcContext(request, headers);
 
-    logger.info(SearchDbMsgs.PROCESS_PAYLOAD_QUERY, "GET", (request != null)
-        ? request.getRequestURL().toString() : "");
+    logger.info(SearchDbMsgs.PROCESS_PAYLOAD_QUERY, "GET",
+        (request != null) ? request.getRequestURL().toString() : "");
     if (logger.isDebugEnabled()) {
       logger.debug("Request Body: " + content);
     }
@@ -371,14 +365,13 @@ public class DocumentApi {
   }
 
   public Response processSearchWithPost(String content, HttpServletRequest request,
-                                        HttpHeaders headers, String index,
-                                        DocumentStoreInterface documentStore) {
+      HttpHeaders headers, String index, DocumentStoreInterface documentStore) {
 
     // Initialize the MDC Context for logging purposes.
     ApiUtils.initMdcContext(request, headers);
 
-    logger.info(SearchDbMsgs.PROCESS_PAYLOAD_QUERY, "POST", (request != null)
-        ? request.getRequestURL().toString() : "");
+    logger.info(SearchDbMsgs.PROCESS_PAYLOAD_QUERY, "POST",
+        (request != null) ? request.getRequestURL().toString() : "");
     if (logger.isDebugEnabled()) {
       logger.debug("Request Body: " + content);
     }
@@ -386,18 +379,33 @@ public class DocumentApi {
     return processQuery(index, content, request, headers, documentStore);
   }
 
+  public Response processSuggestQueryWithPost(String content, HttpServletRequest request,
+      HttpHeaders headers, String index, DocumentStoreInterface documentStore) {
+
+    // Initialize the MDC Context for logging purposes.
+    ApiUtils.initMdcContext(request, headers);
+
+    logger.info(SearchDbMsgs.PROCESS_PAYLOAD_QUERY, "POST",
+        (request != null) ? request.getRequestURL().toString() : "");
+    if (logger.isDebugEnabled()) {
+      logger.debug("Request Body: " + content);
+    }
+
+    return processSuggestQuery(index, content, request, headers, documentStore);
+  }
+
   /**
-   * Common handler for query requests. This is called by both the GET with
-   * payload and POST with payload variants of the query endpoint.
+   * Common handler for query requests. This is called by both the GET with payload and POST with
+   * payload variants of the query endpoint.
    *
-   * @param index   - The index to be queried against.
+   * @param index - The index to be queried against.
    * @param content - The payload containing the query structure.
    * @param request - The HTTP request.
    * @param headers - The HTTP headers.
    * @return - A standard HTTP response.
    */
   private Response processQuery(String index, String content, HttpServletRequest request,
-                                HttpHeaders headers, DocumentStoreInterface documentStore) {
+      HttpHeaders headers, DocumentStoreInterface documentStore) {
 
     try {
       ObjectMapper mapper = new ObjectMapper();
@@ -415,9 +423,7 @@ public class DocumentApi {
             ApiUtils.SEARCH_AUTH_POLICY_NAME);
 
       } catch (Exception e) {
-        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL,
-            "processQuery",
-            e.getMessage());
+        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "processQuery", e.getMessage());
         return handleError(request, content, Status.FORBIDDEN);
       }
 
@@ -438,8 +444,8 @@ public class DocumentApi {
 
       // Now, submit the search statement, translated into
       // ElasticSearch syntax, to the document store DAO.
-      SearchOperationResult result = documentStore.searchWithPayload(index,
-          searchStatement.toElasticSearch());
+      SearchOperationResult result =
+          documentStore.searchWithPayload(index, searchStatement.toElasticSearch());
       String output = null;
       if (result.getResultCode() >= 200 && result.getResultCode() <= 299) {
         output = prepareOutput(mapper, result);
@@ -461,37 +467,124 @@ public class DocumentApi {
     }
   }
 
-  
   /**
-   * Checks the supplied HTTP headers to see if we should allow the underlying document 
-   * store to implicitly create the index referenced in a document PUT or POST if it
-   * does not already exist in the data store.
+   * Common handler for query requests. This is called by both the GET with payload and POST with
+   * payload variants of the query endpoint.
+   *
+   * @param index - The index to be queried against.
+   * @param content - The payload containing the query structure.
+   * @param request - The HTTP request.
+   * @param headers - The HTTP headers.
+   * @return - A standard HTTP response.
+   */
+  private Response processSuggestQuery(String index, String content, HttpServletRequest request,
+      HttpHeaders headers, DocumentStoreInterface documentStore) {
+
+    try {
+      ObjectMapper mapper = new ObjectMapper();
+      mapper.setSerializationInclusion(Include.NON_EMPTY);
+
+      // Make sure that we were supplied a payload before proceeding.
+      if (content == null) {
+        return handleError(request, content, Status.BAD_REQUEST);
+      }
+
+      // Validate that the request has the appropriate authorization.
+      boolean isValid;
+      try {
+        isValid = searchService.validateRequest(headers, request, ApiUtils.Action.POST,
+            ApiUtils.SEARCH_AUTH_POLICY_NAME);
+
+      } catch (Exception e) {
+        logger.info(SearchDbMsgs.EXCEPTION_DURING_METHOD_CALL, "processQuery", e.getMessage());
+        return handleError(request, content, Status.FORBIDDEN);
+      }
+
+      if (!isValid) {
+        return handleError(request, content, Status.FORBIDDEN);
+      }
+
+      SuggestionStatement suggestionStatement;
+
+      try {
+        // Marshall the supplied request payload into a search statement
+        // object.
+        suggestionStatement = mapper.readValue(content, SuggestionStatement.class);
+
+      } catch (Exception e) {
+        return handleError(request, e.getMessage(), Status.BAD_REQUEST);
+      }
+
+      // Now, submit the search statement, translated into
+      // ElasticSearch syntax, to the document store DAO.
+      SearchOperationResult result =
+          documentStore.suggestionQueryWithPayload(index, suggestionStatement.toElasticSearch());
+      String output = null;
+      if (result.getResultCode() >= 200 && result.getResultCode() <= 299) {
+        output = prepareSuggestOutput(mapper, result);
+      } else {
+        output = result.getError() != null
+            ? mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getError())
+            : result.getFailureCause();
+      }
+      Response response = Response.status(result.getResultCode()).entity(output).build();
+
+      // Clear the MDC context so that no other transaction inadvertently
+      // uses our transaction id.
+      ApiUtils.clearMdcContext();
+
+      return response;
+
+    } catch (Exception e) {
+      return handleError(request, e.getMessage(), Status.INTERNAL_SERVER_ERROR);
+    }
+  }
+
+  /**
+   * Checks the supplied HTTP headers to see if we should allow the underlying document store to
+   * implicitly create the index referenced in a document PUT or POST if it does not already exist
+   * in the data store.
    * 
    * @param headers - The HTTP headers to examine.
    * 
-   * @return - true if the headers indicate that missing indices should be implicitly created,
-   *           false otherwise.
+   * @return - true if the headers indicate that missing indices should be implicitly created, false
+   *         otherwise.
    */
   private boolean implicitlyCreateIndex(HttpHeaders headers) {
-    
+
     boolean createIndexIfNotPresent = false;
-    String implicitIndexCreationHeader = 
+    String implicitIndexCreationHeader =
         headers.getRequestHeaders().getFirst(REQUEST_HEADER_ALLOW_IMPLICIT_INDEX_CREATION);
-    
-    if( (implicitIndexCreationHeader != null) && (implicitIndexCreationHeader.equals("true")) ) {
+
+    if ((implicitIndexCreationHeader != null) && (implicitIndexCreationHeader.equals("true"))) {
       createIndexIfNotPresent = true;
     }
-    
+
     return createIndexIfNotPresent;
   }
-  
-  
+
   private String prepareOutput(ObjectMapper mapper, SearchOperationResult result)
       throws JsonProcessingException {
     StringBuffer output = new StringBuffer();
     output.append("{\r\n\"searchResult\":");
-    output.append(mapper.writerWithDefaultPrettyPrinter()
-        .writeValueAsString(result.getSearchResult()));
+    output.append(
+        mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getSearchResult()));
+    AggregationResults aggs = result.getAggregationResult();
+    if (aggs != null) {
+      output.append(",\r\n\"aggregationResult\":");
+      output.append(mapper.setSerializationInclusion(Include.NON_NULL)
+          .writerWithDefaultPrettyPrinter().writeValueAsString(aggs));
+    }
+    output.append("\r\n}");
+    return output.toString();
+  }
+
+  private String prepareSuggestOutput(ObjectMapper mapper, SearchOperationResult result)
+      throws JsonProcessingException {
+    StringBuffer output = new StringBuffer();
+    output.append("{\r\n\"searchResult\":");
+    output.append(
+        mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result.getSuggestResult()));
     AggregationResults aggs = result.getAggregationResult();
     if (aggs != null) {
       output.append(",\r\n\"aggregationResult\":");
@@ -514,8 +607,7 @@ public class DocumentApi {
         (request != null) ? request.getRemoteHost() : "", Integer.toString(status.getStatusCode()));
 
     auditLogger.info(SearchDbMsgs.PROCESS_REST_REQUEST,
-        new LogFields()
-            .setField(LogLine.DefinedFields.RESPONSE_CODE, status.getStatusCode())
+        new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, status.getStatusCode())
             .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, status.getReasonPhrase()),
         (request != null) ? request.getMethod() : "",
         (request != null) ? request.getRequestURL().toString() : "",
index 249f6b1..99b4615 100644 (file)
@@ -41,17 +41,14 @@ import javax.ws.rs.core.HttpHeaders;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 
-
 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;
 
-
   /**
    * Create a new instance of the end point.
    */
@@ -61,7 +58,6 @@ public class SearchServiceApi {
     init();
   }
 
-
   /**
    * Performs all one-time initialization required for the end point.
    */
@@ -76,10 +72,8 @@ public class SearchServiceApi {
   @PUT
   @Path("/indexes/{index}")
   @Consumes({MediaType.APPLICATION_JSON})
-  public Response processCreateIndex(String requestBody,
-                                     @Context HttpServletRequest request,
-                                     @Context HttpHeaders headers,
-                                     @PathParam("index") String index) {
+  public Response processCreateIndex(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);
@@ -89,10 +83,8 @@ public class SearchServiceApi {
   @PUT
   @Path("/indexes/dynamic/{index}")
   @Consumes({MediaType.APPLICATION_JSON})
-  public Response processCreateDynamicIndex(String requestBody,
-                                     @Context HttpServletRequest request,
-                                     @Context HttpHeaders headers,
-                                     @PathParam("index") String index) {
+  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);
@@ -102,104 +94,84 @@ public class SearchServiceApi {
   @DELETE
   @Path("/indexes/{index}")
   @Consumes({MediaType.APPLICATION_JSON})
-  public Response processDeleteIndex(String requestBody,
-                                     @Context HttpServletRequest request,
-                                     @Context HttpHeaders headers,
-                                     @PathParam("index") String index) {
+  public Response processDeleteIndex(String requestBody, @Context HttpServletRequest request,
+      @Context HttpHeaders headers, @PathParam("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) {
+  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.
     DocumentApi documentApi = new DocumentApi(this);
-    return documentApi.processGet(requestBody, request, headers, httpResponse,
-        index, id, documentStore);
+    return documentApi.processGet(requestBody, request, headers, httpResponse, index, id,
+        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) {
+  public Response processCreateDocWithoutId(String requestBody, @Context HttpServletRequest request,
+      @Context HttpServletResponse httpResponse, @Context HttpHeaders headers,
+      @PathParam("index") String index) {
 
     // Forward the request to our document API to create the document.
     DocumentApi documentApi = new DocumentApi(this);
-    return documentApi.processPost(requestBody, request, headers, httpResponse,
-        index, documentStore);
+    return documentApi.processPost(requestBody, request, headers, httpResponse, index,
+        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) {
+  public Response processUpsertDoc(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 upsert the document.
     DocumentApi documentApi = new DocumentApi(this);
-    return documentApi.processPut(requestBody, request, headers, httpResponse,
-        index, id, documentStore);
+    return documentApi.processPut(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) {
+  public Response processDeleteDoc(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 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) {
+  public Response processInlineQuery(String requestBody, @Context HttpServletRequest request,
+      @Context HttpHeaders headers, @PathParam("index") String index,
+      @PathParam("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) {
+  public Response processQueryWithGet(String requestBody, @Context HttpServletRequest request,
+      @Context HttpHeaders headers, @PathParam("index") String index) {
 
     // Forward the request to our document API to delete the document.
     DocumentApi documentApi = new DocumentApi(this);
@@ -209,34 +181,40 @@ public class SearchServiceApi {
   @POST
   @Path("/indexes/{index}/query")
   @Consumes({MediaType.APPLICATION_JSON})
-  public Response processQuery(String requestBody,
-                               @Context HttpServletRequest request,
-                               @Context HttpHeaders headers,
-                               @PathParam("index") String index) {
+  public Response processQuery(String requestBody, @Context HttpServletRequest request,
+      @Context HttpHeaders headers, @PathParam("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) {
+
+    // 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);
+  }
 
   @POST
   @Path("/bulk")
   @Consumes({MediaType.APPLICATION_JSON})
-  public Response processBulkRequest(String requestBody,
-                                     @Context HttpServletRequest request,
-                                     @Context HttpHeaders headers,
-                                     @PathParam("index") String index) {
+  public Response processBulkRequest(String requestBody, @Context HttpServletRequest request,
+      @Context HttpHeaders headers, @PathParam("index") String index) {
 
     // Forward the request to our document API to delete the document.
     BulkApi bulkApi = new BulkApi(this);
     return bulkApi.processPost(requestBody, request, headers, documentStore, apiUtils);
   }
 
-  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();
 
index 2f3350c..a3a8e8e 100644 (file)
@@ -20,7 +20,6 @@
  */
 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;
@@ -28,7 +27,6 @@ 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);
@@ -37,13 +35,11 @@ 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 DocumentOperationResult deleteDocument(String indexName, DocumentStoreDataEntity document)
       throws DocumentStoreOperationException;
@@ -57,14 +53,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
    */
index ef141ec..00f66e0 100644 (file)
@@ -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<ElasticSearchResultItem> fails)
-      throws DocumentStoreOperationException {
+      List<ElasticSearchResultItem> 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<ElasticSearchResultItem> rejectedOps) {
+      List<ElasticSearchResultItem> 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<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());
+      throw new DocumentStoreOperationException(
+          "Failed to parse Elastic Search response." + result.getResult());
     }
 
   }
index b48f94d..31482c4 100644 (file)
@@ -24,11 +24,16 @@ public class SearchOperationResult extends OperationResult {
 
   private SearchHits searchResult;
   private AggregationResults aggregationResult;
+  private SuggestHits suggestResult;
 
   public SearchHits getSearchResult() {
     return searchResult;
   }
 
+  public SuggestHits getSuggestResult() {
+    return suggestResult;
+  }
+
   public AggregationResults getAggregationResult() {
     return aggregationResult;
   }
@@ -41,10 +46,14 @@ public class SearchOperationResult extends OperationResult {
     this.searchResult = hits;
   }
 
+  public void setSuggestResult(SuggestHits hits) {
+    this.suggestResult = hits;
+  }
+
   @Override
   public String toString() {
-    return "SearchOperationResult [searchResult=" + searchResult
-        + ", aggregationResult=" + aggregationResult;
+    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
new file mode 100644 (file)
index 0000000..f1c69a9
--- /dev/null
@@ -0,0 +1,57 @@
+/**
+ * ============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.searchdbabstraction.entity;
+
+public class SuggestHit {
+
+  private String score;
+  private String text;
+  Document document;
+
+  public String getScore() {
+    return score;
+  }
+
+  public void setScore(String score) {
+    this.score = score;
+  }
+
+  public String getText() {
+    return text;
+  }
+
+  public void setText(String text) {
+    this.text = text;
+  }
+
+  public Document getDocument() {
+    return document;
+  }
+
+  public void setDocument(Document document) {
+    this.document = document;
+  }
+
+  @Override
+  public String toString() {
+    return "SearchHit [text=" + text + ",score=" + score + ", document=" + document + "]";
+  }
+}
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
new file mode 100644 (file)
index 0000000..6c65465
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * ============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.searchdbabstraction.entity;
+
+import java.util.Arrays;
+
+public class SuggestHits {
+
+  private String totalHits;
+  private SuggestHit[] hits;
+
+  public String getTotalHits() {
+    return totalHits;
+  }
+
+  public void setTotalHits(String totalHits) {
+    this.totalHits = totalHits;
+  }
+
+  public SuggestHit[] getHits() {
+    return hits;
+  }
+
+  public void setHits(SuggestHit[] hits) {
+    this.hits = hits;
+  }
+
+  @Override
+  public String toString() {
+    return "SuggestHit [totalHits=" + totalHits + ", hits=" + Arrays.toString(hits) + "]";
+  }
+}
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
new file mode 100644 (file)
index 0000000..0631281
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * ============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.searchdbabstraction.searchapi;
+
+import org.radeox.util.logging.Logger;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+/**
+ * This class represents the structure of a search statement.
+ *
+ * <p>
+ * The expected JSON structure to represent a Completion suggest search statement is as follows:
+ *
+ * { "suggest-vnf" : { "text" : "VNFs", "completion" : { "field" : "entity_suggest", "size": 1 } } }
+ */
+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();
+  }
+
+}
index d5d77ab..c792391 100644 (file)
@@ -35,9 +35,8 @@ import java.util.HashMap;
 import java.util.Map;
 
 /**
- * This class implements a stubbed version of the document store DAO so
- * that we can run unit tests without trying to connect to a real
- * document store.
+ * This class implements a stubbed version of the document store DAO so that we can run unit tests
+ * without trying to connect to a real document store.
  */
 public class StubEsController implements DocumentStoreInterface {
 
@@ -48,7 +47,7 @@ public class StubEsController implements DocumentStoreInterface {
   /**
    *
    */
-  //private IndexAPIHarness indexAPIHarness;
+  // private IndexAPIHarness indexAPIHarness;
 
   StubEsController() {
     analysisConfig = new AnalysisConfiguration();
@@ -56,10 +55,8 @@ public class StubEsController implements DocumentStoreInterface {
         "src/test/resources/json/analysis-config.json");
   }
 
-
   @Override
-  public OperationResult createIndex(String         index, 
-                                     DocumentSchema documentSchema) {
+  public OperationResult createIndex(String index, DocumentSchema documentSchema) {
 
     // Just return an OK result, with the parameters that we were passed
     // bundled in the response string. This allows unit tests to validate
@@ -77,7 +74,8 @@ public class StubEsController implements DocumentStoreInterface {
   public OperationResult createDynamicIndex(String index, String dynamicSchema) {
     OperationResult opResult = new OperationResult();
     opResult.setResultCode(200);
-    // Directly return the json as this flow should not edit the json in any way
+    // Directly return the json as this flow should not edit the json in any
+    // way
     opResult.setResult(dynamicSchema);
     return opResult;
   }
@@ -98,11 +96,9 @@ public class StubEsController implements DocumentStoreInterface {
   }
 
   @Override
-  public DocumentOperationResult createDocument(String                  indexName,
-                                                DocumentStoreDataEntity document,
-                                                boolean                 allowImplicitIndexCreation) 
-    throws DocumentStoreOperationException {
-    
+  public DocumentOperationResult createDocument(String indexName, DocumentStoreDataEntity document,
+      boolean allowImplicitIndexCreation) throws DocumentStoreOperationException {
+
     DocumentOperationResult opResult = buildSampleDocumentOperationResult();
 
     if (indexName.equals(DOES_NOT_EXIST_INDEX)) {
@@ -120,11 +116,9 @@ public class StubEsController implements DocumentStoreInterface {
   }
 
   @Override
-  public DocumentOperationResult updateDocument(String                  indexName,
-                                                DocumentStoreDataEntity document,
-                                                boolean                 allowImplicitIndexCreation) 
-    throws DocumentStoreOperationException {
-    
+  public DocumentOperationResult updateDocument(String indexName, DocumentStoreDataEntity document,
+      boolean allowImplicitIndexCreation) throws DocumentStoreOperationException {
+
     DocumentOperationResult opResult = buildSampleDocumentOperationResult();
 
     if (indexName.equals(DOES_NOT_EXIST_INDEX)) {
@@ -142,11 +136,10 @@ public class StubEsController implements DocumentStoreInterface {
   }
 
   @Override
-  public DocumentOperationResult deleteDocument(String indexName,
-                                                DocumentStoreDataEntity document) throws DocumentStoreOperationException {
+  public DocumentOperationResult deleteDocument(String indexName, DocumentStoreDataEntity document)
+      throws DocumentStoreOperationException {
     DocumentOperationResult opResult = buildSampleDocumentOperationResult();
 
-
     if (indexName.equals(DOES_NOT_EXIST_INDEX)) {
       opResult.setResultCode(404);
     } else {
@@ -162,8 +155,8 @@ public class StubEsController implements DocumentStoreInterface {
   }
 
   @Override
-  public DocumentOperationResult getDocument(String indexName,
-                                             DocumentStoreDataEntity document) throws DocumentStoreOperationException {
+  public DocumentOperationResult getDocument(String indexName, DocumentStoreDataEntity document)
+      throws DocumentStoreOperationException {
     DocumentOperationResult opResult = buildSampleDocumentOperationResult();
 
     if (indexName.equals(DOES_NOT_EXIST_INDEX)) {
@@ -176,8 +169,8 @@ public class StubEsController implements DocumentStoreInterface {
   }
 
   @Override
-  public SearchOperationResult search(String indexName,
-                                      String queryText) throws DocumentStoreOperationException {
+  public SearchOperationResult search(String indexName, String queryText)
+      throws DocumentStoreOperationException {
 
     SearchOperationResult opResult = buildSampleSearchOperationResult();
 
@@ -192,8 +185,8 @@ public class StubEsController implements DocumentStoreInterface {
   }
 
   @Override
-  public SearchOperationResult searchWithPayload(String indexName,
-                                                 String query) throws DocumentStoreOperationException {
+  public SearchOperationResult searchWithPayload(String indexName, String query)
+      throws DocumentStoreOperationException {
     SearchOperationResult opResult = buildSampleSearchOperationResult();
 
     if (indexName.equals(DOES_NOT_EXIST_INDEX)) {
@@ -207,7 +200,23 @@ public class StubEsController implements DocumentStoreInterface {
   }
 
   @Override
-  public OperationResult performBulkOperations(BulkRequest[] requests) throws DocumentStoreOperationException {
+  public SearchOperationResult suggestionQueryWithPayload(String indexName, String query)
+      throws DocumentStoreOperationException {
+    SearchOperationResult opResult = new SearchOperationResult();
+
+    if (indexName.equals(DOES_NOT_EXIST_INDEX)) {
+      opResult.setResultCode(404);
+    } else {
+      opResult.setResultCode(200);
+      opResult.setResult(indexName + "@" + query);
+    }
+
+    return opResult;
+  }
+
+  @Override
+  public OperationResult performBulkOperations(BulkRequest[] requests)
+      throws DocumentStoreOperationException {
 
     OperationResult opResult = new OperationResult();
     opResult.setResultCode(200);
@@ -247,4 +256,4 @@ public class StubEsController implements DocumentStoreInterface {
 
   }
 
-}
\ No newline at end of file
+}
index ddaf7da..10e7d2c 100644 (file)
@@ -22,6 +22,7 @@ package org.onap.aai.sa.searchdbabstraction.elasticsearch.dao;
 
 import org.json.JSONException;
 import org.json.JSONObject;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Ignore;
 import org.junit.Test;
@@ -39,8 +40,10 @@ public class ElasticSearchHttpControllerTest {
   private static ElasticSearchHttpController elasticSearch;
   private static AAIEntityTestObject testDocument;
 
-  private static final String indexMappings = "{\r\n    \"properties\": {\r\n        \"entityType\": {\r\n            \"type\": \"string\"\r\n        },\r\n        \"edgeTagQueryEntityFieldName\": {\r\n            \"type\": \"string\",\r\n            \"index\": \"no\"\r\n        },\r\n        \"edgeTagQueryEntityFieldValue\": {\r\n            \"type\": \"string\",\r\n            \"index\": \"no\"\r\n        },\r\n        \"searchTagIDs\" : {\r\n            \"type\" : \"string\"\r\n          },\r\n        \"searchTags\": {\r\n            \"type\": \"string\",\r\n            \"analyzer\": \"nGram_analyzer\",\r\n            \"search_analyzer\": \"whitespace_analyzer\"\r\n        }\r\n    }\r\n}";
-  private static final String indexSettings = "{\r\n    \"analysis\": {\r\n        \"filter\": {\r\n            \"nGram_filter\": {\r\n                \"type\": \"nGram\",\r\n                \"min_gram\": 1,\r\n                \"max_gram\": 50,\r\n                \"token_chars\": [\r\n                    \"letter\",\r\n                    \"digit\",\r\n                    \"punctuation\",\r\n                    \"symbol\"\r\n                ]\r\n            }\r\n        },\r\n        \"analyzer\": {\r\n            \"nGram_analyzer\": {\r\n                \"type\": \"custom\",\r\n                \"tokenizer\": \"whitespace\",\r\n                \"filter\": [\r\n                    \"lowercase\",\r\n                    \"asciifolding\",\r\n                    \"nGram_filter\"\r\n                ]\r\n            },\r\n            \"whitespace_analyzer\": {\r\n                \"type\": \"custom\",\r\n                \"tokenizer\": \"whitespace\",\r\n                \"filter\": [\r\n                    \"lowercase\",\r\n                    \"asciifolding\"\r\n                ]\r\n            }\r\n        }\r\n    }\r\n}";
+  private static final String indexMappings =
+      "{\r\n    \"properties\": {\r\n        \"entityType\": {\r\n            \"type\": \"string\"\r\n        },\r\n        \"edgeTagQueryEntityFieldName\": {\r\n            \"type\": \"string\",\r\n            \"index\": \"no\"\r\n        },\r\n        \"edgeTagQueryEntityFieldValue\": {\r\n            \"type\": \"string\",\r\n            \"index\": \"no\"\r\n        },\r\n        \"searchTagIDs\" : {\r\n            \"type\" : \"string\"\r\n          },\r\n        \"searchTags\": {\r\n            \"type\": \"string\",\r\n            \"analyzer\": \"nGram_analyzer\",\r\n            \"search_analyzer\": \"whitespace_analyzer\"\r\n        }\r\n    }\r\n}";
+  private static final String indexSettings =
+      "{\r\n    \"analysis\": {\r\n        \"filter\": {\r\n            \"nGram_filter\": {\r\n                \"type\": \"nGram\",\r\n                \"min_gram\": 1,\r\n                \"max_gram\": 50,\r\n                \"token_chars\": [\r\n                    \"letter\",\r\n                    \"digit\",\r\n                    \"punctuation\",\r\n                    \"symbol\"\r\n                ]\r\n            }\r\n        },\r\n        \"analyzer\": {\r\n            \"nGram_analyzer\": {\r\n                \"type\": \"custom\",\r\n                \"tokenizer\": \"whitespace\",\r\n                \"filter\": [\r\n                    \"lowercase\",\r\n                    \"asciifolding\",\r\n                    \"nGram_filter\"\r\n                ]\r\n            },\r\n            \"whitespace_analyzer\": {\r\n                \"type\": \"custom\",\r\n                \"tokenizer\": \"whitespace\",\r\n                \"filter\": [\r\n                    \"lowercase\",\r\n                    \"asciifolding\"\r\n                ]\r\n            }\r\n        }\r\n    }\r\n}";
 
   @Before
   public void setUp() throws Exception {
@@ -62,7 +65,8 @@ public class ElasticSearchHttpControllerTest {
 
   @Test
   public void testCreateTable() throws Exception {
-    OperationResult result = elasticSearch.createTable("test", "aai-entities", indexSettings, indexMappings);
+    OperationResult result =
+        elasticSearch.createTable("test", "aai-entities", indexSettings, indexMappings);
     System.out.println(result);
   }
 
@@ -145,6 +149,13 @@ public class ElasticSearchHttpControllerTest {
     System.out.println(result);
   }
 
+  @Test
+  public void testsuggestionQueryWithPayload() throws Exception {
+
+    Assert.assertNotNull(elasticSearch.suggestionQueryWithPayload("autoSuggest", "suggest-index"));
+
+  }
+
   @Test
   public void testDeleteIndex() throws Exception {
     OperationResult result = elasticSearch.deleteIndex("test");
@@ -216,12 +227,10 @@ public class ElasticSearchHttpControllerTest {
     @Override
     public String getContentInJson() {
       try {
-        return new JSONObject()
-            .put("entityType", entityType)
+        return new JSONObject().put("entityType", entityType)
             .put("edgeTagQueryEntityFieldName", edgeTagQueryEntityFieldName)
             .put("edgeTagQueryEntityFieldValue", edgeTagQueryEntityFieldValue)
-            .put("searchTagIDs", searchTagIDs)
-            .put("searchTags", searchTags).toString();
+            .put("searchTagIDs", searchTagIDs).put("searchTags", searchTags).toString();
       } catch (JSONException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();