From 57ccc376054d09367dc4bf8855adea1f19a87b3f Mon Sep 17 00:00:00 2001 From: Edwin Lawrance Date: Mon, 4 Mar 2019 11:08:03 +0000 Subject: Update poms to conform to merge job requirements Change-Id: Ic989e9538b67214e43faf221724ed5d36bfc6d03 Issue-ID: AAI-2203 Signed-off-by: Edwin Lawrance --- .../onap/aai/sa/auth/SearchDbServiceAuthTest.java | 86 +++ .../java/org/onap/aai/sa/rest/ApiUtilsTest.java | 37 ++ .../java/org/onap/aai/sa/rest/BulkApiTest.java | 86 +++ .../java/org/onap/aai/sa/rest/BulkRequestTest.java | 149 +++++ .../java/org/onap/aai/sa/rest/DocumentApiTest.java | 206 ++++++ .../org/onap/aai/sa/rest/DocumentSchemaTest.java | 99 +++ .../java/org/onap/aai/sa/rest/DocumentTest.java | 727 +++++++++++++++++++++ .../java/org/onap/aai/sa/rest/IndexApiTest.java | 280 ++++++++ .../onap/aai/sa/rest/SearchServiceApiHarness.java | 164 +++++ .../onap/aai/sa/rest/SettingConfigurationTest.java | 57 ++ .../org/onap/aai/sa/rest/StubEsController.java | 266 ++++++++ .../test/java/org/onap/aai/sa/rest/TestUtils.java | 63 ++ .../config/ElasticSearchConfigTest.java | 53 ++ .../dao/AggregationResponseParsingTest.java | 99 +++ .../dao/ElasticSearchHttpControllerTest.java | 330 ++++++++++ .../dao/ElasticSearchResultItemTest.java | 119 ++++ .../searchapi/AggregationStatementTest.java | 154 +++++ .../searchapi/AggregationTest.java | 51 ++ .../searchapi/DateHistogramAggregationTest.java | 78 +++ .../searchapi/DateRangeAggregationTest.java | 69 ++ .../searchapi/DateRangeTest.java | 75 +++ .../searchdbabstraction/searchapi/FilterTest.java | 43 ++ .../searchapi/GroupByAggregationTest.java | 62 ++ .../searchdbabstraction/searchapi/QueryTest.java | 368 +++++++++++ .../searchapi/RangeQueryTest.java | 155 +++++ .../searchapi/SearchStatementTest.java | 211 ++++++ .../sa/searchdbabstraction/searchapi/SortTest.java | 49 ++ .../searchapi/TermQueryTest.java | 63 ++ .../util/ElasticSearchPayloadTranslatorTest.java | 55 ++ .../src/test/resources/json/analysis-config.json | 21 + .../src/test/resources/json/bulk-ops-invalid.json | 32 + .../src/test/resources/json/bulk-ops-valid.json | 31 + .../resources/json/dynamic-custom-template.json | 12 + .../src/test/resources/json/dynamicIndex.json | 17 + .../resources/json/es-payload-translation.json | 16 + .../src/test/resources/json/filter-config.json | 7 + .../src/test/resources/json/index-mapping.json | 28 + .../src/test/resources/json/nested-document.json | 49 ++ .../json/queries/query-with-subrange.json | 14 + .../json/queries/simple-parsed-query.json | 10 + .../src/test/resources/json/search_policy.json | 63 ++ .../src/test/resources/json/settings-config.json | 9 + .../src/test/resources/json/simpleDocument.json | 17 + .../test/resources/json/tier-support-document.json | 30 + 44 files changed, 4610 insertions(+) create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/auth/SearchDbServiceAuthTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/rest/ApiUtilsTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/rest/BulkApiTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/rest/BulkRequestTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentApiTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentSchemaTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/rest/IndexApiTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/rest/SearchServiceApiHarness.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/rest/SettingConfigurationTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/rest/StubEsController.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/rest/TestUtils.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/config/ElasticSearchConfigTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/AggregationResponseParsingTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpControllerTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchResultItemTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/AggregationStatementTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/AggregationTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateHistogramAggregationTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateRangeAggregationTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateRangeTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/FilterTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/GroupByAggregationTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/QueryTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/RangeQueryTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/SearchStatementTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/SortTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/TermQueryTest.java create mode 100644 search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/util/ElasticSearchPayloadTranslatorTest.java create mode 100644 search-data-service-app/src/test/resources/json/analysis-config.json create mode 100644 search-data-service-app/src/test/resources/json/bulk-ops-invalid.json create mode 100644 search-data-service-app/src/test/resources/json/bulk-ops-valid.json create mode 100644 search-data-service-app/src/test/resources/json/dynamic-custom-template.json create mode 100644 search-data-service-app/src/test/resources/json/dynamicIndex.json create mode 100644 search-data-service-app/src/test/resources/json/es-payload-translation.json create mode 100644 search-data-service-app/src/test/resources/json/filter-config.json create mode 100644 search-data-service-app/src/test/resources/json/index-mapping.json create mode 100644 search-data-service-app/src/test/resources/json/nested-document.json create mode 100644 search-data-service-app/src/test/resources/json/queries/query-with-subrange.json create mode 100644 search-data-service-app/src/test/resources/json/queries/simple-parsed-query.json create mode 100644 search-data-service-app/src/test/resources/json/search_policy.json create mode 100644 search-data-service-app/src/test/resources/json/settings-config.json create mode 100644 search-data-service-app/src/test/resources/json/simpleDocument.json create mode 100644 search-data-service-app/src/test/resources/json/tier-support-document.json (limited to 'search-data-service-app/src/test') diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/auth/SearchDbServiceAuthTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/auth/SearchDbServiceAuthTest.java new file mode 100644 index 0000000..97e928e --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/auth/SearchDbServiceAuthTest.java @@ -0,0 +1,86 @@ +/** + * ============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.auth; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.onap.aai.sa.searchdbabstraction.util.SearchDbConstants; +import org.springframework.http.HttpHeaders; + +// import javax.servlet.http.Cookie; + +public class SearchDbServiceAuthTest { + + @Mock + HttpHeaders headers; + + // @Mock + // Cookie mockedCookie; + + @Before + public void setUp() throws NoSuchFieldException, IllegalAccessException, IOException { + MockitoAnnotations.initMocks(this); + System.setProperty("AJSC_HOME", new File(".").getCanonicalPath().replace('\\', '/')); + setFinalStatic(System.getProperty("AJSC_HOME") + "/src/test/resources/json/search_policy.json"); + } + + @Test + public void testAuthUser() { + SearchDbServiceAuth aaiAuth = new SearchDbServiceAuth(); + String auth = aaiAuth.authUser(headers, "user-1", "function-1"); + Assert.assertEquals(auth, "AAI_9101"); + } + + // @Test + // public void testAuthCookie_NullCookie(){ + // SearchDbServiceAuth aaiAuth = new SearchDbServiceAuth(); + // Cookie cookie = null; + // Assert.assertFalse(aaiAuth.authCookie(cookie, "function-1", new StringBuilder("user-1"))); + // } + + // @Test + // public void testAuthCookie_NotNullCookie(){ + // SearchDbServiceAuth aaiAuth = new SearchDbServiceAuth(); + // Cookie cookie = new Cookie ( "TestCookie", "TestValue"); + // // Cookie cookie = new Cookie ( "TestCookie", "TestValue" ); + // boolean retValue = aaiAuth.authCookie(cookie, "GET:testFunction", new StringBuilder("testuser")); + // Assert.assertTrue(retValue); + // } + + static void setFinalStatic(String fieldValue) + throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { + Field configField = SearchDbConstants.class.getDeclaredField("SDB_AUTH_CONFIG_FILENAME"); + configField.setAccessible(true); + + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(configField, configField.getModifiers() & ~Modifier.FINAL); + + configField.set(null, fieldValue); + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/rest/ApiUtilsTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/ApiUtilsTest.java new file mode 100644 index 0000000..df6ed0e --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/ApiUtilsTest.java @@ -0,0 +1,37 @@ +/** + * ============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.rest; + +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import org.junit.Test; + +public class ApiUtilsTest { + + @Test + public void testHTTPStatusConversion() { + assertThat(ApiUtils.getHttpStatusString(201), is(equalTo("Created"))); + assertThat(ApiUtils.getHttpStatusString(207), is(equalTo("Multi-Status"))); + assertThat(ApiUtils.getHttpStatusString(9999), is(equalTo("Unknown"))); + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/rest/BulkApiTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/BulkApiTest.java new file mode 100644 index 0000000..fcc5b77 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/BulkApiTest.java @@ -0,0 +1,86 @@ +/** + * ============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.rest; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +import java.io.File; +import java.io.IOException; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; + + +/** + * This suite of tests validates the behaviour of the bulk operations REST end point. + */ +@RunWith(SpringRunner.class) +@SpringBootTest(classes = org.onap.aai.sa.Application.class) +@AutoConfigureMockMvc +public class BulkApiTest { + + private final String TOP_URI = "/test/bulk"; + + @Autowired + private MockMvc mockMvc; + + @Test + public void authenticationFailureTest() throws Exception { + + this.mockMvc + .perform(post(TOP_URI).contentType(MediaType.APPLICATION_JSON) + .content(SearchServiceApiHarness.FAIL_AUTHENTICATION_TRIGGER)) + .andExpect(status().isForbidden()); + } + + + /** + * This test validates that properly constructed json payloads are correctly validated and that improperly + * contructed payloads will be rejected with the appropriate response code returned to the client. + * + * @throws IOException + */ + @Test + public void payloadValidationTest() throws Exception { + + // Post a request to the bulk operations endpoint with a valid + // operations list payload. + File validBulkOpsFile = new File("src/test/resources/json/bulk-ops-valid.json"); + String validPayloadStr = TestUtils.readFileToString(validBulkOpsFile); + + // Validate that the payload is accepted as expected. + this.mockMvc.perform(post(TOP_URI).contentType(MediaType.APPLICATION_JSON).content(validPayloadStr)) + .andExpect(status().isOk()); + + // Post a request to the bulk operations endpoint with an invalid + // operations list payload. + File inValidBulkOpsFile = new File("src/test/resources/json/bulk-ops-invalid.json"); + String inValidPayloadStr = TestUtils.readFileToString(inValidBulkOpsFile); + this.mockMvc.perform(post(TOP_URI).contentType(MediaType.APPLICATION_JSON).content(inValidPayloadStr)) + .andExpect(status().isBadRequest()); + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/rest/BulkRequestTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/BulkRequestTest.java new file mode 100644 index 0000000..7d784d1 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/BulkRequestTest.java @@ -0,0 +1,149 @@ +/** + * ============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.rest; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.junit4.SpringRunner; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class BulkRequestTest { + + @Test + public void testBulkRequest_Delete() { + BulkRequest request = new BulkRequest(); + BulkOperation operation = new BulkOperation(); + Document document = new Document(); + BulkMetaData metaData = getMetaData(); + operation.setMetaData(metaData); + operation.setDocument(document); + Assert.assertNotNull(operation.getDocument()); + Assert.assertNotNull(operation.getMetaData()); + Assert.assertNotNull(operation.toString()); + + request.setDelete(operation); + Assert.assertNotNull(request.getDelete()); + Assert.assertEquals(operation, request.getOperation()); + Assert.assertEquals(BulkRequest.OperationType.DELETE, request.getOperationType()); + Assert.assertTrue(request.toString().contains("delete:")); + + + } + + @Test + public void testBulkRequest_Update() { + BulkRequest request = new BulkRequest(); + BulkOperation operation = new BulkOperation(); + Document document = new Document(); + BulkMetaData metaData = getMetaData(); + operation.setMetaData(metaData); + operation.setDocument(document); + Assert.assertNotNull(operation.getDocument()); + Assert.assertNotNull(operation.getMetaData()); + Assert.assertNotNull(operation.toString()); + + request.setUpdate(operation); + Assert.assertNotNull(request.getUpdate()); + Assert.assertEquals(operation, request.getOperation()); + Assert.assertEquals(BulkRequest.OperationType.UPDATE, request.getOperationType()); + Assert.assertTrue(request.toString().contains("update:")); + + } + + @Test + public void testBulkRequest_Create() { + BulkRequest request = new BulkRequest(); + BulkOperation operation = new BulkOperation(); + Document document = new Document(); + BulkMetaData metaData = getMetaData(); + operation.setMetaData(metaData); + operation.setDocument(document); + Assert.assertNotNull(operation.getDocument()); + Assert.assertNotNull(operation.getMetaData()); + Assert.assertNotNull(operation.toString()); + + request.setCreate(operation); + Assert.assertNotNull(request.getCreate()); + Assert.assertEquals(operation, request.getOperation()); + Assert.assertEquals(BulkRequest.OperationType.CREATE, request.getOperationType()); + Assert.assertTrue(request.toString().contains("create:")); + + } + + @Test + public void testBulkRequest_Undefined() { + BulkRequest request = new BulkRequest(); + Assert.assertNull(request.getOperation()); + Assert.assertNull(request.getOperationType()); + Assert.assertEquals("UNDEFINED", request.toString()); + } + + @Test + public void testGetIndex() { + BulkRequest request = new BulkRequest(); + BulkOperation operation = new BulkOperation(); + BulkMetaData metaData = new BulkMetaData(); + metaData.setUrl("/test/indexes/index1"); + operation.setMetaData(metaData); + request.setCreate(operation); + String index = request.getIndex(); + Assert.assertEquals(index, "index1"); + } + + @Test + public void testGetId() { + BulkRequest request = new BulkRequest(); + BulkOperation operation = new BulkOperation(); + BulkMetaData metaData = new BulkMetaData(); + metaData.setUrl("/test/documents/document1"); + operation.setMetaData(metaData); + request.setCreate(operation); + String index = request.getId(); + Assert.assertEquals(index, "document1"); + } + + @Test + public void testApiUtils() { + Assert.assertEquals("services/search-data-service/v1/search/indexes/index1", ApiUtils.buildIndexUri("index1")); + Assert.assertEquals("services/search-data-service/v1/search/indexes/index1/documents/document1", + ApiUtils.buildDocumentUri("index1", "document1")); + Assert.assertTrue(ApiUtils.validateIndexUri("services/search-data-service/v1/search/indexes/index1")); + Assert.assertTrue(ApiUtils.validateDocumentUri( + "services/search-data-service/v1/search/indexes/index1/documents/document1", true)); + Assert.assertTrue(ApiUtils.validateDocumentUri( + "services/search-data-service/v1/search/indexes/index1/documents/document1", false)); + } + + private BulkMetaData getMetaData() { + BulkMetaData metaData = new BulkMetaData(); + metaData.setUrl("http://127.0.0.1"); + metaData.setEtag("etag-1"); + Assert.assertEquals(metaData.getUrl(), "http://127.0.0.1"); + Assert.assertEquals(metaData.getEtag(), "etag-1"); + Assert.assertNotNull(metaData.toString()); + return metaData; + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentApiTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentApiTest.java new file mode 100644 index 0000000..865f981 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentApiTest.java @@ -0,0 +1,206 @@ +/** + * ============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.rest; + +import static org.junit.Assert.assertTrue; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; + +import java.io.IOException; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; + +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class DocumentApiTest { + + private static final String INDEXES_URI = "/test/indexes/"; + private static final String DOCUMENT_URI = "documents/"; + + private static final String SEARCH_URI = "query/"; + private static final String INDEX_NAME = "test-index"; + private static final String DOC_ID = "test-1"; + private static final String SIMPLE_QUERY = + "\"parsed-query\": {\"my-field\": \"something\", \"query-string\": \"string\"}"; + private static final String COMPLEX_QUERY = "{" + "\"filter\": {" + "\"all\": [" + + "{\"match\": {\"field\": \"searchTags\", \"value\": \"a\"}}" + "]" + "}," + "\"queries\": [" + + "{\"may\": {\"parsed-query\": {\"field\": \"searchTags\", \"query-string\": \"b\"}}}" + "]" + "}"; + + private static final String CREATE_JSON_CONTENT = "creation content"; + + @Autowired + private MockMvc mockMvc; + + /** + * This test validates the behaviour of the 'Create Document' POST request endpoint. + * + * @throws IOException + * @throws ParseException + */ + @Test + public void createDocumentTest() throws Exception { + + MvcResult result = this.mockMvc.perform(post(INDEXES_URI + INDEX_NAME + "/" + DOCUMENT_URI) + .contentType(MediaType.APPLICATION_JSON).content(CREATE_JSON_CONTENT)).andReturn(); + + // Our stub document store DAO returns the parameters that it was + // passed as the result string, so now we can validate that our + // endpoint invoked it with the correct parameters. + + JSONParser parser = new JSONParser(); + JSONObject json = (JSONObject) parser.parse(result.getResponse().getContentAsString()); + + assertTrue("Unexpected Result ", !json.get("etag").toString().isEmpty()); + } + + /** + * This test validates the behaviour of the 'Create Document' PUT request endpoint. + * + * @throws IOException + * @throws ParseException + */ + @Test + public void updateDocumentTest() throws Exception { + // WebTarget target = target(INDEXES_URI + INDEX_NAME + "/" + DOCUMENT_URI + DOC_ID); + // Builder request = target.request().header("If-Match", "1"); + // String result = request.put(Entity.json(CREATE_JSON_CONTENT), String.class); + + MvcResult result = this.mockMvc + .perform(put(INDEXES_URI + INDEX_NAME + "/" + DOCUMENT_URI + DOC_ID) + .contentType(MediaType.APPLICATION_JSON).header("If-Match", "1").content(CREATE_JSON_CONTENT)) + .andReturn(); + + // Our stub document store DAO returns the parameters that it was + // passed as the result string, so now we can validate that our + // endpoint invoked it with the correct parameters. + JSONParser parser = new JSONParser(); + JSONObject json = (JSONObject) parser.parse(result.getResponse().getContentAsString()); + + assertTrue("Unexpected Result ", !json.get("etag").toString().isEmpty()); + } + + /** + * This test validates the behaviour of the 'Get Document' GET request endpoint. + * + * @throws IOException + * @throws ParseException + */ + @Test + public void getDocumentTest() throws Exception { + // String result = target(INDEXES_URI + INDEX_NAME + "/" + DOCUMENT_URI + DOC_ID).request().get(String.class); + + // MvcResult result = this.mockMvc.perform ( get ( INDEXES_URI + INDEX_NAME + "/" + DOCUMENT_URI + DOC_ID ) + // ).andReturn (); + MvcResult result = this.mockMvc + .perform(get(INDEXES_URI + INDEX_NAME + "/" + DOCUMENT_URI + DOC_ID) + .contentType(MediaType.APPLICATION_JSON).header("If-Match", "1").content(CREATE_JSON_CONTENT)) + .andReturn(); + + + // Our stub document store DAO returns the parameters that it was + // passed as the result string, so now we can validate that our + // endpoint invoked it with the correct parameters. + JSONParser parser = new JSONParser(); + JSONObject json = (JSONObject) parser.parse(result.getResponse().getContentAsString()); + + assertTrue("Unexpected Result ", !json.get("etag").toString().isEmpty()); + + } + + // + // /** + // * This test validates the behaviour of the 'Delete Document' DELETE request + // * endpoint. + // * + // * @throws IOException + // * @throws ParseException + // */ + @Test + public void deleteDocumentTest() throws Exception { + // WebTarget target = target(INDEXES_URI + INDEX_NAME + "/" + DOCUMENT_URI + DOC_ID); + // Builder request = target.request().header("If-Match", "1"); + // String result = request.delete(String.class); + MvcResult result = this.mockMvc + .perform(delete(INDEXES_URI + INDEX_NAME + "/" + DOCUMENT_URI + DOC_ID) + .contentType(MediaType.APPLICATION_JSON).header("If-Match", "1").content(CREATE_JSON_CONTENT)) + .andReturn(); + + + + // Our stub document store DAO returns the parameters that it was + // passed as the result string, so now we can validate that our + // endpoint invoked it with the correct parameters. + assertTrue("Unexpected Result ", result.getResponse().getContentAsString().isEmpty()); + + } + + + /** + * This test validates the behaviour of the 'Search Documents' GET request endpoint. + * + * @throws Exception + */ + @Ignore + public void searchDocumentTest1() throws Exception { + MvcResult result = this.mockMvc + .perform(get(INDEXES_URI + INDEX_NAME + "/" + SEARCH_URI + SIMPLE_QUERY) + .contentType(MediaType.APPLICATION_JSON).header("If-Match", "1").content(CREATE_JSON_CONTENT)) + .andReturn(); + + JSONParser parser = new JSONParser(); + JSONObject json = (JSONObject) parser.parse(result.getResponse().getContentAsString()); + + assertTrue("Unexpected Result ", json.get("totalHits").toString().equals("1")); + } + + /** + * This test validates the behaviour of the 'Search Documents' GET request endpoint. + * + * @throws IOException + * @throws ParseException + */ + @Test + public void searchDocumentTest2() throws Exception { + MvcResult result = this.mockMvc.perform(get(INDEXES_URI + INDEX_NAME + "/" + SEARCH_URI) + .contentType(MediaType.APPLICATION_JSON).content(COMPLEX_QUERY)).andReturn(); + + JSONParser parser = new JSONParser(); + JSONObject json = (JSONObject) parser.parse(result.getResponse().getContentAsString()); + JSONObject resultJson = (JSONObject) json.get("searchResult"); + + assertTrue("Unexpected Result ", resultJson.get("totalHits").toString().equals("1")); + } + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentSchemaTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentSchemaTest.java new file mode 100644 index 0000000..c2d5021 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentSchemaTest.java @@ -0,0 +1,99 @@ +/** + * ============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.rest; + +import static org.junit.Assert.assertTrue; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.IOException; +import org.junit.Test; + +public class DocumentSchemaTest { + + private final String SIMPLE_DOC_SCHEMA_JSON = "src/test/resources/json/simpleDocument.json"; + private final String NESTED_DOC_SCHEMA_JSON = "src/test/resources/json/nested-document.json"; + + + /** + * This test validates that we convert document definitions back and forth between json strings and POJOs without + * any loss of data. + * + * @throws com.fasterxml.jackson.core.JsonParseException + * @throws com.fasterxml.jackson.databind.JsonMappingException + * @throws IOException + */ + @Test + public void simpleDocSchemaFromJsonFileTest() throws com.fasterxml.jackson.core.JsonParseException, + com.fasterxml.jackson.databind.JsonMappingException, IOException { + + // Import our json format document schema from a file. + File schemaFile = new File(SIMPLE_DOC_SCHEMA_JSON); + String fileString = TestUtils.readFileToString(schemaFile); + + // Unmarshall that to a Java POJO + ObjectMapper mapper = new ObjectMapper(); + DocumentSchema docSchema = mapper.readValue(schemaFile, DocumentSchema.class); + + // Now, for the purposes of comparison, produce a JSON string from + // our Java object. + String jsonString = mapper.writeValueAsString(docSchema); + + // Assert that the raw JSON that we read from the file matches the marshalled + // JSON we generated from our Java object (ie: validate that we didn't lose + // anything going in either direction). + assertTrue("Marshalled object does not match the original json source that produced it", + fileString.equals(jsonString)); + } + + // + // /** + // * This test validates that we convert document definitions back and + // * forth between json strings and POJOs without any loss of data in + // * the case of document schemas which contain nested fields. + // * + // * @throws com.fasterxml.jackson.core.JsonParseException + // * @throws com.fasterxml.jackson.databind.JsonMappingException + // * @throws IOException + // */ + + @Test + public void nestedDocSchemaFromJsonFileTest() throws JsonParseException, JsonMappingException, IOException { + + // Import our json format document schema from a file. + File schemaFile = new File(NESTED_DOC_SCHEMA_JSON); + String fileString = TestUtils.readFileToString(schemaFile); + + // Unmarshall that to a Java POJO + ObjectMapper mapper = new ObjectMapper(); + DocumentSchema docSchema = mapper.readValue(schemaFile, DocumentSchema.class); + + String jsonString = mapper.writeValueAsString(docSchema); + + // Assert that the raw JSON that we read from the file matches the marshalled + // JSON we generated from our Java object (ie: validate that we didn't lose + // anything going in either direction). + assertTrue("Marshalled object does not match the original json source that produced it", + fileString.equals(jsonString)); + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentTest.java new file mode 100644 index 0000000..e4cf335 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/DocumentTest.java @@ -0,0 +1,727 @@ +/** + * ============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.rest; + +import com.fasterxml.jackson.core.JsonProcessingException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +// import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MultivaluedMap; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.MockitoAnnotations; +import org.mockito.invocation.InvocationOnMock; +import org.mockito.stubbing.Answer; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.config.ElasticSearchConfig; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.dao.DocumentStoreDataEntity; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.dao.DocumentStoreInterface; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.dao.ElasticSearchHttpController; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.exception.DocumentStoreOperationException; +import org.onap.aai.sa.searchdbabstraction.entity.DocumentOperationResult; +import org.onap.aai.sa.searchdbabstraction.entity.ErrorResult; +import org.onap.aai.sa.searchdbabstraction.entity.SearchHits; +import org.onap.aai.sa.searchdbabstraction.entity.SearchOperationResult; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import java.util.Properties; + + +public class DocumentTest { + + @Mock + SearchServiceApi searchServiceApi; + + @Mock + HttpServletRequest request; + + @Mock + HttpHeaders headers; + + @Mock + HttpServletResponse httpResponse; + + @Mock + DocumentStoreInterface documentStore; + + @Mock + MultivaluedMap multivaluedMap; + + @InjectMocks + IndexApi indexApi; + + DocumentApi documentApi; + + @Mock + ElasticSearchHttpController httpController; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + documentApi = new DocumentApi(searchServiceApi); + } + + @Test + public void testDocumentClass_AllMethods() throws JsonProcessingException { + Document doc = new Document(); + doc.setField("name-1", "value-1"); + Assert.assertTrue(doc.getFields().size() == 1); + Assert.assertTrue(doc.toJson().contains("value-1")); + Assert.assertNotNull(doc.toString()); + Assert.assertTrue(doc.toString().contains("name-1")); + } + + @Test + public void testProcessPost_NullContent() { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = null; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap); + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + ResponseEntity response = + documentApi.processPost(content, request, headers, httpResponse, "index", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.BAD_REQUEST.value() == response.getStatusCodeValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void testProcessPost_NotNullContent() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap); + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenThrow(IllegalArgumentException.class); + ResponseEntity response = + documentApi.processPost(content, request, headers, httpResponse, "index", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + // + @Test + public void testProcessPost_ValidRequest() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + DocumentOperationResult result = new DocumentOperationResult(); + result.setResultCode(150); + result.setError(new ErrorResult("type-1", "reason-1")); + result.setFailureCause("test-failure"); + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap); + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(true); + Mockito.when(documentStore.createDocument(Mockito.anyString(), Mockito.any(DocumentStoreDataEntity.class), + Mockito.anyBoolean())).thenReturn(result); + Mockito.doNothing().when(httpResponse).setHeader(Mockito.anyString(), Mockito.anyString()); + ResponseEntity response = + documentApi.processPost(content, request, headers, httpResponse, "index", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.INTERNAL_SERVER_ERROR.value() == response.getStatusCodeValue()); + } + + // + @Test + public void testProcessSearchWithGet_Created() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + SearchOperationResult result = new SearchOperationResult(); + result.setResultCode(201); + SearchHits hits = new SearchHits(); + hits.setTotalHits("2"); + result.setSearchResult(hits); + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap); + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(true); + Mockito.when(documentStore.search(Mockito.anyString(), Mockito.anyString())).thenReturn(result); + ResponseEntity response = + documentApi.processSearchWithGet(content, request, headers, "index-1", "query-text", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.CREATED.value() == response.getStatusCodeValue()); + + } + + @SuppressWarnings("unchecked") + @Test + public void testProcessSearchWithGet_ValidateThrowsException() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + SearchOperationResult result = new SearchOperationResult(); + result.setResultCode(201); + SearchHits hits = new SearchHits(); + hits.setTotalHits("2"); + result.setSearchResult(hits); + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap); + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenThrow(IllegalArgumentException.class); + Mockito.when(documentStore.search(Mockito.anyString(), Mockito.anyString())).thenReturn(result); + ResponseEntity response = + documentApi.processSearchWithGet(content, request, headers, "index-1", "query-text", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + + } + + @Test + public void testProcessSearchWithGet_ValidateIsFalse() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + SearchOperationResult result = new SearchOperationResult(); + result.setResultCode(201); + SearchHits hits = new SearchHits(); + hits.setTotalHits("2"); + result.setSearchResult(hits); + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap); + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(false); + Mockito.when(documentStore.search(Mockito.anyString(), Mockito.anyString())).thenReturn(result); + ResponseEntity response = + documentApi.processSearchWithGet(content, request, headers, "index-1", "query-text", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + + } + + @Test + public void testProcessSearchWithGet_InvalidResult() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + SearchOperationResult result = new SearchOperationResult(); + result.setResultCode(302); + SearchHits hits = new SearchHits(); + hits.setTotalHits("2"); + result.setSearchResult(hits); + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(true); + Mockito.when(documentStore.search(Mockito.anyString(), Mockito.anyString())).thenReturn(result); + ResponseEntity response = + documentApi.processSearchWithGet(content, request, headers, "index-1", "query-text", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FOUND.value() == response.getStatusCodeValue()); + + } + + @Test + public void testProcessPut_NullContent() { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = null; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + ResponseEntity response = + documentApi.processPut(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.BAD_REQUEST.value() == response.getStatusCodeValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void testProcessPut_RequestThrowsException() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenThrow(IllegalArgumentException.class); + ResponseEntity response = + documentApi.processPut(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @Test + public void testProcessPut_RequestInvalid() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(false); + ResponseEntity response = + documentApi.processPut(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @Test + public void testProcessPut_ResultInvalid() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + DocumentOperationResult result = new DocumentOperationResult(); + result.setResultCode(302); + result.setError(new ErrorResult("type-1", "reason-1")); + result.setFailureCause("test-failure"); + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(true); + Mockito.when(documentStore.createDocument(Mockito.anyString(), Mockito.any(DocumentStoreDataEntity.class), + Mockito.anyBoolean())).thenReturn(result); + ResponseEntity response = + documentApi.processPut(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FOUND.value() == response.getStatusCodeValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void testProcessDelete_RequestThrowsException() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenThrow(IllegalArgumentException.class); + ResponseEntity response = + documentApi.processDelete(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @Test + public void testProcessDelete_RequestInvalid() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(false); + ResponseEntity response = + documentApi.processDelete(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @Ignore + @Test + public void testProcessDelete_ResultInvalid() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + DocumentOperationResult result = new DocumentOperationResult(); + result.setResultCode(302); + result.setError(new ErrorResult("type-1", "reason-1")); + result.setFailureCause("test-failure"); + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(true); + Mockito.when(documentStore.deleteDocument(Mockito.anyString(), Mockito.any(DocumentStoreDataEntity.class))) + .thenReturn(result); + ResponseEntity response = + documentApi.processDelete(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FOUND.value() == response.getStatusCodeValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void testProcessGet_RequestThrowsException() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenThrow(IllegalArgumentException.class); + ResponseEntity response = + documentApi.processGet(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @Test + public void testProcessGet_RequestInvalid() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(false); + ResponseEntity response = + documentApi.processGet(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @Test + public void testProcessGet_ResultInvalid() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + DocumentOperationResult result = new DocumentOperationResult(); + result.setResultCode(302); + result.setError(new ErrorResult("type-1", "reason-1")); + result.setFailureCause("test-failure"); + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(true); + Mockito.when(documentStore.getDocument(Mockito.anyString(), Mockito.any(DocumentStoreDataEntity.class))) + .thenReturn(result); + ResponseEntity response = + documentApi.processGet(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FOUND.value() == response.getStatusCodeValue()); + } + + @Test + public void testQueryWithGetWithPayload_NullContent() { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = null; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + ResponseEntity response = + documentApi.queryWithGetWithPayload(content, request, headers, "index-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.BAD_REQUEST.value() == response.getStatusCodeValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void testQueryWithGetWithPayload_RequestThrowsException() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenThrow(IllegalArgumentException.class); + ResponseEntity response = + documentApi.queryWithGetWithPayload(content, request, headers, "index-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @Test + public void testQueryWithGetWithPayload_RequestInvalid() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(false); + ResponseEntity response = + documentApi.queryWithGetWithPayload(content, request, headers, "index-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @Test + public void testCreateProcessIndex_IndexApi_RequestInvalid() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(false); + ResponseEntity response = + indexApi.processCreateIndex("document-1", request, headers, "index-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void testCreateProcessIndex_IndexApi_RequestThrowsException() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenThrow(IllegalArgumentException.class); + ResponseEntity response = + indexApi.processCreateIndex("document-1", request, headers, "index-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @Test + public void testCreateProcessIndex_IndexApi_NullDocument() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String documentSchema = null; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(true); + ResponseEntity response = + indexApi.processCreateIndex(documentSchema, request, headers, "index-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.INTERNAL_SERVER_ERROR.value() == response.getStatusCodeValue()); + } + + @Test + public void testProcessDelete_IndexApi_RequestInvalid() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(false); + ResponseEntity response = indexApi.processDelete("document-1", request, headers, documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void testProcessDelete_IndexApi_RequestThrowsException() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenThrow(IllegalArgumentException.class); + ResponseEntity response = indexApi.processDelete("document-1", request, headers, documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + } + + @SuppressWarnings("unchecked") + @Test + public void testProcessDelete_IndexApi_DeleteIndexException() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenReturn(true); + Mockito.when(documentStore.deleteIndex(Mockito.anyString())).thenThrow(DocumentStoreOperationException.class); + ResponseEntity response = indexApi.processDelete("document-1", request, headers, documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.INTERNAL_SERVER_ERROR.value() == response.getStatusCodeValue()); + } + + @Test + public void testUserAuthorization() throws Exception { + String transactionId = "transactionId-1"; + String remoteAddr = "http://127.0.0.1"; + String content = "content"; + // Mockito.when(headers.getRequestHeaders()).thenReturn(multivaluedMap);; + Mockito.when(multivaluedMap.getFirst(Mockito.anyString())).thenReturn(transactionId); + Mockito.when(request.getRemoteAddr()).thenReturn(remoteAddr); + Mockito.when(request.getMethod()).thenReturn("testMethod"); + Mockito.when(request.getRequestURL()).thenReturn(new StringBuffer("http://127.0.0.1")); + Mockito.when(request.getRemoteHost()).thenReturn("localhost"); + Mockito.when(searchServiceApi.validateRequest(Mockito.any(HttpHeaders.class), + Mockito.any(HttpServletRequest.class), Mockito.any(ApiUtils.Action.class), Mockito.anyString())) + .thenCallRealMethod(); + + Mockito.doAnswer(new Answer() { + public ElasticSearchConfig answer(InvocationOnMock invocation) { + Properties properties = new Properties(); + return new ElasticSearchConfig(properties); + } + }).when(httpController).getElasticSearchConfig(); + + searchServiceApi.documentStore = httpController; + + ResponseEntity response = + documentApi.processPut(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + + Mockito.doAnswer(new Answer() { + public ElasticSearchConfig answer(InvocationOnMock invocation) { + Properties properties = new Properties(); + properties.put(ElasticSearchConfig.ES_AUTH_ENABLED, "true"); + return new ElasticSearchConfig(properties); + } + }).when(httpController).getElasticSearchConfig(); + + + response = documentApi.processPut(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FORBIDDEN.value() == response.getStatusCodeValue()); + + Mockito.doAnswer(new Answer() { + public ElasticSearchConfig answer(InvocationOnMock invocation) { + Properties properties = new Properties(); + properties.put(ElasticSearchConfig.ES_AUTH_ENABLED, "false"); + return new ElasticSearchConfig(properties); + } + }).when(httpController).getElasticSearchConfig(); + + DocumentOperationResult result = new DocumentOperationResult(); + result.setResultCode(302); + result.setError(new ErrorResult("type-1", "reason-1")); + result.setFailureCause("test-failure"); + Mockito.when(documentStore.createDocument(Mockito.anyString(), Mockito.any(DocumentStoreDataEntity.class), + Mockito.anyBoolean())).thenReturn(result); + response = documentApi.processPut(content, request, headers, httpResponse, "index", "id-1", documentStore); + Assert.assertNotNull(response); + Assert.assertTrue(HttpStatus.FOUND.value() == response.getStatusCodeValue()); + + } +} \ No newline at end of file diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/rest/IndexApiTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/IndexApiTest.java new file mode 100644 index 0000000..ed84a7a --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/IndexApiTest.java @@ -0,0 +1,280 @@ +/** + * ============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.rest; + + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import org.junit.Before; +// import org.glassfish.jersey.server.ResourceConfig; +// import org.glassfish.jersey.test.JerseyTest; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.exception.DocumentStoreOperationException; +import org.onap.aai.sa.searchdbabstraction.entity.OperationResult; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.MvcResult; + +//import javax.ws.rs.core.Application; +//import javax.ws.rs.core.Response; + + +/** + * This suite of tests is intended to exercise the set of REST endpoints associated with manipulating Indexes in the + * document store. + */ +@RunWith(SpringRunner.class) +@SpringBootTest +@AutoConfigureMockMvc +public class IndexApiTest { + + 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"; + + @Autowired + private MockMvc mockMvc; + + // + // @Override + // protected Application configure() { + // + // // Make sure that our test endpoint is on the resource path + // // for Jersey Test. + // return new ResourceConfig(SearchServiceApiHarness.class); + // } + // + // + + @Before + public void setup() throws Exception { + System.setProperty("CONFIG_HOME", System.getProperty("user.dir") + File.separator + "src/test/resources/json"); + } + + /** + * 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 Exception { + 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); + MvcResult result = this.mockMvc + .perform(put(dynamicUri + indexName).contentType(MediaType.APPLICATION_JSON).content(indexPayload)) + .andReturn(); + + assertEquals(indexPayload, result.getResponse().getContentAsString()); + } + + + /** + * This test validates that the {@link IndexApi} is able to convert {@link OperationResult} obects to standard REST + * {@link ResponseEntity} objects. + * + * @throws FileNotFoundException + * @throws IOException + * @throws DocumentStoreOperationException + */ + @Test + public void responseFromOperationResultTest() + throws FileNotFoundException, IOException, DocumentStoreOperationException { + + int SUCCESS_RESULT_CODE = 200; + String SUCCESS_RESULT_STRING = "Everything is ay-okay!"; + int FAILURE_RESULT_CODE = 500; + String FAILURE_CAUSE_STRING = "Something went wrong!"; + + + // Create an instance of the index API endpoint that we will test against. + // We will override the init() method because we don't want it to try to + // connect to a real document store. + IndexApi indexApi = new IndexApi(new SearchServiceApiHarness()) { + @Override + public void init() { /* do nothing */ } + }; + // + // Construct an OperationResult instance with a success code and string. + OperationResult successResult = new OperationResult(); + successResult.setResultCode(SUCCESS_RESULT_CODE); + successResult.setResult(SUCCESS_RESULT_STRING); + + // Convert our success OperationResult to a standard REST Response... + ResponseEntity successResponse = indexApi.responseFromOperationResult(successResult); + + // ...and validate that the Response is correctly populated. + assertEquals("Unexpected result code", SUCCESS_RESULT_CODE, successResponse.getStatusCodeValue()); + assertTrue("Incorrect result string", ((String) successResponse.getBody()).equals(SUCCESS_RESULT_STRING)); + + // Construct an OperationResult instance with an error code and failure + // cause. + OperationResult failureResult = new OperationResult(); + failureResult.setResultCode(FAILURE_RESULT_CODE); + failureResult.setFailureCause(FAILURE_CAUSE_STRING); + + // Convert our failure OperationResult to a standard REST Response... + ResponseEntity failureResponse = indexApi.responseFromOperationResult(failureResult); + + // ...and validate that the Response is correctly populated. + assertEquals("Unexpected result code", FAILURE_RESULT_CODE, failureResponse.getStatusCodeValue()); + assertTrue("Incorrect result string", ((String) failureResponse.getBody()).equals(FAILURE_CAUSE_STRING)); + } + + // + // + // /** + // * This test validates the behaviour of the 'Create Index' POST request + // * endpoint. + // * + // * @throws IOException + // */ + @Test + public void createIndexTest() throws Exception { + + String INDEX_NAME = "test-index"; + String EXPECTED_SETTINGS = "{\"analysis\": " + "{\"filter\": " + "{\"nGram_filter\": { " + + "\"type\": \"nGram\", " + "\"min_gram\": 1, " + "\"max_gram\": 50, " + + "\"token_chars\": [ \"letter\", \"digit\", \"punctuation\", \"symbol\" ]}}," + "\"analyzer\": {" + + "\"nGram_analyzer\": " + "{\"type\": \"custom\"," + "\"tokenizer\": \"whitespace\"," + + "\"filter\": [\"lowercase\",\"asciifolding\",\"nGram_filter\"]}," + "\"whitespace_analyzer\": " + + "{\"type\": \"custom\"," + "\"tokenizer\": \"whitespace\"," + + "\"filter\": [\"lowercase\",\"asciifolding\"]}}}}"; + String EXPECTED_MAPPINGS = + "{\"dynamic_templates\":[{\"strings\":{\"match_mapping_type\":\"string\",\"match\":\"*\",\"mapping\":{\"type\":\"text\",\"fielddata\":true}}}]" + + ",\"properties\": {" + "\"serverName\": {" + "\"type\": \"string\", " + + "\"index\": \"analyzed\", " + "\"search_analyzer\": \"whitespace\"}, " + + "\"serverComplex\": {" + "\"type\": \"string\", " + "\"search_analyzer\": \"whitespace\"}}}"; + + // Read a valid document schema from a json file. + File schemaFile = new File(SIMPLE_DOC_SCHEMA_JSON); + String documentJson = TestUtils.readFileToString(schemaFile); + + // Send a request to our 'create index' endpoint, using the schema + // which we just read. + // String result = target(TOP_URI + INDEX_NAME).request().put(Entity.json(documentJson), String.class); + MvcResult result = this.mockMvc + .perform(put(TOP_URI + INDEX_NAME).contentType(MediaType.APPLICATION_JSON).content(documentJson)) + .andReturn(); + + + // Our stub document store DAO returns the parameters that it was + // passed as the result string, so now we can validate that our + // endpoint invoked it with the correct parameters. + String[] tokenizedResult = result.getResponse().getContentAsString().split("@"); + assertTrue("Unexpected Index Name '" + tokenizedResult[0] + "' passed to doc store DAO", + tokenizedResult[0].equals(INDEX_NAME)); + assertTrue("Unexpected settings string '" + tokenizedResult[1] + "' passed to doc store DAO", + tokenizedResult[1].equals(EXPECTED_SETTINGS)); + assertTrue("Unexpected mappings string '" + tokenizedResult[2] + "' passed to doc store DAO", + tokenizedResult[2].equals(EXPECTED_MAPPINGS)); + } + + // + // + /** + * This test validates that a 'create index' request with an improperly formatted document schema as the payload + * will result in an appropriate error being returned from the endpoint. + */ + @Test + public void createIndexWithMangledSchemaTest() throws Exception { + + String INDEX_NAME = "test-index"; + int BAD_REQUEST_CODE = 400; + + String invalidSchemaString = "this is definitely not json!"; + + // ResponseEntity result = target(TOP_URI + INDEX_NAME).request().put(Entity.json(invalidSchemaString), + // ResponseEntity.class); + MvcResult result = this.mockMvc + .perform(put(TOP_URI + INDEX_NAME).contentType(MediaType.APPLICATION_JSON).content(invalidSchemaString)) + .andReturn(); + + assertEquals("Invalid document schema should result in a 400 error", BAD_REQUEST_CODE, + result.getResponse().getStatus()); + } + + // + // + /** + * This test validates the behaviour of the 'Delete Index' end point. + */ + @Test + public void deleteIndexTest() throws Exception { + + String INDEX_NAME = "test-index"; + + // Send a request to the 'delete index' endpoint. + // String result = target(TOP_URI + INDEX_NAME).request().delete(String.class); + + MvcResult result = this.mockMvc.perform(delete(TOP_URI + INDEX_NAME).contentType(MediaType.APPLICATION_JSON) + .header("If-Match", "1").content("Some Json")).andReturn(); + + // Validate that the expected parameters were passed to the document + // store DAO. + assertTrue("Unexpected index name '" + result.getResponse().getContentAsString() + "' passed to doc store DAO", + result.getResponse().getContentAsString().equals(INDEX_NAME)); + } + + // + // + // /** + // * This test validates that attempting to delete an index which does not + // * exist results in a 404 error. + // */ + @Test + public void deleteIndexDoesNotExistTest() throws Exception { + + int NOT_FOUND_CODE = 404; + + // Send a request to the 'delete index' endpoint, specifying a + // non-existent index. + // ResponseEntity result = target(TOP_URI + + // StubEsController.DOES_NOT_EXIST_INDEX).request().delete(ResponseEntity.class); + + MvcResult result = + this.mockMvc + .perform(delete(TOP_URI + StubEsController.DOES_NOT_EXIST_INDEX) + .contentType(MediaType.APPLICATION_JSON).header("If-Match", "1").content("Some Json")) + .andReturn(); + + + // Validate that a 404 error code is returned from the end point. + assertEquals("Deleting an index which does not exist should result in a 404 error", NOT_FOUND_CODE, + result.getResponse().getStatus()); + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/rest/SearchServiceApiHarness.java b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/SearchServiceApiHarness.java new file mode 100644 index 0000000..93e1d49 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/SearchServiceApiHarness.java @@ -0,0 +1,164 @@ +/** + * ============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.rest; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@Component +@RestController +@RequestMapping("/test") +public class SearchServiceApiHarness extends SearchServiceApi { + + + public static final String FAIL_AUTHENTICATION_TRIGGER = "FAIL AUTHENTICATION"; + + private boolean authenticationShouldSucceed = true; + + + /** + * Performs all one-time initialization required for the end point. + */ + @Override + public void init() { + + // Instantiate our Document Store DAO. + documentStore = new StubEsController(); + } + + @Override + @RequestMapping(value = "/indexes/dynamic/{index}", method = RequestMethod.PUT, consumes = {"application/json"}) + public ResponseEntity processCreateDynamicIndex(@RequestBody String requestBody, HttpServletRequest request, + @RequestHeader HttpHeaders headers, @PathVariable("index") String index) { + + return super.processCreateDynamicIndex(requestBody, request, headers, index); + } + + + @Override + @RequestMapping(value = "/indexes/{index}", method = RequestMethod.PUT, consumes = {"application/json"}) + public ResponseEntity processCreateIndex(@RequestBody String requestBody, HttpServletRequest request, + @RequestHeader HttpHeaders headers, @PathVariable("index") String index) { + + return super.processCreateIndex(requestBody, request, headers, index); + } + + @Override + @RequestMapping(value = "/indexes/{index}", method = RequestMethod.DELETE, consumes = {"application/json"}) + public ResponseEntity processDeleteIndex(HttpServletRequest request, @RequestHeader HttpHeaders headers, + @PathVariable("index") String index) { + + return super.processDeleteIndex(request, headers, index); + } + + @Override + @RequestMapping(value = "/indexes/{index}/documents/{id}", method = RequestMethod.GET) + public ResponseEntity processGetDocument(HttpServletRequest request, HttpServletResponse httpResponse, + @RequestHeader HttpHeaders headers, @PathVariable("index") String index, @PathVariable("id") String id) { + + return super.processGetDocument(request, httpResponse, headers, index, id); + } + + @Override + @RequestMapping(value = "/indexes/{index}/documents", method = RequestMethod.POST, + consumes = {"application/json", "application/xml"}) + public ResponseEntity processCreateDocWithoutId(@RequestBody String requestBody, HttpServletRequest request, + HttpServletResponse httpResponse, @RequestHeader HttpHeaders headers, @PathVariable("index") String index) { + + return super.processCreateDocWithoutId(requestBody, request, httpResponse, headers, index); + } + + @Override + @RequestMapping(value = "/indexes/{index}/documents/{id}", method = RequestMethod.PUT, + consumes = {"application/json", "application/xml"}) + public ResponseEntity processUpsertDoc(@RequestBody String requestBody, HttpServletRequest request, + HttpServletResponse httpResponse, @RequestHeader HttpHeaders headers, @PathVariable("index") String index, + @PathVariable("id") String id) { + + return super.processUpsertDoc(requestBody, request, httpResponse, headers, index, id); + } + + @Override + @RequestMapping(value = "/indexes/{index}/documents/{id}", method = RequestMethod.DELETE, + consumes = {"application/json"}) + public ResponseEntity processDeleteDoc(HttpServletRequest request, HttpServletResponse httpResponse, + @RequestHeader HttpHeaders headers, @PathVariable("index") String index, @PathVariable("id") String id) { + + return super.processDeleteDoc(request, httpResponse, headers, index, id); + } + + @Override + @RequestMapping(value = "/indexes/{index}/query/{queryText}", method = RequestMethod.GET) + public ResponseEntity processInlineQuery(HttpServletRequest request, @RequestHeader HttpHeaders headers, + @PathVariable("index") String index, @PathVariable("queryText") String queryText) { + + return super.processInlineQuery(request, headers, index, queryText); + } + + @Override + @RequestMapping(value = "/indexes/{index}/query", method = RequestMethod.GET, consumes = {"application/json"}) + public ResponseEntity processQueryWithGet(@RequestBody String requestBody, HttpServletRequest request, + @RequestHeader HttpHeaders headers, @PathVariable("index") String index) { + + return super.processQueryWithGet(requestBody, request, headers, index); + } + + @Override + @RequestMapping(value = "/indexes/{index}/query", method = RequestMethod.POST, consumes = {"application/json"}) + public ResponseEntity processQuery(@RequestBody String requestBody, HttpServletRequest request, + @RequestHeader HttpHeaders headers, @PathVariable("index") String index) { + + return super.processQuery(requestBody, request, headers, index); + } + + @Override + @RequestMapping(value = "/bulk", method = RequestMethod.POST, consumes = {"application/json"}, + produces = {"application/json"}) + public ResponseEntity processBulkRequest(@RequestBody String requestBody, HttpServletRequest request, + @RequestHeader HttpHeaders headers) { + + // If the operations string contains a special keyword, set the + // harness to fail the authentication validation. + if (requestBody.contains(FAIL_AUTHENTICATION_TRIGGER)) { + authenticationShouldSucceed = false; + } + + // Just pass the request up to the parent, since that is the code + // that we really want to test. + // return super.processPost(operations, request, headers, index); + return super.processBulkRequest(requestBody, request, headers); + } + + @Override + protected boolean validateRequest(HttpHeaders headers, HttpServletRequest req, ApiUtils.Action action, + String authPolicyFunctionName) { + return authenticationShouldSucceed; + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/rest/SettingConfigurationTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/SettingConfigurationTest.java new file mode 100644 index 0000000..9cc4e3b --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/SettingConfigurationTest.java @@ -0,0 +1,57 @@ +/** + * ============LICENSE_START======================================================= + * org.onap.aai + * ================================================================================ + * Copyright © 2019 AT&T Intellectual Property. All rights reserved. + * Copyright © 2019 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.rest; + +import org.junit.Assert; +import org.junit.Test; + + +public class SettingConfigurationTest { + + @Test + public void settingConfigTest() throws Exception { + SettingConfiguration config = new SettingConfiguration(); + config.init("src/test/resources/json/settings-config.json"); + String settings = config.getSettings(); + System.out.println("SettingsConfig:\n" + settings); + Assert.assertTrue(settings.contains("number_of_shards")); + } + + @Test + public void settingConfigAnalysisTest() throws Exception { + AnalysisConfiguration ac = new AnalysisConfiguration(); + ac.init("src/test/resources/json/filter-config.json", "src/test/resources/json/analysis-config.json"); + System.out.println("AnalysisConfig:\n" + ac.buildEsIndexSettings()); + + SettingConfiguration config = new SettingConfiguration(); + config.init("src/test/resources/json/settings-config.json"); + String settings = config.getSettingsWithAnalysis(ac); + System.out.println("SettingsAnalysisConfig:\n" + settings); + Assert.assertTrue(settings.contains("number_of_shards")); + Assert.assertTrue(settings.contains("nGram_analyzer")); + + config = new SettingConfiguration(); + config.init("src/test/resources/json/missing-file.json"); + settings = config.getSettingsWithAnalysis(ac); + System.out.println("SettingsAnalysisConfigMissing:\n" + settings); + Assert.assertFalse(ac.getEsIndexSettings().isEmpty()); + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/rest/StubEsController.java b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/StubEsController.java new file mode 100644 index 0000000..cb4edbc --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/StubEsController.java @@ -0,0 +1,266 @@ +/** + * ============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.rest; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import org.json.simple.JSONObject; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.dao.DocumentStoreDataEntity; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.dao.DocumentStoreInterface; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.exception.DocumentStoreOperationException; +import org.onap.aai.sa.searchdbabstraction.entity.Document; +import org.onap.aai.sa.searchdbabstraction.entity.DocumentOperationResult; +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.util.DocumentSchemaUtil; + +/** + * 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 { + + public static final String DOES_NOT_EXIST_INDEX = "index-does-not-exist"; + + private AnalysisConfiguration analysisConfig = null; + + /** + * + */ + // private IndexAPIHarness indexAPIHarness; + + StubEsController() { + analysisConfig = new AnalysisConfiguration(); + analysisConfig.init("src/test/resources/json/filter-config.json", + "src/test/resources/json/analysis-config.json"); + } + + + @Override + 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 + // that those parameters match what they expected to be passed. + OperationResult opResult = new OperationResult(); + opResult.setResultCode(200); + + try { + opResult.setResult(index + "@" + analysisConfig.getEsIndexSettings() + "@" + + DocumentSchemaUtil.generateDocumentMappings(documentSchema)); + } catch (IOException e) { + e.printStackTrace(); + } + + 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 { + + OperationResult opResult = new OperationResult(); + + if (indexName.equals(DOES_NOT_EXIST_INDEX)) { + opResult.setResultCode(404); + } else { + opResult.setResultCode(200); + opResult.setResult(indexName); + } + + return opResult; + } + + @Override + public DocumentOperationResult createDocument(String indexName, DocumentStoreDataEntity document, + boolean allowImplicitIndexCreation) throws DocumentStoreOperationException { + + DocumentOperationResult opResult = buildSampleDocumentOperationResult(); + + if (indexName.equals(DOES_NOT_EXIST_INDEX)) { + opResult.setResultCode(404); + } else { + opResult.setResultCode(200); + opResult.setResultVersion("1"); + } + + return opResult; + } + + @Override + public DocumentOperationResult updateDocument(String indexName, DocumentStoreDataEntity document, + boolean allowImplicitIndexCreation) throws DocumentStoreOperationException { + + DocumentOperationResult opResult = buildSampleDocumentOperationResult(); + + if (indexName.equals(DOES_NOT_EXIST_INDEX)) { + opResult.setResultCode(404); + } else { + opResult.setResultCode(200); + String version = "1"; + if (document.getVersion() != null) { + version = String.valueOf(Integer.parseInt(document.getVersion()) + 1); + } + opResult.setResultVersion(version); + } + + return opResult; + } + + @Override + public DocumentOperationResult deleteDocument(String indexName, DocumentStoreDataEntity document) + throws DocumentStoreOperationException { + DocumentOperationResult opResult = buildSampleDocumentOperationResult(); + + + if (indexName.equals(DOES_NOT_EXIST_INDEX)) { + opResult.setResultCode(404); + } else { + if (opResult.getDocument() != null) { + opResult.getDocument().setEtag(null); + opResult.getDocument().setUrl(null); + opResult.setResultVersion("1"); + } + opResult.setResultCode(200); + opResult.setResult(indexName + "@" + document.getId()); + opResult.setResultVersion("1"); + } + + return opResult; + } + + @Override + public DocumentOperationResult getDocument(String indexName, DocumentStoreDataEntity document) + throws DocumentStoreOperationException { + DocumentOperationResult opResult = buildSampleDocumentOperationResult(); + + if (indexName.equals(DOES_NOT_EXIST_INDEX)) { + opResult.setResultCode(404); + // Adding it to make the tests pass. + opResult.setResultVersion("1"); + } else { + opResult.setResultCode(200); + // Adding it to make the tests pass. + opResult.setResultVersion("1"); + } + + return opResult; + } + + @Override + public SearchOperationResult search(String indexName, String queryText) throws DocumentStoreOperationException { + + SearchOperationResult opResult = buildSampleSearchOperationResult(); + + if (indexName.equals(DOES_NOT_EXIST_INDEX)) { + opResult.setResultCode(404); + } else { + opResult.setResultCode(200); + opResult.setResult(indexName + "@" + queryText); + } + + return opResult; + } + + @Override + public SearchOperationResult searchWithPayload(String indexName, String query) + throws DocumentStoreOperationException { + SearchOperationResult opResult = buildSampleSearchOperationResult(); + + if (indexName.equals(DOES_NOT_EXIST_INDEX)) { + opResult.setResultCode(404); + } else { + opResult.setResultCode(200); + opResult.setResult(indexName + "@" + query); + } + + return opResult; + } + + @Override + 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); + + return opResult; + } + + private DocumentOperationResult buildSampleDocumentOperationResult() { + DocumentOperationResult result = new DocumentOperationResult(); + Document doc = new Document(); + doc.setEtag("etag1"); + + doc.setContent(new JSONObject()); + result.setDocument(doc); + return result; + } + + private SearchOperationResult buildSampleSearchOperationResult() { + SearchOperationResult result = new SearchOperationResult(); + + SearchHits searchHits = new SearchHits(); + SearchHit[] searchHitArray = new SearchHit[1]; + SearchHit searchHit = new SearchHit(); + Document doc = new Document(); + doc.setEtag("etag1"); + Map content = new HashMap<>(); + content.put("key1", "value1"); + doc.setContent(new JSONObject()); + searchHit.setDocument(doc); + searchHitArray[0] = searchHit; + + searchHits.setHits(searchHitArray); + searchHits.setTotalHits("1"); + result.setSearchResult(searchHits); + + return result; + + } + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/rest/TestUtils.java b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/TestUtils.java new file mode 100644 index 0000000..0d2c615 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/rest/TestUtils.java @@ -0,0 +1,63 @@ +/** + * ============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.rest; + +import static org.junit.Assert.fail; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +public class TestUtils { + + /** + * This helper method reads the contents of a file into a simple string. + * + * @param aFile - The file to be imported. + * + * @return - The file contents expressed as a simple string. + * + * @throws IOException + */ + public static String readFileToString(File aFile) throws IOException { + + BufferedReader br = new BufferedReader(new FileReader(aFile)); + try { + StringBuilder sb = new StringBuilder(); + String line = br.readLine(); + + while (line != null) { + sb.append(line); + line = br.readLine(); + } + + return sb.toString().replaceAll("\\s+", ""); + } finally { + try { + br.close(); + } catch (IOException e) { + fail("Unexpected IOException: " + e.getMessage()); + } + } + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/config/ElasticSearchConfigTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/config/ElasticSearchConfigTest.java new file mode 100644 index 0000000..e840e2c --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/config/ElasticSearchConfigTest.java @@ -0,0 +1,53 @@ +/** + * ============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.elasticsearch.config; + +import java.util.Properties; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +public class ElasticSearchConfigTest { + + @Autowired + ElasticSearchConfig elasticSearchConfig; + + @Before + public void setUp() { + Properties prop = new Properties(); + prop.put("es.cluster-name", "cluster-1"); + prop.put("es.ip-address", "127.0.0.1"); + prop.put("es.http-port", "9001"); + // elasticSearchConfig = new ElasticSearchConfig(prop); + } + + @Ignore + @Test + public void testAllGetMethods() { + Assert.assertEquals(elasticSearchConfig.getClusterName(), "cluster-1"); + Assert.assertEquals(elasticSearchConfig.getIpAddress(), "127.0.0.1"); + Assert.assertEquals(elasticSearchConfig.getHttpPort(), "9001"); + Assert.assertEquals(elasticSearchConfig.getJavaApiPort(), "9300"); + Assert.assertNotNull(elasticSearchConfig.toString()); + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/AggregationResponseParsingTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/AggregationResponseParsingTest.java new file mode 100644 index 0000000..fbc077d --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/AggregationResponseParsingTest.java @@ -0,0 +1,99 @@ +/** + * ============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.elasticsearch.dao; + +import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.junit.Test; +import org.onap.aai.sa.searchdbabstraction.entity.AggregationResult; +import org.onap.aai.sa.searchdbabstraction.entity.AggregationResults; +import org.onap.aai.sa.searchdbabstraction.util.AggregationParsingUtil; + +public class AggregationResponseParsingTest { + + @Test + public void testParseAggregationResponse() { + JSONParser parser = new JSONParser(); + JSONObject root; + + String input = + "{\r\n \"aggregations\": {\r\n \"violations\": {\r\n \"doc_count\": 2,\r\n \"by_Timestamp\": {\r\n \"doc_count_error_upper_bound\": 0,\r\n \"sum_other_doc_count\": 0,\r\n \"buckets\": [\r\n {\r\n \"key\": 7199992,\r\n \"key_as_string\": \"Jan 1 1970 01:59:59\",\r\n \"doc_count\": 2\r\n }\r\n ]\r\n }\r\n }\r\n }\r\n}"; + + try { + root = (JSONObject) parser.parse(input); + JSONObject aggregations = (JSONObject) root.get("aggregations"); + AggregationResult[] results = AggregationParsingUtil.parseAggregationResults(aggregations); + AggregationResults aggs = new AggregationResults(); + ObjectMapper mapper = new ObjectMapper(); + aggs.setAggregations(results); + System.out.println(mapper.setSerializationInclusion(Include.NON_NULL).writerWithDefaultPrettyPrinter() + .writeValueAsString(aggs)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void testParseAggregationResponse2() { + JSONParser parser = new JSONParser(); + JSONObject root; + + String input = + "{\r\n \"aggregations\": {\r\n \"entityType\": {\r\n \"doc_count_error_upper_bound\": 0,\r\n \"sum_other_doc_count\": 0,\r\n \"buckets\": [\r\n {\r\n \"key\": \"entity1\",\r\n \"doc_count\": 5,\r\n \"byVersion\": {\r\n \"doc_count_error_upper_bound\": 0,\r\n \"sum_other_doc_count\": 0,\r\n \"buckets\": [\r\n {\r\n \"key\": \"0\",\r\n \"doc_count\": 5\r\n }\r\n ]\r\n }\r\n }\r\n ]\r\n }\r\n }\r\n}"; + + try { + root = (JSONObject) parser.parse(input); + JSONObject aggregations = (JSONObject) root.get("aggregations"); + AggregationResult[] results = AggregationParsingUtil.parseAggregationResults(aggregations); + AggregationResults aggs = new AggregationResults(); + ObjectMapper mapper = new ObjectMapper(); + aggs.setAggregations(results); + System.out.println(mapper.setSerializationInclusion(Include.NON_NULL).writerWithDefaultPrettyPrinter() + .writeValueAsString(aggs)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Test + public void testParseAggregationResponse3() { + JSONParser parser = new JSONParser(); + JSONObject root; + + String input = + "{\r\n \"aggregations\": {\r\n \"validateTimes\": {\r\n \"buckets\": [\r\n {\r\n \"key\": \"Jan 10 2017 21:6:6-Jan 24 2017 13:43:5\",\r\n \"from\": 1484082366000,\r\n \"from_as_string\": \"Jan 10 2017 21:6:6\",\r\n \"to\": 1485265385000,\r\n \"to_as_string\": \"Jan 24 2017 13:43:5\",\r\n \"doc_count\": 95\r\n },\r\n {\r\n \"key\": \"Feb 3 2017 18:27:39-*\",\r\n \"from\": 1486146459000,\r\n \"from_as_string\": \"Feb 3 2017 18:27:39\",\r\n \"doc_count\": 2\r\n }\r\n ]\r\n }\r\n }\r\n}"; + + try { + root = (JSONObject) parser.parse(input); + JSONObject aggregations = (JSONObject) root.get("aggregations"); + AggregationResult[] results = AggregationParsingUtil.parseAggregationResults(aggregations); + AggregationResults aggs = new AggregationResults(); + ObjectMapper mapper = new ObjectMapper(); + aggs.setAggregations(results); + System.out.println(mapper.setSerializationInclusion(Include.NON_NULL).writerWithDefaultPrettyPrinter() + .writeValueAsString(aggs)); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpControllerTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpControllerTest.java new file mode 100644 index 0000000..007e3fc --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchHttpControllerTest.java @@ -0,0 +1,330 @@ +/** + * ============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.elasticsearch.dao; + +import static org.hamcrest.CoreMatchers.anyOf; +import static org.hamcrest.CoreMatchers.containsString; +import static org.hamcrest.CoreMatchers.either; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.not; +import static org.junit.Assert.assertThat; + +import java.util.Properties; +import org.eclipse.jetty.util.security.Password; +import org.json.JSONObject; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import org.onap.aai.sa.rest.AnalysisConfiguration; +import org.onap.aai.sa.rest.DocumentSchema; +import org.onap.aai.sa.rest.SettingConfiguration; +import org.onap.aai.sa.searchdbabstraction.elasticsearch.config.ElasticSearchConfig; +import org.onap.aai.sa.searchdbabstraction.entity.OperationResult; + +@Ignore("All tests in this classes require an Elasticsearch instance to run locally") +public class ElasticSearchHttpControllerTest { + + static { + // Set the location of the payload translation JSON file. + System.setProperty("CONFIG_HOME", "src/test/resources/json"); + } + + private static ElasticSearchHttpController elasticSearch; + private static AAIEntityTestObject testDocument; + + private static final String TEST_INDEX_NAME = "test"; + + private static final String indexMappings = + "{\r\n \"properties\": {\r\n \"entityType\": {\r\n \"type\": \"text\"\r\n },\r\n" + + " \"edgeTagQueryEntityFieldName\": {\r\n \"type\": \"text\",\r\n \"index\": \"false\"\r\n },\r\n" + + " \"edgeTagQueryEntityFieldValue\": {\r\n \"type\": \"text\",\r\n \"index\": \"false\"\r\n },\r\n \"searchTagIDs\" : {\r\n \"type\" : \"text\"\r\n },\r\n \"searchTags\": {\r\n \"type\": \"text\",\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 { + Properties properties = new Properties(); + properties.put(ElasticSearchConfig.ES_IP_ADDRESS, "127.0.0.1"); + properties.put(ElasticSearchConfig.ES_HTTP_PORT, "9200"); + properties.put(ElasticSearchConfig.ES_URI_SCHEME, "http"); + properties.put(ElasticSearchConfig.ES_AUTH_USER, "your_user_here"); + properties.put(ElasticSearchConfig.ES_AUTH_ENC, Password.obfuscate("your_password_here")); + elasticSearch = new ElasticSearchHttpController(new ElasticSearchConfig(properties)); + + testDocument = new AAIEntityTestObject(); + testDocument.setId("test123"); + testDocument.setEntityType("service-instance"); + testDocument.setEdgeTagQueryEntityFieldName("service-instance.service-instance-id"); + testDocument.setEdgeTagQueryEntityFieldValue("123456"); + testDocument.setSearchTagIDs("0"); + testDocument.setSearchTags("service-instance-id"); + } + + @Test + public void testGetInstance() throws Exception { + ElasticSearchHttpController.getInstance(); + } + + @Test + public void testCreateIndex() throws Exception { + testDeleteIndex(); + OperationResult result = elasticSearch.createIndex(TEST_INDEX_NAME, new DocumentSchema()); + assertThat(result.getResult(), containsString("/search/indexes/test")); + assertThat(result.getResultCode(), is(201)); + + result = elasticSearch.createIndex(TEST_INDEX_NAME, new DocumentSchema()); + assertThat(result.getResult(), containsString("already exists")); + assertThat(result.getResultCode(), is(400)); + } + + @Test(expected = IllegalArgumentException.class) + public void testCreateDynamicIndexEmptySchema() throws Exception { + elasticSearch.createDynamicIndex(TEST_INDEX_NAME, ""); + } + + @Test + public void testCreateDynamicIndex() throws Exception { + String indexName = "test_dynamic"; + elasticSearch.deleteIndex(indexName); + + OperationResult result = elasticSearch.createDynamicIndex(indexName, + "{\"mappings\":{\"_doc\":{\"dynamic_templates\":[{\"strings_as_text\":{\"match_mapping_type\":\"string\",\"mapping\":{\"type\":\"text\"}}}]}}}"); + assertThat(result.getResult(), containsString("/search/indexes/test")); + assertThat(result.getResultCode(), is(201)); + + elasticSearch.deleteIndex(indexName); + } + + @Test + public void testCreateTable() throws Exception { + AnalysisConfiguration ac = new AnalysisConfiguration(); + ac.init("src/test/resources/json/filter-config.json", "src/test/resources/json/analysis-config.json"); + SettingConfiguration sc = new SettingConfiguration(); + sc.init("src/test/resources/json/settings-config.json"); + + OperationResult result = + elasticSearch.createTable(TEST_INDEX_NAME, "aai-entities", ac, indexMappings, sc); + assertThat(result.getResult(), containsString("\"index\":\"test\"}")); + assertThat(result.getResultCode(), either(is(200)).or(is(400))); + } + + @Test + public void testCreateDocument() throws Exception { + OperationResult result = elasticSearch.createDocument(TEST_INDEX_NAME, testDocument, false); + assertThat(result.getResult(), not(equalTo(""))); + + DocumentStoreDataEntityImpl ds = new DocumentStoreDataEntityImpl(); + ds.setId(testDocument.getId()); + + result = elasticSearch.getDocument(TEST_INDEX_NAME, ds); + assertThat(result.getResult(), not(equalTo(""))); + } + + @Test + public void testCreateDocumentInvalidIndex() throws Exception { + OperationResult result = elasticSearch.createDocument("index_does_not_exist", testDocument, false); + assertThat(result.getResultCode(), is(404)); + assertThat(result.getResult(), not(equalTo(""))); + } + + @Test + public void testUpdateDocument() throws Exception { + testDocument.setEdgeTagQueryEntityFieldValue("567890"); + + OperationResult result = elasticSearch.getDocument(TEST_INDEX_NAME, testDocument); + if (result.getResultCode() == 404) { + testCreateDocument(); + } + // assertThat(result.getResultCode(), anyOf(equalTo(200), equalTo(412))); + // assertThat(result.getResult(), containsString("\"found\":true")); + + result = elasticSearch.updateDocument(TEST_INDEX_NAME, testDocument, false); + assertThat(result.getResultCode(), anyOf(equalTo(200), equalTo(412))); + + result = elasticSearch.getDocument(TEST_INDEX_NAME, testDocument); + assertThat(result.getResult(), containsString("test123")); + } + + @Test + public void testDeleteDocument() throws Exception { + OperationResult result = elasticSearch.getDocument(TEST_INDEX_NAME, testDocument); + if (result.getResultCode() == 404) { + testCreateDocument(); + } + + result = elasticSearch.deleteDocument(TEST_INDEX_NAME, testDocument); + assertThat(result.getResult(), containsString(TEST_INDEX_NAME)); + + result = elasticSearch.getDocument(TEST_INDEX_NAME, testDocument); + assertThat(result.getResult(), containsString("test123")); + } + + @Test + public void testBulkCreateDocuments() throws Exception { + for (int i = 0; i < 10; i++) { + AAIEntityTestObject doc = new AAIEntityTestObject(); + doc.setId("test-" + i); + doc.setEntityType("service-instance"); + doc.setEdgeTagQueryEntityFieldName("service-instance.service-instance-id"); + doc.setEdgeTagQueryEntityFieldValue("123456" + i); + doc.setSearchTagIDs("" + i); + doc.setSearchTags("service-instance-id"); + + OperationResult result = elasticSearch.createDocument(TEST_INDEX_NAME, doc, false); + assertThat(result.getResultCode(), anyOf(equalTo(201), equalTo(400))); + } + } + + @Test + public void serchByEntityType() throws Exception { + OperationResult result = elasticSearch.search(TEST_INDEX_NAME, "q=instance"); + assertThat(result.getResult(), not(equalTo(""))); + } + + @Test + public void serchByTagIDs() throws Exception { + OperationResult result = elasticSearch.search(TEST_INDEX_NAME, "q=9"); + assertThat(result.getResult(), not(equalTo(""))); + } + + @Test + public void serchByTags() throws Exception { + OperationResult result = elasticSearch.search(TEST_INDEX_NAME, "q=service"); + assertThat(result.getResult(), not(equalTo(""))); + } + + @Test + public void searchWithPayload() throws Exception { + testCreateIndex(); + OperationResult result = + elasticSearch.searchWithPayload(TEST_INDEX_NAME, "{\"query\":{\"term\":{\"user\":\"fred\"}}}"); + assertThat(result.getResult(), containsString("successful")); + assertThat(result.getResultCode(), is(equalTo(200))); + } + + /** + * The _suggest endpoint appears to be deprecated in ES 5.x and above. + */ + @Test + public void suggestionQueryWithPayload() throws Exception { + testCreateIndex(); + OperationResult result = elasticSearch.suggestionQueryWithPayload(TEST_INDEX_NAME, + "{\"my-suggestion\":{\"text\":\"fred\",\"term\":{\"field\":\"body\"}}}"); + assertThat(result.getResult(), containsString("error")); + assertThat(result.getResultCode(), is(equalTo(400))); + } + + @Test + public void testCreateDocumentWithoutId() throws Exception { + AAIEntityTestObject doc = new AAIEntityTestObject(); + doc.setEntityType("service-instance"); + doc.setEdgeTagQueryEntityFieldName("service-instance.service-instance-id"); + doc.setEdgeTagQueryEntityFieldValue("1111111"); + doc.setSearchTagIDs("321"); + doc.setSearchTags("service-instance-id"); + + OperationResult result = elasticSearch.createDocument(TEST_INDEX_NAME, doc, false); + assertThat(result.getResult(), not(equalTo(""))); + } + + @Test + public void testDeleteIndex() throws Exception { + OperationResult result = elasticSearch.deleteIndex(TEST_INDEX_NAME); + assertThat(result.getResultCode(), anyOf(equalTo(200), equalTo(404))); + assertThat(result.getResult(), not(equalTo(""))); + } + + class AAIEntityTestObject implements DocumentStoreDataEntity { + private String id; + private String entityType; + private String edgeTagQueryEntityFieldName; + private String edgeTagQueryEntityFieldValue; + private String searchTagIDs; + private String searchTags; + + public void setId(String id) { + this.id = id; + } + + @Override + public String getId() { + return this.id; + } + + public String getEntityType() { + return entityType; + } + + public void setEntityType(String entityType) { + this.entityType = entityType; + } + + public String getEdgeTagQueryEntityFieldName() { + return edgeTagQueryEntityFieldName; + } + + public void setEdgeTagQueryEntityFieldName(String edgeTagQueryEntityFieldName) { + this.edgeTagQueryEntityFieldName = edgeTagQueryEntityFieldName; + } + + public String getEdgeTagQueryEntityFieldValue() { + return edgeTagQueryEntityFieldValue; + } + + public void setEdgeTagQueryEntityFieldValue(String edgeTagQueryEntityFieldValue) { + this.edgeTagQueryEntityFieldValue = edgeTagQueryEntityFieldValue; + } + + public String getSearchTagIDs() { + return searchTagIDs; + } + + public void setSearchTagIDs(String searchTagIDs) { + this.searchTagIDs = searchTagIDs; + } + + public String getSearchTags() { + return searchTags; + } + + public void setSearchTags(String searchTags) { + this.searchTags = searchTags; + } + + @Override + public String getVersion() { + return "1"; + } + + @Override + public String getContentInJson() { + return new JSONObject(). // + put("entityType", entityType) // + .put("edgeTagQueryEntityFieldName", edgeTagQueryEntityFieldName) + .put("edgeTagQueryEntityFieldValue", edgeTagQueryEntityFieldValue) // + .put("searchTagIDs", searchTagIDs) // + .put("searchTags", searchTags) // + .toString(); + } + } + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchResultItemTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchResultItemTest.java new file mode 100644 index 0000000..eef7742 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/elasticsearch/dao/ElasticSearchResultItemTest.java @@ -0,0 +1,119 @@ +/** + * ============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.elasticsearch.dao; + +import org.junit.Assert; +import org.junit.Test; + +public class ElasticSearchResultItemTest { + + @Test + public void testAllMethods() { + ElasticSearchShardStatus shardStatus = new ElasticSearchShardStatus(); + shardStatus.setTotal(10); + shardStatus.setSuccessful(0); + shardStatus.setFailed(1); + Assert.assertEquals(shardStatus.getTotal(), 10); + Assert.assertEquals(shardStatus.getSuccessful(), 0); + Assert.assertEquals(shardStatus.getFailed(), 1); + + ElasticSearchCause cause = new ElasticSearchCause(); + cause.setType("type-1"); + cause.setReason("reason-1"); + Assert.assertEquals(cause.getType(), "type-1"); + Assert.assertEquals(cause.getReason(), "reason-1"); + + ElasticSearchError error = new ElasticSearchError(); + error.setType("type-1"); + error.setReason("reason-1"); + error.setCausedBy(cause); + Assert.assertEquals(error.getType(), "type-1"); + Assert.assertEquals(error.getReason(), "reason-1"); + Assert.assertNotNull(error.getCausedBy()); + error.setAdditionalProperties("name-1", "value-1"); + Assert.assertNotNull(error.getAdditionalProperties()); + + // Create Status + ElasticSearchResultItem resultItem1 = new ElasticSearchResultItem(); + resultItem1.setCreate(getStatus(shardStatus, error)); + Assert.assertNotNull(resultItem1.getCreate()); + Assert.assertEquals(resultItem1.operationType(), "create"); + Assert.assertEquals(resultItem1.operationStatus(), resultItem1.getCreate()); + Assert.assertTrue(resultItem1.toString().contains("create")); + Assert.assertNotNull(resultItem1.toJson()); + + // Index Status + ElasticSearchResultItem resultItem2 = new ElasticSearchResultItem(); + resultItem2.setIndex(getStatus(shardStatus, error)); + Assert.assertNotNull(resultItem2.getIndex()); + Assert.assertEquals(resultItem2.operationType(), "update"); + Assert.assertEquals(resultItem2.operationStatus(), resultItem2.getIndex()); + Assert.assertTrue(resultItem2.toString().contains("index")); + Assert.assertNotNull(resultItem2.toJson()); + + // Delete Status + ElasticSearchResultItem resultItem3 = new ElasticSearchResultItem(); + resultItem3.setDelete(getStatus(shardStatus, error)); + Assert.assertNotNull(resultItem3.getDelete()); + Assert.assertEquals(resultItem3.operationType(), "delete"); + Assert.assertEquals(resultItem3.operationStatus(), resultItem3.getDelete()); + Assert.assertTrue(resultItem3.toString().contains("delete")); + Assert.assertNotNull(resultItem3.toJson()); + + // Unknown Status + ElasticSearchResultItem resultItem4 = new ElasticSearchResultItem(); + Assert.assertEquals(resultItem4.operationType(), "unknown"); + Assert.assertNull(resultItem4.operationStatus()); + + // ElasticSearchBulkOperationResult + ElasticSearchResultItem[] resultItems = {resultItem1, resultItem2, resultItem3}; + ElasticSearchBulkOperationResult result = new ElasticSearchBulkOperationResult(); + result.setErrors(true); + result.setTook(new Integer(10)); + result.setItems(resultItems); + Assert.assertTrue(result.getErrors()); + Assert.assertEquals(result.getTook(), new Integer(10)); + Assert.assertNotNull(result.getItems()); + Assert.assertNotNull(result.toString()); + } + + private ElasticSearchOperationStatus getStatus(ElasticSearchShardStatus shardStatus, ElasticSearchError error) { + ElasticSearchOperationStatus status = new ElasticSearchOperationStatus(); + status.setIndex("index-1"); + status.setType("type-1"); + status.setId("id-1"); + status.setVersion("1.0"); + status.setShards(shardStatus); + status.setStatus(new Integer(1)); + status.setError(error); + status.setAdditionalProperties("REQUEST_URL", "http://127.0.0.1"); + Assert.assertEquals(status.getIndex(), "index-1"); + Assert.assertEquals(status.getType(), "type-1"); + Assert.assertEquals(status.getId(), "id-1"); + Assert.assertEquals(status.getVersion(), "1.0"); + Assert.assertEquals(status.getStatus(), new Integer(1)); + Assert.assertNotNull(status.getShards()); + Assert.assertNotNull(status.getError()); + Assert.assertNotNull(status.getAdditionalProperties()); + return status; + } + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/AggregationStatementTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/AggregationStatementTest.java new file mode 100644 index 0000000..bff0f4f --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/AggregationStatementTest.java @@ -0,0 +1,154 @@ +/** + * ============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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +public class AggregationStatementTest { + + private static ObjectMapper mapper = new ObjectMapper(); + + @Test + public void testGroupBy() { + String input = "{\r\n \"group-by\": {\r\n \"field\": \"entityType\"\r\n }\r\n }"; + + String expected = "{\"terms\": {\"field\": \"entityType\"}}"; + + AggregationStatement actual; + try { + actual = mapper.readValue(input, AggregationStatement.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + + } + + @Test + public void testDateRange() { + String input = + "{\r\n \"date-range\": {\r\n \"field\": \"mydate\",\r\n \"ranges\": [\r\n {\r\n \"from\": \"2016-12-19T00:00:00.738-05:00\",\r\n \"to\": \"2016-12-23T23:59:59.738-05:00\"\r\n }\r\n ],\r\n \"format\": \"MM-yyy\",\r\n \"size\": \"5\"\r\n }\r\n}"; + + String expected = + "{\"date_range\": {\"field\": \"mydate\", \"format\": \"MM-yyy\", \"ranges\": [{\"from\": \"2016-12-19T00:00:00.738-05:00\", \"to\": \"2016-12-23T23:59:59.738-05:00\"}], \"size\": 5}}"; + + AggregationStatement actual; + try { + actual = mapper.readValue(input, AggregationStatement.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + + } + + @Test + public void testDateHistogram() { + String input = + "{\r\n \"date-histogram\": {\r\n \"field\": \"mydate\",\r\n \"interval\": \"day\"\r\n }\r\n}"; + + String expected = "{\"date_histogram\": {\"field\": \"mydate\", \"interval\": \"day\"}}"; + + AggregationStatement actual; + try { + actual = mapper.readValue(input, AggregationStatement.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + + } + + @Test + public void testSubAggregation1() { + String input = + "{\r\n \"group-by\": {\r\n \"field\": \"severity\"\r\n },\r\n \"sub-aggregations\": [\r\n {\r\n \"name\": \"byType\",\r\n \"aggregation\": {\r\n \"group-by\": {\r\n \"field\": \"entityType\"\r\n }\r\n }\r\n }\r\n ]\r\n}"; + String expected = + "{\"terms\": {\"field\": \"severity\"}, \"aggs\": {\"byType\": {\"terms\": {\"field\": \"entityType\"}}}}"; + + AggregationStatement actual; + try { + actual = mapper.readValue(input, AggregationStatement.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + + } + + @Test + public void testSubAggregation2() { + String input = + "{\r\n \"group-by\": {\r\n \"field\": \"severity\"\r\n },\r\n \"sub-aggregations\": [\r\n {\r\n \"name\": \"byType\",\r\n \"aggregation\": {\r\n \"group-by\": {\r\n \"field\": \"violationType\"\r\n }\r\n }\r\n },\r\n {\r\n \"name\": \"byRule\",\r\n \"aggregation\": {\r\n \"group-by\": {\r\n \"field\": \"validationRule\"\r\n }\r\n }\r\n }\r\n ]\r\n}"; + String expected = + "{\"terms\": {\"field\": \"severity\"}, \"aggs\": {\"byType\": {\"terms\": {\"field\": \"violationType\"}},\"byRule\": {\"terms\": {\"field\": \"validationRule\"}}}}"; + + AggregationStatement actual; + try { + actual = mapper.readValue(input, AggregationStatement.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + + } + + + @Test + public void testNestedAggregation1() { + String input = + "{\r\n \"nested\": [{\r\n \"name\": \"by_severity\",\r\n \"aggregation\": {\r\n \"group-by\": {\r\n \"field\": \"violations.severity\"\r\n }\r\n }\r\n }]\r\n}"; + String expected = + "{\"nested\": {\"path\": \"violations\"}, \"aggs\": {\"by_severity\": {\"terms\": {\"field\": \"violations.severity\"}}}}"; + + AggregationStatement actual; + try { + actual = mapper.readValue(input, AggregationStatement.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + + } + + @Test + public void testNestedAggregation2() { + String input = + "{\r\n \"nested\": [\r\n {\r\n \"name\": \"by_severity\",\r\n \"aggregation\": {\r\n \"group-by\": {\r\n \"field\": \"violations.severity\"\r\n }\r\n }\r\n },\r\n {\r\n \"name\": \"by_type\",\r\n \"aggregation\": {\r\n \"group-by\": {\r\n \"field\": \"violations.violationType\"\r\n }\r\n }\r\n }\r\n ]\r\n}"; + String expected = + "{\"nested\": {\"path\": \"violations\"}, \"aggs\": {\"by_severity\": {\"terms\": {\"field\": \"violations.severity\"}},\"by_type\": {\"terms\": {\"field\": \"violations.violationType\"}}}}"; + + AggregationStatement actual; + try { + actual = mapper.readValue(input, AggregationStatement.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + + } + + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/AggregationTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/AggregationTest.java new file mode 100644 index 0000000..12b18d1 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/AggregationTest.java @@ -0,0 +1,51 @@ +/** + * ============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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +public class AggregationTest { + private static ObjectMapper mapper = new ObjectMapper(); + + // + @Test + public void test() { + String input = + "{\r\n \"name\": \"byDate\",\r\n \"aggregation\": {\r\n \"date-range\": {\r\n \"field\": \"mydate\",\r\n \"ranges\": [\r\n {\r\n \"from\": \"2016-12-19T00:00:00.738-05:00\",\r\n \"to\": \"2016-12-23T23:59:59.738-05:00\"\r\n }\r\n ]\r\n },\r\n \"sub-aggregations\": [{\r\n \"name\": \"byTerm\",\r\n \"aggregation\": {\r\n \"group-by\": {\r\n \"field\": \"myterm\"\r\n }\r\n }\r\n }]\r\n }\r\n}"; + + String expected = + "\"byDate\": {\"date_range\": {\"field\": \"mydate\", \"ranges\": [{\"from\": \"2016-12-19T00:00:00.738-05:00\", \"to\": \"2016-12-23T23:59:59.738-05:00\"}]}, \"aggs\": {\"byTerm\": {\"terms\": {\"field\": \"myterm\"}}}}"; + + Aggregation actual; + try { + actual = mapper.readValue(input, Aggregation.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + + } + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateHistogramAggregationTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateHistogramAggregationTest.java new file mode 100644 index 0000000..005cb76 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateHistogramAggregationTest.java @@ -0,0 +1,78 @@ +/** + * ============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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +public class DateHistogramAggregationTest { + ObjectMapper mapper = new ObjectMapper(); + + @Test + public void testFullSet() { + String input = "{\r\n \"field\": \"mydate\",\r\n \"interval\": \"day\",\r\n \"time-zone\": \"-01:00\"\r\n}"; + + String expected = + "\"date_histogram\": {\"field\": \"mydate\", \"interval\": \"day\", \"time_zone\": \"-01:00\"}"; + + DateHistogramAggregation actual; + try { + actual = mapper.readValue(input, DateHistogramAggregation.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + } + + @Test + public void test2() { + String input = "{\r\n \"field\": \"mydate\",\r\n \"interval\": \"day\"\r\n}"; + + String expected = "\"date_histogram\": {\"field\": \"mydate\", \"interval\": \"day\"}"; + + DateHistogramAggregation actual; + try { + actual = mapper.readValue(input, DateHistogramAggregation.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + } + + @Test + public void test3() { + String input = "{\r\n \"field\": \"mydate\"\r\n}"; + + String expected = "\"date_histogram\": {\"field\": \"mydate\"}"; + + DateHistogramAggregation actual; + try { + actual = mapper.readValue(input, DateHistogramAggregation.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + } + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateRangeAggregationTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateRangeAggregationTest.java new file mode 100644 index 0000000..45e7c51 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateRangeAggregationTest.java @@ -0,0 +1,69 @@ +/** + * ============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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +public class DateRangeAggregationTest { + + private static ObjectMapper mapper = new ObjectMapper(); + + + @Test + public void test() { + + String input = + "{\r\n \"field\": \"mydate\",\r\n \"ranges\": [\r\n {\r\n \"from\": \"2016-12-19T00:00:00.738-05:00\",\r\n \"to\": \"2016-12-23T23:59:59.738-05:00\"\r\n },\r\n {\r\n \"to\": \"2016-12-23T23:59:59.738-05:00\"\r\n },\r\n {\r\n \"from\": \"2016-12-19T00:00:00.738-05:00\"\r\n }\r\n ],\r\n \"format\": \"MM-yyy\",\r\n \"size\": \"5\"\r\n}"; + String expected = + "\"date_range\": {\"field\": \"mydate\", \"format\": \"MM-yyy\", \"ranges\": [{\"from\": \"2016-12-19T00:00:00.738-05:00\", \"to\": \"2016-12-23T23:59:59.738-05:00\"},{\"to\": \"2016-12-23T23:59:59.738-05:00\"},{\"from\": \"2016-12-19T00:00:00.738-05:00\"}], \"size\": 5}"; + + DateRangeAggregation actual; + try { + actual = mapper.readValue(input, DateRangeAggregation.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + } + + @Test + public void testNoFormatNoSize() { + + String input = + "{\r\n \"field\": \"mydate\",\r\n \"ranges\": [\r\n {\r\n \"from\": \"2016-12-19T00:00:00.738-05:00\",\r\n \"to\": \"2016-12-23T23:59:59.738-05:00\"\r\n },\r\n {\r\n \"to\": \"2016-12-23T23:59:59.738-05:00\"\r\n },\r\n {\r\n \"from\": \"2016-12-19T00:00:00.738-05:00\"\r\n }\r\n ]\r\n}"; + String expected = + "\"date_range\": {\"field\": \"mydate\", \"ranges\": [{\"from\": \"2016-12-19T00:00:00.738-05:00\", \"to\": \"2016-12-23T23:59:59.738-05:00\"},{\"to\": \"2016-12-23T23:59:59.738-05:00\"},{\"from\": \"2016-12-19T00:00:00.738-05:00\"}]}"; + + DateRangeAggregation actual; + try { + actual = mapper.readValue(input, DateRangeAggregation.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + } + + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateRangeTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateRangeTest.java new file mode 100644 index 0000000..ef7325e --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/DateRangeTest.java @@ -0,0 +1,75 @@ +/** + * ============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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +public class DateRangeTest { + private static ObjectMapper mapper = new ObjectMapper(); + + @Test + public void testBoth() { + String input = + "{\r\n \"from\": \"2016-12-19T00:00:00.738-05:00\",\r\n \"to\": \"2016-12-23T23:59:59.738-05:00\"\r\n}"; + String expected = "{\"from\": \"2016-12-19T00:00:00.738-05:00\", \"to\": \"2016-12-23T23:59:59.738-05:00\"}"; + + DateRange actual; + try { + actual = mapper.readValue(input, DateRange.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + } + + @Test + public void testFrom() { + String input = "{\"from\": \"2016-12-19T00:00:00.738-05:00\"}"; + String expected = "{\"from\": \"2016-12-19T00:00:00.738-05:00\"}"; + + DateRange actual; + try { + actual = mapper.readValue(input, DateRange.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + } + + @Test + public void testTo() { + String input = "{\r\n \"to\": \"2016-12-23T23:59:59.738-05:00\"\r\n}"; + String expected = "{\"to\": \"2016-12-23T23:59:59.738-05:00\"}"; + + DateRange actual; + try { + actual = mapper.readValue(input, DateRange.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + } + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/FilterTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/FilterTest.java new file mode 100644 index 0000000..81fa07f --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/FilterTest.java @@ -0,0 +1,43 @@ +/** + * ============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 com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import org.junit.Test; + +public class FilterTest { + + @Test + public void test() throws JsonParseException, JsonMappingException, IOException { + + + String json = "{ \"any\": [ " + "{\"match\": {\"field\": \"searchTags\", \"value\": \"a\"}}," + + "{\"match\": {\"field\": \"searchTags\", \"value\": \"b\"}}" + "]," + "\"all\": [" + + "{\"parsed-query\": {\"field\": \"fieldname\", \"query-string\": \"string\"}}" + "]" + "}"; + + ObjectMapper mapper = new ObjectMapper(); + Filter filter = mapper.readValue(json, Filter.class); + System.out.println("GDF: filter = " + filter); + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/GroupByAggregationTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/GroupByAggregationTest.java new file mode 100644 index 0000000..1ebed91 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/GroupByAggregationTest.java @@ -0,0 +1,62 @@ +/** + * ============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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.Test; + +public class GroupByAggregationTest { + private static ObjectMapper mapper = new ObjectMapper(); + + @Test + public void test() { + String input = "{\"field\" : \"entityType\", \"size\": 20}\r\n"; + + String expected = "\"terms\": {\"field\": \"entityType\", \"size\": 20}"; + + GroupByAggregation actual; + try { + actual = mapper.readValue(input, GroupByAggregation.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + } + + @Test + public void testNoSize() { + String input = "{\"field\" : \"entityType\"}\r\n"; + + String expected = "\"terms\": {\"field\": \"entityType\"}"; + + GroupByAggregation actual; + try { + actual = mapper.readValue(input, GroupByAggregation.class); + assertEquals(expected, actual.toElasticSearch()); + } catch (Exception e) { + fail("Exception occurred: " + e.getMessage()); + } + } + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/QueryTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/QueryTest.java new file mode 100644 index 0000000..1f4887f --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/QueryTest.java @@ -0,0 +1,368 @@ +/** + * ============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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import org.junit.Test; + +public class QueryTest { + + /** + * This test validates that we are able to marshal json structures representing term queries into POJOs and that we + * can then unmarshal those POJOs into ElasticSearch syntax. + * + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + @Test + public void termQueryTest() throws JsonParseException, JsonMappingException, IOException { + + Integer intValue = 1; + String field = "searchTags"; + String termQueryWithIntegerValueJson = "{\"field\": \"" + field + "\", \"value\": " + intValue + "}"; + String termQueryWithIntegerValueExpectedES = "{\"term\": {\"" + field + "\" : " + intValue + "}}"; + + Double doubleValue = 5.7; + String termQueryWithDoubleValueJson = "{\"field\": \"" + field + "\", \"value\": " + doubleValue + "}"; + String termQueryWithDoubleValueExpectedES = "{\"term\": {\"" + field + "\" : " + doubleValue + "}}"; + + String stringValue = "theValue"; + String termQueryWithStringValueJson = "{\"field\": \"" + field + "\", \"value\": \"" + stringValue + "\"}"; + String termQueryWithStringValueExpectedES = "{\"term\": {\"" + field + "\" : \"" + stringValue + "\"}}"; + + ObjectMapper mapper = new ObjectMapper(); + + + // Validate that we can marshal a term query where the supplied value + // is an Integer. + TermQuery integerTermQuery = mapper.readValue(termQueryWithIntegerValueJson, TermQuery.class); + assertTrue( + "Expected value to be of type Integer, but was type " + + integerTermQuery.getValue().getClass().getName(), + integerTermQuery.getValue() instanceof Integer); + assertEquals(intValue, integerTermQuery.getValue()); + + assertTrue("ElasticSearch term query translation does not match the expected result", + termQueryWithIntegerValueExpectedES.equals(integerTermQuery.toElasticSearch())); + + // Validate that we can marshal a term query where the supplied value + // is a Double. + TermQuery doubleTermQuery = mapper.readValue(termQueryWithDoubleValueJson, TermQuery.class); + assertTrue( + "Expected value to be of type Double, but was type " + doubleTermQuery.getValue().getClass().getName(), + doubleTermQuery.getValue() instanceof Double); + assertEquals(doubleValue, doubleTermQuery.getValue()); + assertTrue("ElasticSearch term query translation does not match the expected result", + termQueryWithDoubleValueExpectedES.equals(doubleTermQuery.toElasticSearch())); + + // Validate that we can marshal a term query where the supplied value + // is a String literal. + TermQuery stringTermQuery = mapper.readValue(termQueryWithStringValueJson, TermQuery.class); + assertTrue( + "Expected value to be of type String, but was type " + stringTermQuery.getValue().getClass().getName(), + stringTermQuery.getValue() instanceof String); + assertEquals(stringValue, stringTermQuery.getValue()); + assertTrue("ElasticSearch term query translation does not match the expected result", + termQueryWithStringValueExpectedES.equals(stringTermQuery.toElasticSearch())); + + + } + + + /** + * This test validates that we are able to marshal json structures representing parsed queries into POJOs and that + * we can then unmarshal those POJOs into ElasticSearch syntax. + * + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + @Test + public void parsedQueryTest() throws JsonParseException, JsonMappingException, IOException { + + String field = "fieldname"; + String queryString = "The query string"; + + String queryJson = "{\"field\": \"" + field + "\", \"query-string\": \"" + queryString + "\"}"; + String queryExpectedES = + "{\"query_string\": {\"default_field\": \"" + field + "\", \"query\": \"" + queryString + "\"}}"; + + ObjectMapper mapper = new ObjectMapper(); + ParsedQuery pq = mapper.readValue(queryJson, ParsedQuery.class); + + assertTrue("Unexpected marshalled value for 'field' - expected: " + field + " actual: " + pq.getField(), + field.equals(pq.getField())); + assertTrue("Unexpected marshalled value for 'query-string' - expected: " + queryString + " actual: " + + pq.getQueryString(), queryString.equals(pq.getQueryString())); + assertTrue( + "Unexpected ElasticSearch syntax. Expected: " + queryExpectedES + " Actual: " + pq.toElasticSearch(), + queryExpectedES.equals(pq.toElasticSearch())); + } + + + /** + * This test validates that a ranged query cannot be parsed with values for both the 'gte' and 'gt' fields or the + * 'lte' and 'lt' fields, and that we do not allow mixing of numeric and date types in the same query. + * + * @throws JsonParseException + * @throws IOException + */ + @Test + public void rangeQueryConflictingBoundsTest() throws JsonParseException, IOException { + + String invalidGTAndGTE = + "{ \"field\": \"timestamp\", \"gte\": \"2016-10-06T00:00:00.558+03:00\", \"gt\": \"2016-10-06T23:59:59.558+03:00\"}"; + String invalidLTAndLTE = + "{ \"field\": \"timestamp\", \"lte\": \"2016-10-06T00:00:00.558+03:00\", \"lt\": \"2016-10-06T23:59:59.558+03:00\"}"; + String invalidTypes = "{ \"field\": \"timestamp\", \"lte\": 5, \"gte\": \"2016-10-06T23:59:59.558+03:00\"}"; + + ObjectMapper mapper = new ObjectMapper(); + + // Attempt to parse a query where we are setting values for both the + // 'greater than' and 'greater than and equal to' operators. + boolean gotExpectedException = false; + try { + mapper.readValue(invalidGTAndGTE, RangeQuery.class); + } catch (JsonMappingException e) { + gotExpectedException = true; + } + assertTrue("Attempting to set both a 'gt' and 'gte' value on the same query should not have been allowed", + gotExpectedException); + + // Attempt to parse a query where we are setting values for both the + // 'less than' and 'less than and equal to' operators. + gotExpectedException = false; + try { + mapper.readValue(invalidLTAndLTE, RangeQuery.class); + } catch (JsonMappingException e) { + gotExpectedException = true; + } + assertTrue("Attempting to set both a 'lt' and 'lte' value on the same query should not have been allowed", + gotExpectedException); + + // Attempt to parse a query where we are mixing numeric and date values + // in the same query. + gotExpectedException = false; + try { + mapper.readValue(invalidTypes, RangeQuery.class); + } catch (JsonMappingException e) { + gotExpectedException = true; + } + assertTrue("Attempting to mix numeric and date values in the same query should not have been allowed", + gotExpectedException); + + + } + + + /** + * This test validates that date range queries can be marshalled to a Java POJO and unmarshalled to ElasticSearch + * syntax. + * + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + @Test + public void dateRangeQueryTest() throws JsonParseException, JsonMappingException, IOException { + + String field = "timestamp"; + String greaterThanDate = "2016-10-06T00:00:00.558+03:00"; + String lessThanDate = "2016-10-06T23:59:59.558+03:00"; + + ObjectMapper mapper = new ObjectMapper(); + + // Generate a date range query using 'greater than or equal' and 'less + // than or equal' operations. + String dateRangeJson = "{ \"field\": \"" + field + "\", \"gte\": \"" + greaterThanDate + "\", \"lte\": \"" + + lessThanDate + "\"}"; + String dateRangeExpectedES = + "{\"range\": {\"timestamp\": {\"gte\": \"2016-10-06T00:00:00.558+03:00\", \"lte\": \"2016-10-06T23:59:59.558+03:00\"}}}"; + + // Validate that the query is marshalled correctly to the POJO and that + // the generated ElasticSearch syntax looks as expected. + RangeQuery dateRangeQuery = mapper.readValue(dateRangeJson, RangeQuery.class); + + assertTrue("Unexpected marshalled value for 'field'. Expected: " + field + " Actual: " + + dateRangeQuery.getField(), field.equals(dateRangeQuery.getField())); + assertTrue("Unexpected type for 'gte' value. Expected: String Actual: " + + dateRangeQuery.getGte().getClass().getName(), dateRangeQuery.getGte() instanceof String); + assertTrue("Unexpected type for 'lte' value. Expected: String Actual: " + + dateRangeQuery.getLte().getClass().getName(), dateRangeQuery.getLte() instanceof String); + assertTrue("Unexpected marshalled value for 'gte'. Expected: " + greaterThanDate + " Actual: " + + dateRangeQuery.getGte(), greaterThanDate.equals(dateRangeQuery.getGte())); + assertTrue("Unexpected marshalled value for 'lte'. Expected: " + lessThanDate + " Actual: " + + dateRangeQuery.getLte(), lessThanDate.equals(dateRangeQuery.getLte())); + assertTrue( + "Unexpected ElasticSearch syntax. Expected: " + dateRangeExpectedES + " Actual: " + + dateRangeQuery.toElasticSearch(), + dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch())); + + + // Generate a date range query using 'greater than' and 'less than or + // equal' operations. + dateRangeJson = "{ \"field\": \"" + field + "\", \"gt\": \"" + greaterThanDate + "\", \"lte\": \"" + + lessThanDate + "\"}"; + dateRangeExpectedES = + "{\"range\": {\"timestamp\": {\"gt\": \"2016-10-06T00:00:00.558+03:00\", \"lte\": \"2016-10-06T23:59:59.558+03:00\"}}}"; + + // Validate that the query is marshalled correctly to the POJO and that + // the generated ElasticSearch syntax looks as expected. + dateRangeQuery = mapper.readValue(dateRangeJson, RangeQuery.class); + + assertTrue("Unexpected marshalled value for 'field'. Expected: " + field + " Actual: " + + dateRangeQuery.getField(), field.equals(dateRangeQuery.getField())); + + assertTrue("Unexpected type for 'gt' value. Expected: String Actual: " + + dateRangeQuery.getGt().getClass().getName(), dateRangeQuery.getGt() instanceof String); + + assertTrue("Unexpected type for 'lte' value. Expected: String Actual: " + + dateRangeQuery.getLte().getClass().getName(), dateRangeQuery.getLte() instanceof String); + + assertTrue("Unexpected marshalled value for 'gt'. Expected: " + greaterThanDate + " Actual: " + + dateRangeQuery.getGt(), greaterThanDate.equals(dateRangeQuery.getGt())); + + assertTrue("Unexpected marshalled value for 'lte'. Expected: " + lessThanDate + " Actual: " + + dateRangeQuery.getLte(), lessThanDate.equals(dateRangeQuery.getLte())); + + assertTrue( + "Unexpected ElasticSearch syntax. Expected: " + dateRangeExpectedES + " Actual: " + + dateRangeQuery.toElasticSearch(), + dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch())); + + + // Generate a date range query using only a 'greater than' operation. + dateRangeJson = "{ \"field\": \"" + field + "\", \"gt\": \"" + greaterThanDate + "\"}"; + dateRangeExpectedES = "{\"range\": {\"timestamp\": {\"gt\": \"2016-10-06T00:00:00.558+03:00\"}}}"; + + // Validate that the query is marshalled correctly to the POJO and that + // the generated ElasticSearch syntax looks as expected. + dateRangeQuery = mapper.readValue(dateRangeJson, RangeQuery.class); + + assertTrue("Unexpected marshalled value for 'field'. Expected: " + field + " Actual: " + + dateRangeQuery.getField(), field.equals(dateRangeQuery.getField())); + + assertTrue("Unexpected type for 'gt' value. Expected: String Actual: " + + dateRangeQuery.getGt().getClass().getName(), dateRangeQuery.getGt() instanceof String); + + assertTrue("Unexpected marshalled value for 'gt'. Expected: " + greaterThanDate + " Actual: " + + dateRangeQuery.getGt(), greaterThanDate.equals(dateRangeQuery.getGt())); + + assertTrue( + "Unexpected ElasticSearch syntax. Expected: " + dateRangeExpectedES + " Actual: " + + dateRangeQuery.toElasticSearch(), + dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch())); + + } + + /** + * This test validates that numeric range queries can be marshalled to a Java POJO and unmarshalled to ElasticSearch + * syntax. + * + * @throws JsonParseException + * @throws JsonMappingException + * @throws IOException + */ + @Test + public void numericRangeQueryTest() throws JsonParseException, JsonMappingException, IOException { + + String field = "version"; + Integer greaterThanInt = 5; + Integer lessThanInt = 100; + + ObjectMapper mapper = new ObjectMapper(); + + // Generate a numeric range query using 'greater than or equal' and 'less + // than or equal' operations. + String numericRangeJson = + "{ \"field\": \"" + field + "\", \"gte\": " + greaterThanInt + ", \"lte\": " + lessThanInt + "}"; + String numericRangeExpectedES = + "{\"range\": {\"" + field + "\": {\"gte\": " + greaterThanInt + ", \"lte\": " + lessThanInt + "}}}"; + + // Validate that the query is marshalled correctly to the POJO and that + // the generated ElasticSearch syntax looks as expected. + RangeQuery numericRangeQuery = mapper.readValue(numericRangeJson, RangeQuery.class); + + assertTrue("Unexpected marshalled value for 'field'. Expected: " + field + " Actual: " + + numericRangeQuery.getField(), field.equals(numericRangeQuery.getField())); + assertTrue( + "Unexpected type for 'gte' value. Expected: Integer Actual: " + + numericRangeQuery.getGte().getClass().getName(), + numericRangeQuery.getGte() instanceof Integer); + assertTrue( + "Unexpected type for 'lte' value. Expected: Integer Actual: " + + numericRangeQuery.getLte().getClass().getName(), + numericRangeQuery.getLte() instanceof Integer); + assertEquals("Unexpected marshalled value for 'gte'. Expected: " + greaterThanInt + " Actual: " + + numericRangeQuery.getGte(), greaterThanInt, numericRangeQuery.getGte()); + assertEquals("Unexpected marshalled value for 'lte'. Expected: " + lessThanInt + " Actual: " + + numericRangeQuery.getLte(), lessThanInt, numericRangeQuery.getLte()); + assertTrue( + "Unexpected ElasticSearch syntax. Expected: " + numericRangeExpectedES + " Actual: " + + numericRangeQuery.toElasticSearch(), + numericRangeExpectedES.equals(numericRangeQuery.toElasticSearch())); + + + Double greaterThanDouble = 5.0; + Double lessThanDouble = 100.0; + + // Generate a date range query using 'greater than' and 'less than or + // equal' operations. + numericRangeJson = + "{ \"field\": \"" + field + "\", \"gt\": " + greaterThanDouble + ", \"lte\": " + lessThanDouble + "}"; + numericRangeExpectedES = "{\"range\": {\"" + field + "\": {\"gt\": " + greaterThanDouble + ", \"lte\": " + + lessThanDouble + "}}}"; + + // Validate that the query is marshalled correctly to the POJO and that + // the generated ElasticSearch syntax looks as expected. + numericRangeQuery = mapper.readValue(numericRangeJson, RangeQuery.class); + + assertTrue("Unexpected marshalled value for 'field'. Expected: " + field + " Actual: " + + numericRangeQuery.getField(), field.equals(numericRangeQuery.getField())); + + assertTrue("Unexpected type for 'gt' value. Expected: Double Actual: " + + numericRangeQuery.getGt().getClass().getName(), numericRangeQuery.getGt() instanceof Double); + + assertTrue( + "Unexpected type for 'lte' value. Expected: Double Actual: " + + numericRangeQuery.getLte().getClass().getName(), + numericRangeQuery.getLte() instanceof Double); + + assertEquals("Unexpected marshalled value for 'gt'. Expected: " + greaterThanDouble + " Actual: " + + numericRangeQuery.getGt(), greaterThanDouble, numericRangeQuery.getGt()); + + assertEquals("Unexpected marshalled value for 'lte'. Expected: " + lessThanDouble + " Actual: " + + numericRangeQuery.getLte(), lessThanDouble, numericRangeQuery.getLte()); + + assertTrue( + "Unexpected ElasticSearch syntax. Expected: " + numericRangeExpectedES + " Actual: " + + numericRangeQuery.toElasticSearch(), + numericRangeExpectedES.equals(numericRangeQuery.toElasticSearch())); + } + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/RangeQueryTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/RangeQueryTest.java new file mode 100644 index 0000000..e58e545 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/RangeQueryTest.java @@ -0,0 +1,155 @@ +/** + * ============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 static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.IOException; +import org.junit.Assert; +import org.junit.Test; +import org.onap.aai.sa.rest.TestUtils; + +public class RangeQueryTest { + + static { + // Set the location of the payload translation JSON file. + System.setProperty("CONFIG_HOME", "src/test/resources/json"); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetGt() { + RangeQuery rq = new RangeQuery(); + rq.setLt(new String("2x")); + Assert.assertEquals("2x", rq.getLt()); + Assert.assertNotNull(rq.toElasticSearch()); + Assert.assertNotNull(rq.toString()); + rq.setGt(new Integer(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetGte() { + RangeQuery rq = new RangeQuery(); + rq.setGt(new Integer(1)); + Assert.assertNotNull(rq.toElasticSearch()); + Assert.assertNotNull(rq.toString()); + rq.setGte(new Integer(1)); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetLt() { + RangeQuery rq = new RangeQuery(); + rq.setLt(new Integer(1)); + rq.setFormat("format-1"); + assertThat(rq.getFormat(), is(equalTo("format-1"))); + Assert.assertNotNull(rq.toElasticSearch()); + Assert.assertNotNull(rq.toString()); + + rq.setGt(new Integer(1)); + Assert.assertNotNull(rq.toElasticSearch()); + Assert.assertNotNull(rq.toString()); + rq.setLt(new String("10")); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetLte() { + RangeQuery rq = new RangeQuery(); + rq.setGt(new Integer(1)); + rq.setTimeZone("CT"); + assertThat(rq.getTimeZone(), is(equalTo("CT"))); + Assert.assertNotNull(rq.toElasticSearch()); + Assert.assertNotNull(rq.toString()); + + rq.setLte(new String("10")); + } + + @Test + public void testSearchStatementAggregations() throws IOException { + File queryWithSubrangeFile = new File("src/test/resources/json/queries/query-with-subrange.json"); + String queryWithSubrangeStr = TestUtils.readFileToString(queryWithSubrangeFile); + + ObjectMapper mapper = new ObjectMapper(); + SearchStatement ss = mapper.readValue(queryWithSubrangeStr, SearchStatement.class); + + Aggregation a1 = getAggregationObject(); + Aggregation a2 = getAggregationObject(); + Aggregation[] aggs = new Aggregation[] {a1, a2}; + ss.setAggregations(aggs); + Assert.assertNotNull(ss.toString()); + } + + private Aggregation getAggregationObject() { + Aggregation a = new Aggregation(); + + AggregationStatement as = new AggregationStatement(); + DateHistogramAggregation dha = new DateHistogramAggregation(); + dha.setField("field-1"); + dha.setInterval("interval-1"); + assertThat(dha.getInterval(), is(equalTo("interval-1"))); + dha.setTimeZone("CT"); + assertThat(dha.getTimeZone(), is(equalTo("CT"))); + dha.setFormat("format-1"); + assertThat(dha.getFormat(), is(equalTo("format-1"))); + dha.setSize(10); + dha.setMinThreshold(1); + Assert.assertNotNull(dha.toElasticSearch()); + Assert.assertNotNull(dha.toString()); + as.setDateHist(dha); + as.toString(); + + as.getNestedPath(); + + DateRangeAggregation dra = new DateRangeAggregation(); + dra.setField("field-1"); + dra.setMinThreshold(1); + dra.setFormat("format-1"); + assertThat(dra.getFormat(), is(equalTo("format-1"))); + DateRange dr = new DateRange(); + dr.setFromDate("01-12-2017"); + assertThat(dr.getFromDate(), is(equalTo("01-12-2017"))); + dr.setToDate("21-12-2017"); + assertThat(dr.getToDate(), is(equalTo("21-12-2017"))); + DateRange[] drs = {dr}; + dra.setDateRanges(drs); + Assert.assertTrue(dra.getDateRanges().length == 1); + Assert.assertNotNull(dra.toElasticSearch()); + Assert.assertNotNull(dra.toString()); + as.setDateRange(dra); + as.toString(); + + as.getNestedPath(); + + GroupByAggregation gba = new GroupByAggregation(); + gba.setField("field-1"); + gba.setMinThreshold(1); + Assert.assertNotNull(gba.toElasticSearch()); + Assert.assertNotNull(gba.toString()); + as.setGroupBy(gba); + Assert.assertNotNull(as.toString()); + + a.setStatement(as); + Assert.assertNotNull(a.toString()); + return a; + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/SearchStatementTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/SearchStatementTest.java new file mode 100644 index 0000000..45ad666 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/SearchStatementTest.java @@ -0,0 +1,211 @@ +/** + * ============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 static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.File; +import java.io.IOException; +import org.junit.Test; +import org.onap.aai.sa.rest.TestUtils; + +public class SearchStatementTest { + + @Test + public void simpleQueryTest() throws JsonParseException, JsonMappingException, IOException { + + String field = "searchTags"; + String queryString = "aai3255"; + String queryJson = "{" + "\"queries\": [" + "{\"may\": {\"parsed-query\": {" + "\"field\": \"" + field + "\"," + + "\"query-string\": \"" + queryString + "\"}}}" + "]" + "}" + "}"; + + String queryES = "{" + "\"version\": true," + "\"query\": {" + "\"bool\": {" + "\"must\": [], " + + "\"should\": [" + "{\"query_string\": {\"default_field\": \"searchTags\", \"query\": \"aai3255\"}}" + + "]," + "\"must_not\": []}" + "}" + "}"; + + // Marshal our simple query JSON to a SearchStatement object. + ObjectMapper mapper = new ObjectMapper(); + SearchStatement ss = mapper.readValue(queryJson, SearchStatement.class); + + // We expect to have a search statement with one query. + assertEquals("Unexpected number of queries in marshalled result", 1, ss.getQueries().length); + + // Validate that the query is of the expected type and contains the + // expected values. + QueryStatement query = ss.getQueries()[0].getQueryStatement(); + assertNotNull("Expected marshalled statement to contain a 'parsed query'", query.getParsedQuery()); + assertTrue("Unexpected field name in marshalled query. Expected: " + field + " Actual: " + + query.getParsedQuery().getField(), field.equals(query.getParsedQuery().getField())); + assertTrue( + "Unexpected query string in marshalled query. Expected: " + queryString + " Actual: " + + query.getParsedQuery().getQueryString(), + queryString.equals(query.getParsedQuery().getQueryString())); + + // Validate that we are able to produce the expected ElasticSearch + // query syntax from the search statement. + assertTrue("Unexpected ElasticSearch syntax. Expected: " + queryES + " Actual: " + ss.toElasticSearch(), + queryES.equals(ss.toElasticSearch())); + } + + + @Test + public void simpleSortedQueryTest() throws JsonParseException, JsonMappingException, IOException { + + String field = "searchTags"; + String queryString = "aai3255"; + String queryJson = "{" + "\"queries\": [" + "{\"may\": {\"parsed-query\": {" + "\"field\": \"" + field + "\"," + + "\"query-string\": \"" + queryString + "\"}}}" + "]," + + "\"sort\": { \"field\": \"date\", \"order\": \"ascending\" }" + "}"; + + + String queryES = "{" + "\"version\": true," + "\"query\": {" + "\"bool\": {" + "\"must\": [], " + + "\"should\": [" + "{\"query_string\": {\"default_field\": \"searchTags\", \"query\": \"aai3255\"}}" + + "]," + "\"must_not\": []" + "}" + "}, " + "\"sort\": { \"date\": { \"order\": \"asc\"}}" + "}"; + + // Marshal our simple query JSON to a SearchStatement object. + ObjectMapper mapper = new ObjectMapper(); + SearchStatement ss = mapper.readValue(queryJson, SearchStatement.class); + + // We expect to have a search statement with one query. + assertEquals("Unexpected number of queries in marshalled result", 1, ss.getQueries().length); + + // Validate that the query is of the expected type and contains the + // expected values. + QueryStatement query = ss.getQueries()[0].getQueryStatement(); + assertNotNull("Expected marshalled statement to contain a 'parsed query'", query.getParsedQuery()); + assertTrue("Unexpected field name in marshalled query. Expected: " + field + " Actual: " + + query.getParsedQuery().getField(), field.equals(query.getParsedQuery().getField())); + assertTrue( + "Unexpected query string in marshalled query. Expected: " + queryString + " Actual: " + + query.getParsedQuery().getQueryString(), + queryString.equals(query.getParsedQuery().getQueryString())); + System.out.println("GDF: ES = " + ss.toElasticSearch()); + // Validate that we are able to produce the expected ElasticSearch + // query syntax from the search statement. + assertTrue("Unexpected ElasticSearch syntax. Expected: " + queryES + " Actual: " + ss.toElasticSearch(), + queryES.equals(ss.toElasticSearch())); + assertNull(ss.getAggregations()); + } + + @Test + public void filteredQueryTest() throws JsonParseException, JsonMappingException, IOException { + + String filterField1 = "field1"; + String filterField2 = "field2"; + String filterField3 = "field3"; + String filterValue1 = "a"; + String filterValue2 = "b"; + String filterValue3 = "string"; + String filterJson = "{ \"any\": [ " + "{\"match\": {\"field\": \"" + filterField1 + "\", \"value\": \"" + + filterValue1 + "\"}}," + "{\"match\": {\"field\": \"" + filterField2 + "\", \"value\": \"" + + filterValue2 + "\"}}" + "]," + "\"all\": [" + "{\"parsed-query\": {\"field\": \"" + filterField3 + + "\", \"query-string\": \"" + filterValue3 + "\"}}" + "]" + "}"; + + String filterStanzaJson = "\"filter\": " + filterJson; + + String queryStanzaJson = "\"queries\": [ " + + "{\"may\": {\"match\": {\"field\": \"searchTags\", \"value\": \"a\"}}}," + + "{\"may\": {\"match\": {\"field\": \"searchTags\", \"value\": \"b\"}}}," + + "{\"may\": {\"parsed-query\": {\"field\": \"fieldname\", \"query-string\": \"string\"}}}" + "]"; + + String queryES = "{" + "\"version\": true," + "\"query\": {" + "\"bool\": {" + "\"must\": [], " + + "\"should\": [" + "{\"term\": {\"searchTags\" : \"a\"}}, " + "{\"term\": {\"searchTags\" : \"b\"}}, " + + "{\"query_string\": {\"default_field\": \"fieldname\", \"query\": \"string\"}}" + "]," + + "\"must_not\": [], " + "\"filter\": {" + "\"bool\": {" + "\"must\": [" + + "{\"query_string\": {\"default_field\": \"field3\", \"query\": \"string\"}}" + "]," + + "\"must_not\": []," + "\"should\": [" + "{\"term\": {\"field1\" : \"a\"}}, " + + "{\"term\": {\"field2\" : \"b\"}}" + "]," + "\"must_not\": []" + "}" + "}" + "}" + "}" + "}"; + + StringBuilder sb = new StringBuilder(); + sb.append("{"); + sb.append(filterStanzaJson).append(", "); + sb.append(queryStanzaJson); + sb.append("}"); + + ObjectMapper mapper = new ObjectMapper(); + SearchStatement ss = mapper.readValue(sb.toString(), SearchStatement.class); + + assertEquals("Unexpected number of queries in the 'any' list for this statement's filter", 2, + ss.getFilter().getAny().length); + assertEquals("Unexpected number of queries in the 'all' list for this statement's filter", 1, + ss.getFilter().getAll().length); + + assertTrue("Unexpected ElasticSearch syntax. Expected: " + queryES + " Actual: " + ss.toElasticSearch(), + queryES.equals(ss.toElasticSearch())); + + assertNull(ss.getAggregations()); + } + + @Test + public void aggregationTest() { + String input = + "{\r\n \"queries\": [\r\n {\r\n \"must\": {\r\n \"match\": {\r\n \"field\": \"searchTags\",\r\n \"value\": \"a\"\r\n }\r\n }\r\n }\r\n ],\r\n \"aggregations\": [\r\n {\r\n \"name\": \"byDate\",\r\n \"aggregation\": {\r\n \"date-range\": {\r\n \"field\": \"mydate\",\r\n \"ranges\": [\r\n {\r\n \"from\": \"2016-12-19T00:00:00.738-05:00\",\r\n \"to\": \"2016-12-23T23:59:59.738-05:00\"\r\n }\r\n ]\r\n },\r\n \"sub-aggregations\": [\r\n {\r\n \"name\": \"byTerm\",\r\n \"aggregation\": {\r\n \"group-by\": {\r\n \"field\": \"myterm\"\r\n }\r\n }\r\n },\r\n {\r\n \"name\": \"byDate\",\r\n \"aggregation\": {\r\n \"date-histogram\": {\r\n \"field\": \"myDate\",\r\n \"interval\": \"myInterval\"\r\n }\r\n }\r\n }\r\n ]\r\n }\r\n },\r\n {\r\n \"name\": \"2nd\",\r\n \"aggregation\": {\r\n \"group-by\": {\r\n \"field\": \"anotherTerm\"\r\n }\r\n }\r\n }\r\n ]\r\n}"; + + ObjectMapper mapper = new ObjectMapper(); + try { + SearchStatement ss = mapper.readValue(input, SearchStatement.class); + Aggregation[] aggs = ss.getAggregations(); + assertNotNull(aggs); + assertEquals("Unexpected number aggregations", 2, aggs.length); + assertEquals("byDate", aggs[0].getName()); + assertNotNull(aggs[0].getStatement().getDateRange()); + assertEquals("mydate", aggs[0].getStatement().getDateRange().getField()); + assertNotNull(aggs[0].getStatement().getSubAggregations()); + assertEquals(2, aggs[0].getStatement().getSubAggregations().length); + assertEquals("byTerm", aggs[0].getStatement().getSubAggregations()[0].getName()); + assertEquals("byDate", aggs[0].getStatement().getSubAggregations()[1].getName()); + assertNull(aggs[0].getStatement().getGroupBy()); + assertEquals("2nd", aggs[1].getName()); + assertNotNull(aggs[1].getStatement().getGroupBy()); + assertEquals("anotherTerm", aggs[1].getStatement().getGroupBy().getField()); + assertNull(aggs[1].getStatement().getDateRange()); + assertNull(aggs[1].getStatement().getSubAggregations()); + + } catch (Exception e) { + fail("Encountered exception: " + e.getMessage()); + } + } + + @Test + public void resultSetRangeTest() throws IOException { + + // Simple query with a result set subrange specified. + File queryWithSubrangeFile = new File("src/test/resources/json/queries/query-with-subrange.json"); + String queryWithSubrangeStr = TestUtils.readFileToString(queryWithSubrangeFile); + String queryWithSubrangeExpectedESString = + "{\"version\": true,\"from\": 0, \"size\": 10, \"query\": {\"bool\": {\"must\": [{\"term\": {\"field1\" : \"Bob\"}}], \"should\": [],\"must_not\": []}}}"; + + ObjectMapper mapper = new ObjectMapper(); + SearchStatement ss = mapper.readValue(queryWithSubrangeStr, SearchStatement.class); + + assertEquals("Unexpected index for result set start", ss.getFrom(), (Integer) 0); + assertEquals("Unexpected value for result set size", ss.getSize(), (Integer) 10); + assertTrue("Unexpected elastic search query generated from search statement", + ss.toElasticSearch().equals(queryWithSubrangeExpectedESString)); + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/SortTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/SortTest.java new file mode 100644 index 0000000..832fa98 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/SortTest.java @@ -0,0 +1,49 @@ +/** + * ============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 static org.junit.Assert.assertTrue; + +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import org.junit.Test; + +public class SortTest { + + @Test + public void sortFieldTest() throws JsonParseException, JsonMappingException, IOException { + + String field = "fieldname"; + String order = "ascending"; + String json = "{\"field\": \"" + field + "\", \"order\": \"" + order + "\"}"; + + ObjectMapper mapper = new ObjectMapper(); + Sort sort = mapper.readValue(json, Sort.class); + + assertTrue("Unexpected field name in marshalled object. Expected: " + field + " Actual: " + sort.getField(), + field.equals(sort.getField())); + assertTrue("Unexpected order field in marshalled object. Expected: " + order + " Actual: " + sort.getOrder(), + order.equals(sort.getOrder().toString())); + + } +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/TermQueryTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/TermQueryTest.java new file mode 100644 index 0000000..9eab5f4 --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/searchapi/TermQueryTest.java @@ -0,0 +1,63 @@ +/** + * ============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 com.fasterxml.jackson.databind.ObjectMapper; +import java.io.IOException; +import org.junit.Assert; +import org.junit.Test; + +public class TermQueryTest { + + @Test + public void testAllMethods() throws IOException { + String field = "searchTags.nested"; + String stringValue = "theValue.nested"; + String termQueryWithStringValueJson = "{\"field\": \"" + field + "\", \"value\": \"" + stringValue + "\"}"; + + ObjectMapper mapper = new ObjectMapper(); + TermQuery stringTermQuery = mapper.readValue(termQueryWithStringValueJson, TermQuery.class); + Assert.assertEquals(stringValue, stringTermQuery.getValue()); + Assert.assertEquals("searchTags.nested", stringTermQuery.getField()); + stringTermQuery.setOperator("operator-1"); + Assert.assertEquals("operator-1", stringTermQuery.getOperator()); + stringTermQuery.setSearchAnalyzer("search-1"); + Assert.assertEquals("search-1", stringTermQuery.getSearchAnalyzer()); + + String field1 = "searchTags-1 searchTags.second"; + String stringValue1 = "theValue-1 theValue.second"; + String multiFieldTermQueryJSon = "{\"field\": \"" + field1 + "\", \"value\": \"" + stringValue1 + "\"}"; + TermQuery multiFieldTermQuery = mapper.readValue(multiFieldTermQueryJSon, TermQuery.class); + multiFieldTermQuery.setOperator("and"); + multiFieldTermQuery.setSearchAnalyzer("search-1"); + Assert.assertNotNull(multiFieldTermQuery.toElasticSearch()); + Assert.assertNotNull(multiFieldTermQuery.pathForNestedField(field1)); + + String field2 = "search11 search2"; + String stringValue2 = "theValue1 theValue2"; + String multiFieldTermJSon = "{\"field\": \"" + field2 + "\", \"value\": \"" + stringValue2 + "\"}"; + TermQuery multiFieldTerm = mapper.readValue(multiFieldTermJSon, TermQuery.class); + multiFieldTerm.setOperator("or"); + multiFieldTerm.setSearchAnalyzer("search-1"); + Assert.assertNotNull(multiFieldTerm.toElasticSearch()); + } + +} diff --git a/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/util/ElasticSearchPayloadTranslatorTest.java b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/util/ElasticSearchPayloadTranslatorTest.java new file mode 100644 index 0000000..877b64f --- /dev/null +++ b/search-data-service-app/src/test/java/org/onap/aai/sa/searchdbabstraction/util/ElasticSearchPayloadTranslatorTest.java @@ -0,0 +1,55 @@ +/** + * ============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.util; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileInputStream; +import org.apache.commons.io.IOUtils; +import org.junit.Before; +import org.junit.Test; + +public class ElasticSearchPayloadTranslatorTest { + + private final String SIMPLE_DOC_SCHEMA_JSON = "src/test/resources/json/index-mapping.json"; + + @Before + public void setup() throws Exception { + System.setProperty("CONFIG_HOME", System.getProperty("user.dir") + File.separator + "src/test/resources/json"); + } + + @Test + public void testPayloadTranslation() throws Exception { + String expectedErrMsg = "Sample error message for whitespace check"; + File schemaFile = new File(SIMPLE_DOC_SCHEMA_JSON); + String documentJson = IOUtils.toString(new FileInputStream(schemaFile), "UTF-8"); + assertTrue(documentJson.contains("\"type\": \"string\"")); + assertTrue(documentJson.contains("\"index\": \"analyzed\"")); + String translatedPayload = ElasticSearchPayloadTranslator.translateESPayload(documentJson); + assertTrue(translatedPayload.contains("\"type\":\"text\"")); + assertTrue(translatedPayload.contains("\"index\":true")); + assertTrue(translatedPayload.contains("\"fielddata\":true")); + assertFalse(documentJson.contains("\"index\":\"analyzed\"")); + assertTrue(translatedPayload.contains("\"errMsg\":\"" + expectedErrMsg + "\"")); + } +} diff --git a/search-data-service-app/src/test/resources/json/analysis-config.json b/search-data-service-app/src/test/resources/json/analysis-config.json new file mode 100644 index 0000000..a622dcf --- /dev/null +++ b/search-data-service-app/src/test/resources/json/analysis-config.json @@ -0,0 +1,21 @@ +[ + { + "name": "nGram_analyzer", + "description": "NGram Analyzer", + "tokenizer": "whitespace", + "filters": [ + "lowercase", + "asciifolding", + "nGram_filter" + ] + }, + { + "name": "whitespace_analyzer", + "description": "Whitespace Analyzer", + "tokenizer": "whitespace", + "filters": [ + "lowercase", + "asciifolding" + ] + } +] \ No newline at end of file diff --git a/search-data-service-app/src/test/resources/json/bulk-ops-invalid.json b/search-data-service-app/src/test/resources/json/bulk-ops-invalid.json new file mode 100644 index 0000000..4708498 --- /dev/null +++ b/search-data-service-app/src/test/resources/json/bulk-ops-invalid.json @@ -0,0 +1,32 @@ +{ + "operations": [ + { + "operation": "create", + "meta-data": { + "index": "test-index" + }, + "document": { + "field1": "value1", + "field2": "value2" + } + }, + { + "operation": "dance!", + "meta-data": { + "index": "test-index", + "id": "2", + "version": "5" + }, + "document": { + "field1": "new-value" + } + }, + { + "operation": "delete", + "meta-data": { + "index": "test-index", + "id": "4" + } + } + ] +} \ No newline at end of file diff --git a/search-data-service-app/src/test/resources/json/bulk-ops-valid.json b/search-data-service-app/src/test/resources/json/bulk-ops-valid.json new file mode 100644 index 0000000..6e805cf --- /dev/null +++ b/search-data-service-app/src/test/resources/json/bulk-ops-valid.json @@ -0,0 +1,31 @@ +[ + { + "create": { + "metaData": { + "url": "/indexes/test-index/documents/" + }, + "document": { + "field1": "value1", + "field2": "value2" + } + } + }, + { + "update": { + "metaData": { + "url": "/indexes/test-index/documents/3", + "etag": "5" + }, + "document": { + "field1": "new-value" + } + } + }, + { + "delete": { + "metaData": { + "url": "/indexes/test-index/documents/7" + } + } + } +] diff --git a/search-data-service-app/src/test/resources/json/dynamic-custom-template.json b/search-data-service-app/src/test/resources/json/dynamic-custom-template.json new file mode 100644 index 0000000..a7bd5ae --- /dev/null +++ b/search-data-service-app/src/test/resources/json/dynamic-custom-template.json @@ -0,0 +1,12 @@ +"dynamic_templates":[ + { + "strings":{ + "match_mapping_type":"string", + "match": "*", + "mapping":{ + "type":"text", + "fielddata":true + } + } + } +], \ No newline at end of file diff --git a/search-data-service-app/src/test/resources/json/dynamicIndex.json b/search-data-service-app/src/test/resources/json/dynamicIndex.json new file mode 100644 index 0000000..5df4069 --- /dev/null +++ b/search-data-service-app/src/test/resources/json/dynamicIndex.json @@ -0,0 +1,17 @@ +{ + "mappings": { + "dynamic_templates": [{ + "strings": { + "match_mapping_type": "string", + "match": "*", + "mapping": { + "type": "string", + "index": "not_analyzed" + } + } + } + ] + } + + +} \ No newline at end of file diff --git a/search-data-service-app/src/test/resources/json/es-payload-translation.json b/search-data-service-app/src/test/resources/json/es-payload-translation.json new file mode 100644 index 0000000..58ed8f6 --- /dev/null +++ b/search-data-service-app/src/test/resources/json/es-payload-translation.json @@ -0,0 +1,16 @@ +{ + "attr-translations": [ + { + "query": "$..[?(@.type=='string' && @.index=='analyzed')]", + "update": {"type": "text", "index": true, "fielddata": true} + }, + { + "query": "$..[?(@.type=='string' && @.index=='not_analyzed')]", + "update": {"type": "keyword", "index": true} + }, + { + "query": "$..[?(@.type=='string' && !@.index)]", + "update": {"type": "text", "fielddata": true} + } + ] +} \ No newline at end of file diff --git a/search-data-service-app/src/test/resources/json/filter-config.json b/search-data-service-app/src/test/resources/json/filter-config.json new file mode 100644 index 0000000..d1de1d7 --- /dev/null +++ b/search-data-service-app/src/test/resources/json/filter-config.json @@ -0,0 +1,7 @@ +[ + { + "name": "nGram_filter", + "description": "Custom NGram Filter.", + "configuration": " \"type\": \"nGram\", \"min_gram\": 1, \"max_gram\": 50, \"token_chars\": [ \"letter\", \"digit\", \"punctuation\", \"symbol\" ]" + } +] \ No newline at end of file diff --git a/search-data-service-app/src/test/resources/json/index-mapping.json b/search-data-service-app/src/test/resources/json/index-mapping.json new file mode 100644 index 0000000..e447092 --- /dev/null +++ b/search-data-service-app/src/test/resources/json/index-mapping.json @@ -0,0 +1,28 @@ +{ + "fields": [ + {"name": "validationId", "type": "string", "searchable": false}, + {"name": "validationTimestamp1", "type": "date", "format": "MMM d y HH:m:s||dd-MM-yyyy HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSSZZ||MM\/dd\/yyyy||yyyyMMdd'T'HHmmssZ"}, + {"name": "entityId", "type": "nested"}, + {"name": "entityType", "type": "string", "index": "analyzed"}, + {"name": "entityLink", "type": "string"}, + + {"name": "resourceVersion", "type": "string", "index": "not_analyzed"}, + {"name": "violations", "type": "nested", "sub-fields": [ + {"name": "violationId", "type": "string"}, + {"name": "violationTimestamp", "type": "date", "format": "MMM d y HH:m:s||dd-MM-yyyy HH:mm:ss||yyyy-MM-dd'T'HH:mm:ss.SSSZZ||MM\/dd\/yyyy||yyyyMMdd'T'HHmmssZ"}, + {"name": "modelName", "type": "string"}, + {"name": "category", "type": "string"}, + {"name": "severity", "type": "string"}, + {"name": "violationType", "type": "string"}, + {"name": "validationRule", "type": "string"}, + {"name": "violationDetails", "type": "nested", "sub-fields": [ + {"name": "entityId", "type": "nested"}, + {"name": "entityType", "type": "string"}, + {"name": "modelName", "type": "string"}, + {"name": "MISSING_REL", "type": "string"} + ]}, + {"name": "errorMessage", "type": "string", "errMsg": "Sample error message for whitespace check"} + ]} + ] + +} diff --git a/search-data-service-app/src/test/resources/json/nested-document.json b/search-data-service-app/src/test/resources/json/nested-document.json new file mode 100644 index 0000000..8373a6d --- /dev/null +++ b/search-data-service-app/src/test/resources/json/nested-document.json @@ -0,0 +1,49 @@ +{ + "fields": [ + { + "name": "serverName", + "data-type": "string", + "searchable": true, + "search-analyzer": "whitespace", + "sub-fields": [] + }, + { + "name": "serverComplex", + "data-type": "string", + "search-analyzer": "whitespace", + "sub-fields": [] + }, + { + "name": "address", + "data-type": "nested", + "sub-fields": [ + { + "name": "street", + "data-type": "string", + "sub-fields": [] + }, + { + "name": "city", + "data-type": "string", + "sub-fields": [] + }, + { + "name": "phone-numbers", + "data-type": "nested", + "sub-fields": [ + { + "name": "home", + "data-type": "string", + "sub-fields": [] + }, + { + "name": "cell", + "data-type": "string", + "sub-fields": [] + } + ] + } + ] + } + ] +} diff --git a/search-data-service-app/src/test/resources/json/queries/query-with-subrange.json b/search-data-service-app/src/test/resources/json/queries/query-with-subrange.json new file mode 100644 index 0000000..36e5f15 --- /dev/null +++ b/search-data-service-app/src/test/resources/json/queries/query-with-subrange.json @@ -0,0 +1,14 @@ +{ + "results-start": 0, + "results-size": 10, + "queries": [ + { + "must": { + "match": { + "field": "field1", + "value": "Bob" + } + } + } + ] +} \ No newline at end of file diff --git a/search-data-service-app/src/test/resources/json/queries/simple-parsed-query.json b/search-data-service-app/src/test/resources/json/queries/simple-parsed-query.json new file mode 100644 index 0000000..50ce681 --- /dev/null +++ b/search-data-service-app/src/test/resources/json/queries/simple-parsed-query.json @@ -0,0 +1,10 @@ +{ + "queries": [ + { + "parsed-query": { + "field": "searchTags", + "query-string": "a" + } + } + ] +} \ No newline at end of file diff --git a/search-data-service-app/src/test/resources/json/search_policy.json b/search-data-service-app/src/test/resources/json/search_policy.json new file mode 100644 index 0000000..b1abe3c --- /dev/null +++ b/search-data-service-app/src/test/resources/json/search_policy.json @@ -0,0 +1,63 @@ +{ + "roles": [ + { + "name": "testRole", + "functions": [{ + "name": "testFunction", + "methods": [{ + "name": "GET" + }, { + "name": "DELETE" + }, { + "name": "PUT" + } + ] + } + ], + "users": [{ + "username": "testUser" + } + + ] + }, + + { + "name": "devRole", + "functions": [{ + "name": "search", + "methods": [{ + "name": "GET" + }, { + "name": "DELETE" + }, { + "name": "PUT" + } + ] + } + ], + "users": [ + { + "username": "cn=onap, ou=onap, o=onap, l=ottawa, st=ontario, c=ca" + } + + ] + }, + + { + "name": "testBasicAuth", + "functions": [{ + "name": "testBasicAuthFuncyion", + "methods": [{ + "name": "GET" + } + ] + } + ], + "users": [{ + "user": "testBasicAuthUser", + "pass": "OBF:1ytc1vu91v2p1rxf1mqh1v8s1z0d1msn1san1mqf1z0h1v9u1msl1rvf1v1p1vv11yta" + } + ] + } + ] +} \ No newline at end of file diff --git a/search-data-service-app/src/test/resources/json/settings-config.json b/search-data-service-app/src/test/resources/json/settings-config.json new file mode 100644 index 0000000..5ebdbcc --- /dev/null +++ b/search-data-service-app/src/test/resources/json/settings-config.json @@ -0,0 +1,9 @@ +{ + "number_of_shards": "5", + "replication": "TLV_DATACENTER:2", + "drop_on_delete_index": true, + "version": { + "created": "6020399" + } +} + diff --git a/search-data-service-app/src/test/resources/json/simpleDocument.json b/search-data-service-app/src/test/resources/json/simpleDocument.json new file mode 100644 index 0000000..c21c574 --- /dev/null +++ b/search-data-service-app/src/test/resources/json/simpleDocument.json @@ -0,0 +1,17 @@ +{ + "fields": [ + { + "name": "serverName", + "data-type": "string", + "searchable": true, + "search-analyzer": "whitespace", + "sub-fields": [] + }, + { + "name": "serverComplex", + "data-type": "string", + "search-analyzer": "whitespace", + "sub-fields": [] + } + ] +} diff --git a/search-data-service-app/src/test/resources/json/tier-support-document.json b/search-data-service-app/src/test/resources/json/tier-support-document.json new file mode 100644 index 0000000..c6a20db --- /dev/null +++ b/search-data-service-app/src/test/resources/json/tier-support-document.json @@ -0,0 +1,30 @@ +{ + "document-type": "tier-support", + "document-id": "ts-1", + "fields": [ + { + "name": "entityType", + "data-type": "string" + }, + { + "name": "edgeTagQueryEntityFieldName", + "data-type": "string", + "index": false + }, + { + "name": "edgeTagQueryEntityFieldValue", + "data-type": "string", + "index": false + }, + { + "name": "searchTagIDs", + "data-type": "string" + }, + { + "name": "searchTags", + "data-type": "string", + "index-analyzer": "nGram_analyzer", + "search-analyzer": "whitespace_analyzer" + } + ] +} \ No newline at end of file -- cgit 1.2.3-korg