Initial search service commit
[aai/search-data-service.git] / src / test / java / org / openecomp / sa / searchdbabstraction / searchapi / SearchStatementTest.java
1 /**
2  * ============LICENSE_START=======================================================
3  * Search Data Service
4  * ================================================================================
5  * Copyright © 2017 AT&T Intellectual Property.
6  * Copyright © 2017 Amdocs
7  * All rights reserved.
8  * ================================================================================
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License ati
12  *
13  *    http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  * ============LICENSE_END=========================================================
21  *
22  * ECOMP and OpenECOMP are trademarks
23  * and service marks of AT&T Intellectual Property.
24  */
25 package org.openecomp.sa.searchdbabstraction.searchapi;
26
27 import com.fasterxml.jackson.core.JsonParseException;
28 import com.fasterxml.jackson.databind.JsonMappingException;
29 import com.fasterxml.jackson.databind.ObjectMapper;
30 import org.junit.Test;
31 import org.openecomp.sa.rest.TestUtils;
32
33 import java.io.File;
34 import java.io.IOException;
35
36 import static org.junit.Assert.*;
37
38 public class SearchStatementTest {
39
40   @Test
41   public void simpleQueryTest() throws JsonParseException, JsonMappingException, IOException {
42
43     String field = "searchTags";
44     String queryString = "aai3255";
45     String queryJson =
46         "{"
47             + "\"queries\": ["
48             + "{\"may\": {\"parsed-query\": {"
49             + "\"field\": \"" + field + "\","
50             + "\"query-string\": \"" + queryString + "\"}}}"
51             + "]"
52             + "}"
53             + "}";
54
55     String queryES =
56         "{"
57             + "\"version\": true,"
58             + "\"query\": {"
59             + "\"bool\": {"
60             + "\"must\": [], "
61             + "\"should\": ["
62             + "{\"query_string\": {\"default_field\": \"searchTags\", \"query\": \"aai3255\"}}"
63             + "],"
64             + "\"must_not\": []}"
65             + "}"
66             + "}";
67
68     // Marshal our simple query JSON to a SearchStatement object.
69     ObjectMapper mapper = new ObjectMapper();
70     SearchStatement ss = mapper.readValue(queryJson, SearchStatement.class);
71
72     // We expect to have a search statement with one query.
73     assertEquals("Unexpected number of queries in marshalled result",
74         1, ss.getQueries().length);
75
76     // Validate that the query is of the expected type and contains the
77     // expected values.
78     QueryStatement query = ss.getQueries()[0].getQueryStatement();
79     assertNotNull("Expected marshalled statement to contain a 'parsed query'",
80         query.getParsedQuery());
81     assertTrue("Unexpected field name in marshalled query.  Expected: " + field + " Actual: " + query.getParsedQuery().getField(),
82         field.equals(query.getParsedQuery().getField()));
83     assertTrue("Unexpected query string in marshalled query.  Expected: " + queryString + " Actual: " + query.getParsedQuery().getQueryString(),
84         queryString.equals(query.getParsedQuery().getQueryString()));
85
86     // Validate that we are able to produce the expected ElasticSearch
87     // query syntax from the search statement.
88     assertTrue("Unexpected ElasticSearch syntax.  Expected: " + queryES + " Actual: " + ss.toElasticSearch(),
89         queryES.equals(ss.toElasticSearch()));
90   }
91
92
93   @Test
94   public void simpleSortedQueryTest() throws JsonParseException, JsonMappingException, IOException {
95
96     String field = "searchTags";
97     String queryString = "aai3255";
98     String queryJson =
99         "{"
100             + "\"queries\": ["
101             + "{\"may\": {\"parsed-query\": {"
102             + "\"field\": \"" + field + "\","
103             + "\"query-string\": \"" + queryString + "\"}}}"
104             + "],"
105             + "\"sort\": { \"field\": \"date\", \"order\": \"ascending\" }"
106             + "}";
107
108
109     String queryES =
110         "{"
111             + "\"version\": true,"
112             + "\"query\": {"
113             + "\"bool\": {"
114             + "\"must\": [], "
115             + "\"should\": ["
116             + "{\"query_string\": {\"default_field\": \"searchTags\", \"query\": \"aai3255\"}}"
117             + "],"
118             + "\"must_not\": []"
119             + "}"
120             + "}, "
121             + "\"sort\": { \"date\": { \"order\": \"asc\"}}"
122             + "}";
123
124     // Marshal our simple query JSON to a SearchStatement object.
125     ObjectMapper mapper = new ObjectMapper();
126     SearchStatement ss = mapper.readValue(queryJson, SearchStatement.class);
127
128     // We expect to have a search statement with one query.
129     assertEquals("Unexpected number of queries in marshalled result",
130         1, ss.getQueries().length);
131
132     // Validate that the query is of the expected type and contains the
133     // expected values.
134     QueryStatement query = ss.getQueries()[0].getQueryStatement();
135     assertNotNull("Expected marshalled statement to contain a 'parsed query'",
136         query.getParsedQuery());
137     assertTrue("Unexpected field name in marshalled query.  Expected: " + field + " Actual: " + query.getParsedQuery().getField(),
138         field.equals(query.getParsedQuery().getField()));
139     assertTrue("Unexpected query string in marshalled query.  Expected: " + queryString + " Actual: " + query.getParsedQuery().getQueryString(),
140         queryString.equals(query.getParsedQuery().getQueryString()));
141     System.out.println("GDF: ES = " + ss.toElasticSearch());
142     // Validate that we are able to produce the expected ElasticSearch
143     // query syntax from the search statement.
144     assertTrue("Unexpected ElasticSearch syntax.  Expected: " + queryES + " Actual: " + ss.toElasticSearch(),
145         queryES.equals(ss.toElasticSearch()));
146     assertNull(ss.getAggregations());
147   }
148
149   @Test
150   public void filteredQueryTest() throws JsonParseException, JsonMappingException, IOException {
151
152     String filterField1 = "field1";
153     String filterField2 = "field2";
154     String filterField3 = "field3";
155     String filterValue1 = "a";
156     String filterValue2 = "b";
157     String filterValue3 = "string";
158     String filterJson = "{ \"any\": [ "
159         + "{\"match\": {\"field\": \"" + filterField1 + "\", \"value\": \"" + filterValue1 + "\"}},"
160         + "{\"match\": {\"field\": \"" + filterField2 + "\", \"value\": \"" + filterValue2 + "\"}}"
161         + "],"
162         + "\"all\": ["
163         + "{\"parsed-query\": {\"field\": \"" + filterField3 + "\", \"query-string\": \"" + filterValue3 + "\"}}"
164         + "]"
165         + "}";
166
167     String filterStanzaJson = "\"filter\": " + filterJson;
168
169     String queryStanzaJson = "\"queries\": [ "
170         + "{\"may\": {\"match\": {\"field\": \"searchTags\", \"value\": \"a\"}}},"
171         + "{\"may\": {\"match\": {\"field\": \"searchTags\", \"value\": \"b\"}}},"
172         + "{\"may\": {\"parsed-query\": {\"field\": \"fieldname\", \"query-string\": \"string\"}}}"
173         + "]";
174
175     String queryES =
176         "{"
177             + "\"version\": true,"
178             + "\"query\": {"
179             + "\"bool\": {"
180             + "\"must\": [], "
181             + "\"should\": ["
182             + "{\"term\": {\"searchTags\" : \"a\"}}, "
183             + "{\"term\": {\"searchTags\" : \"b\"}}, "
184             + "{\"query_string\": {\"default_field\": \"fieldname\", \"query\": \"string\"}}"
185             + "],"
186             + "\"must_not\": [], "
187             + "\"filter\": {"
188             + "\"bool\": {"
189             + "\"must\": ["
190             + "{\"query_string\": {\"default_field\": \"field3\", \"query\": \"string\"}}"
191             + "],"
192             + "\"must_not\": [],"
193             + "\"should\": ["
194             + "{\"term\": {\"field1\" : \"a\"}}, "
195             + "{\"term\": {\"field2\" : \"b\"}}"
196             + "],"
197             + "\"must_not\": []"
198             + "}"
199             + "}"
200             + "}"
201             + "}"
202             + "}";
203
204     StringBuilder sb = new StringBuilder();
205     sb.append("{");
206     sb.append(filterStanzaJson).append(", ");
207     sb.append(queryStanzaJson);
208     sb.append("}");
209
210     ObjectMapper mapper = new ObjectMapper();
211     SearchStatement ss = mapper.readValue(sb.toString(), SearchStatement.class);
212
213     assertEquals("Unexpected number of queries in the 'any' list for this statement's filter",
214         2, ss.getFilter().getAny().length);
215     assertEquals("Unexpected number of queries in the 'all' list for this statement's filter",
216         1, ss.getFilter().getAll().length);
217
218     assertTrue("Unexpected ElasticSearch syntax.  Expected: " + queryES + " Actual: " + ss.toElasticSearch(),
219         queryES.equals(ss.toElasticSearch()));
220
221     assertNull(ss.getAggregations());
222   }
223
224   @Test
225   public void aggregationTest() {
226     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}";
227
228     ObjectMapper mapper = new ObjectMapper();
229     try {
230       SearchStatement ss = mapper.readValue(input, SearchStatement.class);
231       Aggregation[] aggs = ss.getAggregations();
232       assertNotNull(aggs);
233       assertEquals("Unexpected number aggregations", 2, aggs.length);
234       assertEquals("byDate", aggs[0].getName());
235       assertNotNull(aggs[0].getStatement().getDateRange());
236       assertEquals("mydate", aggs[0].getStatement().getDateRange().getField());
237       assertNotNull(aggs[0].getStatement().getSubAggregations());
238       assertEquals(2, aggs[0].getStatement().getSubAggregations().length);
239       assertEquals("byTerm", aggs[0].getStatement().getSubAggregations()[0].getName());
240       assertEquals("byDate", aggs[0].getStatement().getSubAggregations()[1].getName());
241       assertNull(aggs[0].getStatement().getGroupBy());
242       assertEquals("2nd", aggs[1].getName());
243       assertNotNull(aggs[1].getStatement().getGroupBy());
244       assertEquals("anotherTerm", aggs[1].getStatement().getGroupBy().getField());
245       assertNull(aggs[1].getStatement().getDateRange());
246       assertNull(aggs[1].getStatement().getSubAggregations());
247
248     } catch (Exception e) {
249       fail("Encountered exception: " + e.getMessage());
250     }
251   }
252
253   @Test
254   public void resultSetRangeTest() throws IOException {
255
256     // Simple query with a result set subrange specified.
257     File queryWithSubrangeFile = new File("src/test/resources/json/queries/query-with-subrange.json");
258     String queryWithSubrangeStr = TestUtils.readFileToString(queryWithSubrangeFile);
259     String queryWithSubrangeExpectedESString =
260         "{\"version\": true,\"from\": 0, \"size\": 10, \"query\": {\"bool\": {\"must\": [{\"term\": {\"field1\" : \"Bob\"}}], \"should\": [],\"must_not\": []}}}";
261
262     ObjectMapper mapper = new ObjectMapper();
263     SearchStatement ss = mapper.readValue(queryWithSubrangeStr, SearchStatement.class);
264
265     assertEquals("Unexpected index for result set start", ss.getFrom(), (Integer) 0);
266     assertEquals("Unexpected value for result set size", ss.getSize(), (Integer) 10);
267     assertTrue("Unexpected elastic search query generated from search statement",
268         ss.toElasticSearch().equals(queryWithSubrangeExpectedESString));
269   }
270 }