183317aee1afdc6983fd4db71607847418f427ac
[aai/search-data-service.git] / src / test / java / org / onap / aai / sa / searchdbabstraction / searchapi / QueryTest.java
1 /**
2  * ============LICENSE_START=======================================================
3  * org.onap.aai
4  * ================================================================================
5  * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6  * Copyright © 2017-2018 Amdocs
7  * ================================================================================
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *       http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  * ============LICENSE_END=========================================================
20  */
21 package org.onap.aai.sa.searchdbabstraction.searchapi;
22
23 import com.fasterxml.jackson.core.JsonParseException;
24 import com.fasterxml.jackson.databind.JsonMappingException;
25 import com.fasterxml.jackson.databind.ObjectMapper;
26 import org.junit.Test;
27 import org.onap.aai.sa.searchdbabstraction.searchapi.ParsedQuery;
28 import org.onap.aai.sa.searchdbabstraction.searchapi.RangeQuery;
29 import org.onap.aai.sa.searchdbabstraction.searchapi.TermQuery;
30
31 import java.io.IOException;
32
33 import static org.junit.Assert.assertEquals;
34 import static org.junit.Assert.assertTrue;
35
36
37 public class QueryTest {
38
39   /**
40    * This test validates that we are able to marshal json structures
41    * representing term queries into POJOs and that we can then
42    * unmarshal those POJOs into ElasticSearch syntax.
43    *
44    * @throws JsonParseException
45    * @throws JsonMappingException
46    * @throws IOException
47    */
48   @Test
49   public void termQueryTest() throws JsonParseException, JsonMappingException, IOException {
50
51     Integer intValue = 1;
52     String field = "searchTags";
53     String termQueryWithIntegerValueJson = "{\"field\": \"" + field + "\", \"value\": " + intValue + "}";
54     String termQueryWithIntegerValueExpectedES = "{\"term\": {\"" + field + "\" : " + intValue + "}}";
55
56     Double doubleValue = 5.7;
57     String termQueryWithDoubleValueJson = "{\"field\": \"" + field + "\", \"value\": " + doubleValue + "}";
58     String termQueryWithDoubleValueExpectedES = "{\"term\": {\"" + field + "\" : " + doubleValue + "}}";
59
60     String stringValue = "theValue";
61     String termQueryWithStringValueJson = "{\"field\": \"" + field + "\", \"value\": \"" + stringValue + "\"}";
62     String termQueryWithStringValueExpectedES = "{\"term\": {\"" + field + "\" : \"" + stringValue + "\"}}";
63
64     ObjectMapper mapper = new ObjectMapper();
65
66
67     // Validate that we can marshal a term query where the supplied value
68     // is an Integer.
69     TermQuery integerTermQuery = mapper.readValue(termQueryWithIntegerValueJson, TermQuery.class);
70     assertTrue("Expected value to be of type Integer, but was type " + integerTermQuery.getValue().getClass().getName(),
71         integerTermQuery.getValue() instanceof Integer);
72     assertEquals(intValue, integerTermQuery.getValue());
73
74     assertTrue("ElasticSearch term query translation does not match the expected result",
75         termQueryWithIntegerValueExpectedES.equals(integerTermQuery.toElasticSearch()));
76
77     // Validate that we can marshal a term query where the supplied value
78     // is a Double.
79     TermQuery doubleTermQuery = mapper.readValue(termQueryWithDoubleValueJson, TermQuery.class);
80     assertTrue("Expected value to be of type Double, but was type " + doubleTermQuery.getValue().getClass().getName(),
81         doubleTermQuery.getValue() instanceof Double);
82     assertEquals(doubleValue, doubleTermQuery.getValue());
83     assertTrue("ElasticSearch term query translation does not match the expected result",
84         termQueryWithDoubleValueExpectedES.equals(doubleTermQuery.toElasticSearch()));
85
86     // Validate that we can marshal a term query where the supplied value
87     // is a String literal.
88     TermQuery stringTermQuery = mapper.readValue(termQueryWithStringValueJson, TermQuery.class);
89     assertTrue("Expected value to be of type String, but was type " + stringTermQuery.getValue().getClass().getName(),
90         stringTermQuery.getValue() instanceof String);
91     assertEquals(stringValue, stringTermQuery.getValue());
92     assertTrue("ElasticSearch term query translation does not match the expected result",
93         termQueryWithStringValueExpectedES.equals(stringTermQuery.toElasticSearch()));
94
95
96   }
97
98
99   /**
100    * This test validates that we are able to marshal json structures
101    * representing parsed queries into POJOs and that we can then
102    * unmarshal those POJOs into ElasticSearch syntax.
103    *
104    * @throws JsonParseException
105    * @throws JsonMappingException
106    * @throws IOException
107    */
108   @Test
109   public void parsedQueryTest() throws JsonParseException, JsonMappingException, IOException {
110
111     String field = "fieldname";
112     String queryString = "The query string";
113
114     String queryJson = "{\"field\": \"" + field + "\", \"query-string\": \"" + queryString + "\"}";
115     String queryExpectedES = "{\"query_string\": {\"default_field\": \"" + field + "\", \"query\": \"" + queryString + "\"}}";
116
117     ObjectMapper mapper = new ObjectMapper();
118     ParsedQuery pq = mapper.readValue(queryJson, ParsedQuery.class);
119
120     assertTrue("Unexpected marshalled value for 'field' - expected: " + field + " actual: " + pq.getField(),
121         field.equals(pq.getField()));
122     assertTrue("Unexpected marshalled value for 'query-string' - expected: " + queryString + " actual: " + pq.getQueryString(),
123         queryString.equals(pq.getQueryString()));
124     assertTrue("Unexpected ElasticSearch syntax.  Expected: " + queryExpectedES + " Actual: " + pq.toElasticSearch(),
125         queryExpectedES.equals(pq.toElasticSearch()));
126   }
127
128
129   /**
130    * This test validates that a ranged query cannot be parsed with values
131    * for both the 'gte' and 'gt' fields or the 'lte' and 'lt' fields, and
132    * that we do not allow mixing of numeric and date types in the same
133    * query.
134    *
135    * @throws JsonParseException
136    * @throws IOException
137    */
138   @Test
139   public void rangeQueryConflictingBoundsTest() throws JsonParseException, IOException {
140
141     String invalidGTAndGTE = "{ \"field\": \"timestamp\", \"gte\": \"2016-10-06T00:00:00.558+03:00\", \"gt\": \"2016-10-06T23:59:59.558+03:00\"}";
142     String invalidLTAndLTE = "{ \"field\": \"timestamp\", \"lte\": \"2016-10-06T00:00:00.558+03:00\", \"lt\": \"2016-10-06T23:59:59.558+03:00\"}";
143     String invalidTypes = "{ \"field\": \"timestamp\", \"lte\": 5, \"gte\": \"2016-10-06T23:59:59.558+03:00\"}";
144
145     ObjectMapper mapper = new ObjectMapper();
146
147     // Attempt to parse a query where we are setting values for both the
148     // 'greater than' and 'greater than and equal to' operators.
149     boolean gotExpectedException = false;
150     try {
151       RangeQuery badRangeQuery = mapper.readValue(invalidGTAndGTE, RangeQuery.class);
152     } catch (JsonMappingException e) {
153       gotExpectedException = true;
154     }
155     assertTrue("Attempting to set both a 'gt' and 'gte' value on the same query should not have been allowed",
156         gotExpectedException);
157
158     // Attempt to parse a query where we are setting values for both the
159     // 'less than' and 'less than and equal to' operators.
160     gotExpectedException = false;
161     try {
162       RangeQuery badRangeQuery = mapper.readValue(invalidLTAndLTE, RangeQuery.class);
163     } catch (JsonMappingException e) {
164       gotExpectedException = true;
165     }
166     assertTrue("Attempting to set both a 'lt' and 'lte' value on the same query should not have been allowed",
167         gotExpectedException);
168
169     // Attempt to parse a query where we are mixing numeric and date values
170     // in the same query.
171     gotExpectedException = false;
172     try {
173       RangeQuery badRangeQuery = mapper.readValue(invalidTypes, RangeQuery.class);
174     } catch (JsonMappingException e) {
175       gotExpectedException = true;
176     }
177     assertTrue("Attempting to mix numeric and date values in the same query should not have been allowed",
178         gotExpectedException);
179
180
181   }
182
183
184   /**
185    * This test validates that date range queries can be marshalled to a Java
186    * POJO and unmarshalled to ElasticSearch syntax.
187    *
188    * @throws JsonParseException
189    * @throws JsonMappingException
190    * @throws IOException
191    */
192   @Test
193   public void dateRangeQueryTest() throws JsonParseException, JsonMappingException, IOException {
194
195     String field = "timestamp";
196     String greaterThanDate = "2016-10-06T00:00:00.558+03:00";
197     String lessThanDate = "2016-10-06T23:59:59.558+03:00";
198
199     ObjectMapper mapper = new ObjectMapper();
200
201     // Generate a date range query using 'greater than or equal' and 'less
202     // than or equal' operations.
203     String dateRangeJson =
204         "{ \"field\": \"" + field + "\", \"gte\": \"" + greaterThanDate + "\", \"lte\": \"" + lessThanDate + "\"}";
205     String dateRangeExpectedES =
206         "{\"range\": {\"timestamp\": {\"gte\": \"2016-10-06T00:00:00.558+03:00\", \"lte\": \"2016-10-06T23:59:59.558+03:00\"}}}";
207
208     // Validate that the query is marshalled correctly to the POJO and that
209     // the generated ElasticSearch syntax looks as expected.
210     RangeQuery dateRangeQuery = mapper.readValue(dateRangeJson, RangeQuery.class);
211
212     assertTrue("Unexpected marshalled value for 'field'.  Expected: " + field + " Actual: " + dateRangeQuery.getField(),
213         field.equals(dateRangeQuery.getField()));
214     assertTrue("Unexpected type for 'gte' value.  Expected: String  Actual: " + dateRangeQuery.getGte().getClass().getName(),
215         dateRangeQuery.getGte() instanceof String);
216     assertTrue("Unexpected type for 'lte' value.  Expected: String  Actual: " + dateRangeQuery.getLte().getClass().getName(),
217         dateRangeQuery.getLte() instanceof String);
218     assertTrue("Unexpected marshalled value for 'gte'.  Expected: " + greaterThanDate + " Actual: " + dateRangeQuery.getGte(),
219         greaterThanDate.equals(dateRangeQuery.getGte()));
220     assertTrue("Unexpected marshalled value for 'lte'.  Expected: " + lessThanDate + " Actual: " + dateRangeQuery.getLte(),
221         lessThanDate.equals(dateRangeQuery.getLte()));
222     assertTrue("Unexpected ElasticSearch syntax.  Expected: " + dateRangeExpectedES + " Actual: " + dateRangeQuery.toElasticSearch(),
223         dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch()));
224
225
226     // Generate a date range query using 'greater than' and 'less than or
227     // equal' operations.
228     dateRangeJson =
229         "{ \"field\": \"" + field + "\", \"gt\": \"" + greaterThanDate + "\", \"lte\": \"" + lessThanDate + "\"}";
230     dateRangeExpectedES =
231         "{\"range\": {\"timestamp\": {\"gt\": \"2016-10-06T00:00:00.558+03:00\", \"lte\": \"2016-10-06T23:59:59.558+03:00\"}}}";
232
233     // Validate that the query is marshalled correctly to the POJO and that
234     // the generated ElasticSearch syntax looks as expected.
235     dateRangeQuery = mapper.readValue(dateRangeJson, RangeQuery.class);
236
237     assertTrue("Unexpected marshalled value for 'field'.  Expected: " + field + " Actual: " + dateRangeQuery.getField(),
238         field.equals(dateRangeQuery.getField()));
239
240     assertTrue("Unexpected type for 'gt' value.  Expected: String  Actual: " + dateRangeQuery.getGt().getClass().getName(),
241         dateRangeQuery.getGt() instanceof String);
242
243     assertTrue("Unexpected type for 'lte' value.  Expected: String  Actual: " + dateRangeQuery.getLte().getClass().getName(),
244         dateRangeQuery.getLte() instanceof String);
245
246     assertTrue("Unexpected marshalled value for 'gt'.  Expected: " + greaterThanDate + " Actual: " + dateRangeQuery.getGt(),
247         greaterThanDate.equals(dateRangeQuery.getGt()));
248
249     assertTrue("Unexpected marshalled value for 'lte'.  Expected: " + lessThanDate + " Actual: " + dateRangeQuery.getLte(),
250         lessThanDate.equals(dateRangeQuery.getLte()));
251
252     assertTrue("Unexpected ElasticSearch syntax.  Expected: " + dateRangeExpectedES + " Actual: " + dateRangeQuery.toElasticSearch(),
253         dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch()));
254
255
256     // Generate a date range query using only a 'greater than' operation.
257     dateRangeJson =
258         "{ \"field\": \"" + field + "\", \"gt\": \"" + greaterThanDate + "\"}";
259     dateRangeExpectedES =
260         "{\"range\": {\"timestamp\": {\"gt\": \"2016-10-06T00:00:00.558+03:00\"}}}";
261
262     // Validate that the query is marshalled correctly to the POJO and that
263     // the generated ElasticSearch syntax looks as expected.
264     dateRangeQuery = mapper.readValue(dateRangeJson, RangeQuery.class);
265
266     assertTrue("Unexpected marshalled value for 'field'.  Expected: " + field + " Actual: " + dateRangeQuery.getField(),
267         field.equals(dateRangeQuery.getField()));
268
269     assertTrue("Unexpected type for 'gt' value.  Expected: String  Actual: " + dateRangeQuery.getGt().getClass().getName(),
270         dateRangeQuery.getGt() instanceof String);
271
272     assertTrue("Unexpected marshalled value for 'gt'.  Expected: " + greaterThanDate + " Actual: " + dateRangeQuery.getGt(),
273         greaterThanDate.equals(dateRangeQuery.getGt()));
274
275     assertTrue("Unexpected ElasticSearch syntax.  Expected: " + dateRangeExpectedES + " Actual: " + dateRangeQuery.toElasticSearch(),
276         dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch()));
277
278   }
279
280   /**
281    * This test validates that numeric range queries can be marshalled to a Java
282    * POJO and unmarshalled to ElasticSearch syntax.
283    *
284    * @throws JsonParseException
285    * @throws JsonMappingException
286    * @throws IOException
287    */
288   @Test
289   public void numericRangeQueryTest() throws JsonParseException, JsonMappingException, IOException {
290
291     String field = "version";
292     Integer greaterThanInt = 5;
293     Integer lessThanInt = 100;
294
295     ObjectMapper mapper = new ObjectMapper();
296
297     // Generate a numeric range query using 'greater than or equal' and 'less
298     // than or equal' operations.
299     String numericRangeJson =
300         "{ \"field\": \"" + field + "\", \"gte\": " + greaterThanInt + ", \"lte\": " + lessThanInt + "}";
301     String numericRangeExpectedES =
302         "{\"range\": {\"" + field + "\": {\"gte\": " + greaterThanInt + ", \"lte\": " + lessThanInt + "}}}";
303
304     // Validate that the query is marshalled correctly to the POJO and that
305     // the generated ElasticSearch syntax looks as expected.
306     RangeQuery numericRangeQuery = mapper.readValue(numericRangeJson, RangeQuery.class);
307
308     assertTrue("Unexpected marshalled value for 'field'.  Expected: " + field + " Actual: " + numericRangeQuery.getField(),
309         field.equals(numericRangeQuery.getField()));
310     assertTrue("Unexpected type for 'gte' value.  Expected: Integer  Actual: " + numericRangeQuery.getGte().getClass().getName(),
311         numericRangeQuery.getGte() instanceof Integer);
312     assertTrue("Unexpected type for 'lte' value.  Expected: Integer  Actual: " + numericRangeQuery.getLte().getClass().getName(),
313         numericRangeQuery.getLte() instanceof Integer);
314     assertEquals("Unexpected marshalled value for 'gte'.  Expected: " + greaterThanInt + " Actual: " + numericRangeQuery.getGte(),
315         greaterThanInt, numericRangeQuery.getGte());
316     assertEquals("Unexpected marshalled value for 'lte'.  Expected: " + lessThanInt + " Actual: " + numericRangeQuery.getLte(),
317         lessThanInt, numericRangeQuery.getLte());
318     assertTrue("Unexpected ElasticSearch syntax.  Expected: " + numericRangeExpectedES + " Actual: " + numericRangeQuery.toElasticSearch(),
319         numericRangeExpectedES.equals(numericRangeQuery.toElasticSearch()));
320
321
322     Double greaterThanDouble = 5.0;
323     Double lessThanDouble = 100.0;
324
325     // Generate a date range query using 'greater than' and 'less than or
326     // equal' operations.
327     numericRangeJson =
328         "{ \"field\": \"" + field + "\", \"gt\": " + greaterThanDouble + ", \"lte\": " + lessThanDouble + "}";
329     numericRangeExpectedES =
330         "{\"range\": {\"" + field + "\": {\"gt\": " + greaterThanDouble + ", \"lte\": " + lessThanDouble + "}}}";
331
332     // Validate that the query is marshalled correctly to the POJO and that
333     // the generated ElasticSearch syntax looks as expected.
334     numericRangeQuery = mapper.readValue(numericRangeJson, RangeQuery.class);
335
336     assertTrue("Unexpected marshalled value for 'field'.  Expected: " + field + " Actual: " + numericRangeQuery.getField(),
337         field.equals(numericRangeQuery.getField()));
338
339     assertTrue("Unexpected type for 'gt' value.  Expected: Double  Actual: " + numericRangeQuery.getGt().getClass().getName(),
340         numericRangeQuery.getGt() instanceof Double);
341
342     assertTrue("Unexpected type for 'lte' value.  Expected: Double  Actual: " + numericRangeQuery.getLte().getClass().getName(),
343         numericRangeQuery.getLte() instanceof Double);
344
345     assertEquals("Unexpected marshalled value for 'gt'.  Expected: " + greaterThanDouble + " Actual: " + numericRangeQuery.getGt(),
346         greaterThanDouble, numericRangeQuery.getGt());
347
348     assertEquals("Unexpected marshalled value for 'lte'.  Expected: " + lessThanDouble + " Actual: " + numericRangeQuery.getLte(),
349         lessThanDouble, numericRangeQuery.getLte());
350
351     assertTrue("Unexpected ElasticSearch syntax.  Expected: " + numericRangeExpectedES + " Actual: " + numericRangeQuery.toElasticSearch(),
352         numericRangeExpectedES.equals(numericRangeQuery.toElasticSearch()));
353   }
354
355 }