+ /**
+ * Processes client requests to create a new index and document type in the document store.
+ *
+ * @param documentSchema - The contents of the request body which is expected to be a JSON structure which
+ * corresponds to the schema defined in document.schema.json
+ * @param index - The name of the index to create.
+ * @return - A Standard REST response
+ */
+ public ResponseEntity<String> processCreateIndex(String documentSchema, HttpServletRequest request,
+ HttpHeaders headers, String index, DocumentStoreInterface documentStore) {
+
+ int resultCode = 500;
+
+ // Initialize the MDC Context for logging purposes.
+ ApiUtils.initMdcContext(request, headers);
+
+ // Validate that the request is correctly authenticated before going any further.
+ try {
+ if (!searchService.validateRequest(headers, request, ApiUtils.Action.POST,
+ ApiUtils.SEARCH_AUTH_POLICY_NAME)) {
+ logger.warn(SearchDbMsgs.INDEX_CREATE_FAILURE, index, MSG_AUTHENTICATION_FAILURE);
+ return errorResponse(HttpStatus.FORBIDDEN, MSG_AUTHENTICATION_FAILURE, request);
+ }
+
+ } catch (Exception e) {
+ logger.warn(SearchDbMsgs.INDEX_CREATE_FAILURE, index,
+ MSG_UNEXPECTED_AUTHENTICATION_FAILURE_CAUSE + e.getMessage());
+ return errorResponse(HttpStatus.FORBIDDEN, MSG_AUTHENTICATION_FAILURE, request);
+ }
+
+
+ // We expect a payload containing the document schema. Make sure
+ // it is present.
+ if (documentSchema == null) {
+ logger.warn(SearchDbMsgs.INDEX_CREATE_FAILURE, index, "Missing document schema payload");
+ return errorResponse(HttpStatus.valueOf(resultCode), "Missing payload", request);
+ }
+
+ String resultString;
+
+ try {
+ // Marshal the supplied json string into a document schema object.
+ ObjectMapper mapper = new ObjectMapper();
+ DocumentSchema schema = mapper.readValue(documentSchema, DocumentSchema.class);
+
+ // Now, ask the DAO to create the index.
+ OperationResult result = documentStore.createIndex(index, schema);
+
+ // Extract the result code and string from the OperationResult
+ // object so that we can use them to generate a standard REST
+ // response.
+ // Note that we want to return a 201 result code on a successful
+ // create, so if we get back a 200 from the document store,
+ // translate that int a 201.
+ resultCode = (result.getResultCode() == 200) ? 201 : result.getResultCode();
+ resultString = (result.getFailureCause() == null) ? result.getResult() : result.getFailureCause();
+
+ } catch (com.fasterxml.jackson.core.JsonParseException
+ | com.fasterxml.jackson.databind.JsonMappingException e) {
+
+ // We were unable to marshal the supplied json string into a valid
+ // document schema, so return an appropriate error response.
+ resultCode = HttpStatus.BAD_REQUEST.value();
+ resultString = "Malformed schema: " + e.getMessage();
+
+ } catch (IOException e) {
+
+ // We'll treat this is a general internal error.
+ resultCode = HttpStatus.INTERNAL_SERVER_ERROR.value();
+ resultString = "IO Failure: " + e.getMessage();
+ }
+
+ ResponseEntity<String> response =
+ ResponseEntity.status(resultCode).contentType(MediaType.APPLICATION_JSON).body(resultString);
+
+ if (ApiUtils.isSuccessStatusCode(response.getStatusCodeValue())) {
+ logger.info(SearchDbMsgs.CREATED_INDEX, index);
+ } else {
+ logger.warn(SearchDbMsgs.INDEX_CREATE_FAILURE, index, resultString);
+ }
+
+ // Generate our audit log.
+ auditLogger.info(SearchDbMsgs.PROCESS_REST_REQUEST,
+ new LogFields().setField(LogLine.DefinedFields.RESPONSE_CODE, resultCode).setField(
+ LogLine.DefinedFields.RESPONSE_DESCRIPTION, HttpStatus.valueOf(resultCode).toString()),
+ (request != null) ? request.getMethod() : UNKNOWN_LOG_FIELD_STR,
+ (request != null) ? request.getRequestURL().toString() : UNKNOWN_LOG_FIELD_STR,
+ (request != null) ? request.getRemoteHost() : UNKNOWN_LOG_FIELD_STR,
+ Integer.toString(response.getStatusCodeValue()));
+
+
+
+ // Clear the MDC context so that no other transaction inadvertently
+ // uses our transaction id.
+ ApiUtils.clearMdcContext();
+
+ // Finally, return the response.
+ return response;
+ }