aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrv871f <richard.vondadelszen@amdocs.com>2018-03-16 11:59:32 -0400
committerrv871f <richard.vondadelszen@amdocs.com>2018-03-16 12:02:30 -0400
commit1d1fbefced829fed4f3d6bb4123f9df8c9cb8d3c (patch)
tree1504fc245a6a7518be0f27a51431091fc3582b14
parentd6348739c632fb69c8833078effbb902adc7f702 (diff)
Adding pass through shema creation
Issue-ID: AAI-888 Change-Id: Ifc094758682b39a5f2c5607bccd418de6e36d841 Signed-off-by: rv871f <richard.vondadelszen@amdocs.com>
-rw-r--r--src/main/java/org/onap/aai/sa/rest/IndexApi.java63
-rw-r--r--src/main/java/org/onap/aai/sa/rest/SearchServiceApi.java12
-rw-r--r--src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/DocumentStoreInterface.java2
-rw-r--r--src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpController.java61
-rw-r--r--src/test/java/org/onap/aai/sa/rest/IndexApiTest.java19
-rw-r--r--src/test/java/org/onap/aai/sa/rest/SearchServiceApiHarness.java12
-rw-r--r--src/test/java/org/onap/aai/sa/rest/StubEsController.java8
-rw-r--r--src/test/resources/json/dynamicIndex.json15
8 files changed, 186 insertions, 6 deletions
diff --git a/src/main/java/org/onap/aai/sa/rest/IndexApi.java b/src/main/java/org/onap/aai/sa/rest/IndexApi.java
index af934d1..36570dc 100644
--- a/src/main/java/org/onap/aai/sa/rest/IndexApi.java
+++ b/src/main/java/org/onap/aai/sa/rest/IndexApi.java
@@ -46,6 +46,8 @@ import javax.ws.rs.core.Response;
*/
public class IndexApi {
+ private static final String HEADER_VALIDATION_SUCCESS = "SUCCESS";
+
protected SearchServiceApi searchService = null;
/**
@@ -188,6 +190,39 @@ public class IndexApi {
// Finally, return the response.
return response;
}
+
+ /**
+ * This function accepts any JSON and will "blindly" write it to the
+ * document store.
+ *
+ * Note, eventually this "dynamic" flow should follow the same JSON-Schema
+ * validation procedure as the normal create index flow.
+ *
+ * @param dynamicSchema - The JSON string that will be sent to the document store.
+ * @param index - The name of the index to be created.
+ * @param documentStore - The document store specific interface.
+ * @return The result of the document store interface's operation.
+ */
+ public Response processCreateDynamicIndex(String dynamicSchema, HttpServletRequest request,
+ HttpHeaders headers, String index, DocumentStoreInterface documentStore) {
+
+ Response response = null;
+
+ Response validationResponse = validateRequest(request, headers, index, SearchDbMsgs.INDEX_CREATE_FAILURE);
+
+ if (validationResponse.getStatus() != Response.Status.OK.getStatusCode()) {
+ response = validationResponse;
+ } else {
+ OperationResult result = documentStore.createDynamicIndex(index, dynamicSchema);
+
+ int resultCode = (result.getResultCode() == 200) ? 201 : result.getResultCode();
+ String resultString = (result.getFailureCause() == null) ? result.getResult() : result.getFailureCause();
+
+ response = Response.status(resultCode).entity(resultString).build();
+ }
+
+ return response;
+ }
/**
@@ -227,7 +262,6 @@ public class IndexApi {
return errorResponse(Response.Status.FORBIDDEN, "Authentication failure.", request);
}
-
try {
// Send the request to the document store.
response = responseFromOperationResult(documentStore.deleteIndex(index));
@@ -237,8 +271,7 @@ public class IndexApi {
.entity(e.getMessage())
.build();
}
-
-
+
// Log the result.
if ((response.getStatus() >= 200) && (response.getStatus() < 300)) {
logger.info(SearchDbMsgs.DELETED_INDEX, index);
@@ -372,6 +405,26 @@ public class IndexApi {
.entity(msg)
.build();
}
-
-
+
+ /**
+ * A helper method used for validating/authenticating an incoming request.
+ *
+ * @param request - The http request that will be validated.
+ * @param headers - The http headers that will be validated.
+ * @param index - The name of the index that the document store request is being made against.
+ * @param failureMsgEnum - The logging message to be used upon validation failure.
+ * @return A success or failure response
+ */
+ private Response validateRequest(HttpServletRequest request, HttpHeaders headers, String index, SearchDbMsgs failureMsgEnum) {
+ try {
+ if (!searchService.validateRequest(headers, request, ApiUtils.Action.POST, ApiUtils.SEARCH_AUTH_POLICY_NAME)) {
+ logger.warn(failureMsgEnum, index, "Authentication failure.");
+ return errorResponse(Response.Status.FORBIDDEN, "Authentication failure.", request);
+ }
+ } catch (Exception e) {
+ logger.warn(failureMsgEnum, index, "Unexpected authentication failure - cause: " + e.getMessage());
+ return errorResponse(Response.Status.FORBIDDEN, "Authentication failure.", request);
+ }
+ return Response.status(Response.Status.OK).entity(HEADER_VALIDATION_SUCCESS).build();
+ }
}
diff --git a/src/main/java/org/onap/aai/sa/rest/SearchServiceApi.java b/src/main/java/org/onap/aai/sa/rest/SearchServiceApi.java
index dc091dd..249f6b1 100644
--- a/src/main/java/org/onap/aai/sa/rest/SearchServiceApi.java
+++ b/src/main/java/org/onap/aai/sa/rest/SearchServiceApi.java
@@ -86,6 +86,18 @@ public class SearchServiceApi {
return indexApi.processCreateIndex(requestBody, request, headers, index, documentStore);
}
+ @PUT
+ @Path("/indexes/dynamic/{index}")
+ @Consumes({MediaType.APPLICATION_JSON})
+ 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);
+ return indexApi.processCreateDynamicIndex(requestBody, request, headers, index, documentStore);
+ }
@DELETE
@Path("/indexes/{index}")
diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/DocumentStoreInterface.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/DocumentStoreInterface.java
index b0ee35c..2f3350c 100644
--- a/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/DocumentStoreInterface.java
+++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/DocumentStoreInterface.java
@@ -33,6 +33,8 @@ public interface DocumentStoreInterface {
public OperationResult createIndex(String index, DocumentSchema documentSchema);
+ public OperationResult createDynamicIndex(String index, String dynamicSchema);
+
public OperationResult deleteIndex(String indexName) throws DocumentStoreOperationException;
public DocumentOperationResult createDocument(String indexName,
diff --git a/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpController.java b/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpController.java
index 3c19610..ef141ec 100644
--- a/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpController.java
+++ b/src/main/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpController.java
@@ -183,6 +183,26 @@ public class ElasticSearchHttpController implements DocumentStoreInterface {
return result;
}
+ @Override
+ public OperationResult createDynamicIndex(String index, String dynamicSchema) {
+ OperationResult result = new OperationResult();
+ result.setResultCode(500);
+
+ try {
+ result = createTable(index, dynamicSchema);
+
+ // ElasticSearch will return us a 200 code on success when we
+ // want to report a 201, so translate the result here.
+ result.setResultCode((result.getResultCode() == 200) ? 201 : result.getResultCode());
+ if (isSuccess(result)) {
+ result.setResult("{\"url\": \"" + ApiUtils.buildIndexUri(index) + "\"}");
+ }
+ } catch (DocumentStoreOperationException e) {
+ result.setFailureCause("Document store operation failure. Cause: " + e.getMessage());
+ }
+
+ return result;
+ }
@Override
public OperationResult deleteIndex(String indexName) throws DocumentStoreOperationException {
@@ -360,6 +380,47 @@ public class ElasticSearchHttpController implements DocumentStoreInterface {
return opResult;
}
+ /**
+ * Will send the passed in JSON payload to Elasticsearch using the
+ * provided index name in an attempt to create the index.
+ *
+ * @param indexName - The name of the index to be created
+ * @param settingsAndMappings - The actual JSON object that will define the index
+ * @return - The operation result of writing into Elasticsearch
+ * @throws DocumentStoreOperationException
+ */
+ protected OperationResult createTable(String indexName, String settingsAndMappings) throws DocumentStoreOperationException {
+ OperationResult result = new OperationResult();
+ result.setResultCode(500);
+ result.setResult(INTERNAL_SERVER_ERROR_ELASTIC_SEARCH_OPERATION_FAULT);
+
+ // Grab the current time so we can use it to generate a metrics log.
+ MdcOverride override = getStartTime(new MdcOverride());
+
+ String fullUrl = getFullUrl("/" + indexName + "/", false);
+ HttpURLConnection conn = initializeConnection(fullUrl);
+
+ try {
+ conn.setRequestMethod("PUT");
+ } catch (ProtocolException e) {
+ shutdownConnection(conn);
+ throw new DocumentStoreOperationException("Failed to set HTTP request method to PUT.", e);
+ }
+
+ attachContent(conn, settingsAndMappings);
+ handleResponse(conn, result);
+
+ // Generate a metrics log so we can track how long the operation took.
+ metricsLogger.info(SearchDbMsgs.CREATE_INDEX_TIME,
+ new LogFields()
+ .setField(LogLine.DefinedFields.RESPONSE_CODE, result.getResultCode())
+ .setField(LogLine.DefinedFields.RESPONSE_DESCRIPTION, result.getResultCode()),
+ override,
+ indexName);
+
+ return result;
+ }
+
@Override
public DocumentOperationResult createDocument(String indexName,
DocumentStoreDataEntity document,
diff --git a/src/test/java/org/onap/aai/sa/rest/IndexApiTest.java b/src/test/java/org/onap/aai/sa/rest/IndexApiTest.java
index 6292cbe..f63ddbd 100644
--- a/src/test/java/org/onap/aai/sa/rest/IndexApiTest.java
+++ b/src/test/java/org/onap/aai/sa/rest/IndexApiTest.java
@@ -45,7 +45,7 @@ public class IndexApiTest extends JerseyTest {
private final String TOP_URI = "/test/indexes/";
private final String SIMPLE_DOC_SCHEMA_JSON = "src/test/resources/json/simpleDocument.json";
-
+ private final String DYNAMIC_INDEX_PAYLOAD = "src/test/resources/json/dynamicIndex.json";
@Override
protected Application configure() {
@@ -166,6 +166,23 @@ public class IndexApiTest extends JerseyTest {
tokenizedResult[2].equals(EXPECTED_MAPPINGS));
}
+ /**
+ * Tests the dynamic shcema creation flow that send the request
+ * JSON to the data store without any JSON validation against a schema
+ *
+ * @throws IOException
+ */
+ @Test
+ public void createDynamicIndexTest() throws IOException {
+ String indexName = "super-ultra-dynamic-mega-index";
+ String dynamicUri = TOP_URI + "dynamic/";
+ File indexFile = new File(DYNAMIC_INDEX_PAYLOAD);
+ String indexPayload = TestUtils.readFileToString(indexFile);
+
+ String result = target(dynamicUri + indexName).request().put(Entity.json(indexPayload), String.class);
+
+ assertEquals(indexPayload, result);
+ }
/**
* This test validates that a 'create index' request with an improperly
diff --git a/src/test/java/org/onap/aai/sa/rest/SearchServiceApiHarness.java b/src/test/java/org/onap/aai/sa/rest/SearchServiceApiHarness.java
index 80c058d..b15ccc8 100644
--- a/src/test/java/org/onap/aai/sa/rest/SearchServiceApiHarness.java
+++ b/src/test/java/org/onap/aai/sa/rest/SearchServiceApiHarness.java
@@ -63,6 +63,18 @@ public class SearchServiceApiHarness extends SearchServiceApi {
return super.processCreateIndex(requestBody, request, headers, index);
}
+ @PUT
+ @Path("/indexes/dynamic/{index}")
+ @Consumes({MediaType.APPLICATION_JSON})
+ @Override
+ public Response processCreateDynamicIndex(String requestBody,
+ @Context HttpServletRequest request,
+ @Context HttpHeaders headers,
+ @PathParam("index") String index) {
+
+ return super.processCreateDynamicIndex(requestBody, request, headers, index);
+ }
+
@DELETE
@Path("/indexes/{index}")
@Consumes({MediaType.APPLICATION_JSON})
diff --git a/src/test/java/org/onap/aai/sa/rest/StubEsController.java b/src/test/java/org/onap/aai/sa/rest/StubEsController.java
index 326d03a..d5d77ab 100644
--- a/src/test/java/org/onap/aai/sa/rest/StubEsController.java
+++ b/src/test/java/org/onap/aai/sa/rest/StubEsController.java
@@ -73,6 +73,14 @@ public class StubEsController implements DocumentStoreInterface {
return opResult;
}
+ @Override
+ 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
+ opResult.setResult(dynamicSchema);
+ return opResult;
+ }
@Override
public OperationResult deleteIndex(String indexName) throws DocumentStoreOperationException {
diff --git a/src/test/resources/json/dynamicIndex.json b/src/test/resources/json/dynamicIndex.json
new file mode 100644
index 0000000..1ac1cce
--- /dev/null
+++ b/src/test/resources/json/dynamicIndex.json
@@ -0,0 +1,15 @@
+{
+ "mappings": {
+ "dynamic_templates": [{
+ "strings": {
+ "match_mapping_type": "string",
+ "match": "*",
+ "mapping": {
+ "type": "string",
+ "index": "not_analyzed"
+ }
+ }
+ }
+ ]
+ }
+} \ No newline at end of file