Format Java code to ONAP standard
[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 static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertTrue;
25
26 import com.fasterxml.jackson.core.JsonParseException;
27 import com.fasterxml.jackson.databind.JsonMappingException;
28 import com.fasterxml.jackson.databind.ObjectMapper;
29 import java.io.IOException;
30 import org.junit.Test;
31
32
33 public class QueryTest {
34
35     /**
36      * This test validates that we are able to marshal json structures representing term queries into POJOs and that we
37      * can then unmarshal those POJOs into ElasticSearch syntax.
38      *
39      * @throws JsonParseException
40      * @throws JsonMappingException
41      * @throws IOException
42      */
43     @Test
44     public void termQueryTest() throws JsonParseException, JsonMappingException, IOException {
45
46         Integer intValue = 1;
47         String field = "searchTags";
48         String termQueryWithIntegerValueJson = "{\"field\": \"" + field + "\", \"value\": " + intValue + "}";
49         String termQueryWithIntegerValueExpectedES = "{\"term\": {\"" + field + "\" : " + intValue + "}}";
50
51         Double doubleValue = 5.7;
52         String termQueryWithDoubleValueJson = "{\"field\": \"" + field + "\", \"value\": " + doubleValue + "}";
53         String termQueryWithDoubleValueExpectedES = "{\"term\": {\"" + field + "\" : " + doubleValue + "}}";
54
55         String stringValue = "theValue";
56         String termQueryWithStringValueJson = "{\"field\": \"" + field + "\", \"value\": \"" + stringValue + "\"}";
57         String termQueryWithStringValueExpectedES = "{\"term\": {\"" + field + "\" : \"" + stringValue + "\"}}";
58
59         ObjectMapper mapper = new ObjectMapper();
60
61
62         // Validate that we can marshal a term query where the supplied value
63         // is an Integer.
64         TermQuery integerTermQuery = mapper.readValue(termQueryWithIntegerValueJson, TermQuery.class);
65         assertTrue(
66                 "Expected value to be of type Integer, but was type "
67                         + integerTermQuery.getValue().getClass().getName(),
68                 integerTermQuery.getValue() instanceof Integer);
69         assertEquals(intValue, integerTermQuery.getValue());
70
71         assertTrue("ElasticSearch term query translation does not match the expected result",
72                 termQueryWithIntegerValueExpectedES.equals(integerTermQuery.toElasticSearch()));
73
74         // Validate that we can marshal a term query where the supplied value
75         // is a Double.
76         TermQuery doubleTermQuery = mapper.readValue(termQueryWithDoubleValueJson, TermQuery.class);
77         assertTrue(
78                 "Expected value to be of type Double, but was type " + doubleTermQuery.getValue().getClass().getName(),
79                 doubleTermQuery.getValue() instanceof Double);
80         assertEquals(doubleValue, doubleTermQuery.getValue());
81         assertTrue("ElasticSearch term query translation does not match the expected result",
82                 termQueryWithDoubleValueExpectedES.equals(doubleTermQuery.toElasticSearch()));
83
84         // Validate that we can marshal a term query where the supplied value
85         // is a String literal.
86         TermQuery stringTermQuery = mapper.readValue(termQueryWithStringValueJson, TermQuery.class);
87         assertTrue(
88                 "Expected value to be of type String, but was type " + stringTermQuery.getValue().getClass().getName(),
89                 stringTermQuery.getValue() instanceof String);
90         assertEquals(stringValue, stringTermQuery.getValue());
91         assertTrue("ElasticSearch term query translation does not match the expected result",
92                 termQueryWithStringValueExpectedES.equals(stringTermQuery.toElasticSearch()));
93
94
95     }
96
97
98     /**
99      * This test validates that we are able to marshal json structures representing parsed queries into POJOs and that
100      * we can then unmarshal those POJOs into ElasticSearch syntax.
101      *
102      * @throws JsonParseException
103      * @throws JsonMappingException
104      * @throws IOException
105      */
106     @Test
107     public void parsedQueryTest() throws JsonParseException, JsonMappingException, IOException {
108
109         String field = "fieldname";
110         String queryString = "The query string";
111
112         String queryJson = "{\"field\": \"" + field + "\", \"query-string\": \"" + queryString + "\"}";
113         String queryExpectedES =
114                 "{\"query_string\": {\"default_field\": \"" + field + "\", \"query\": \"" + queryString + "\"}}";
115
116         ObjectMapper mapper = new ObjectMapper();
117         ParsedQuery pq = mapper.readValue(queryJson, ParsedQuery.class);
118
119         assertTrue("Unexpected marshalled value for 'field' - expected: " + field + " actual: " + pq.getField(),
120                 field.equals(pq.getField()));
121         assertTrue("Unexpected marshalled value for 'query-string' - expected: " + queryString + " actual: "
122                 + pq.getQueryString(), queryString.equals(pq.getQueryString()));
123         assertTrue(
124                 "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 for both the 'gte' and 'gt' fields or the
131      * 'lte' and 'lt' fields, and that we do not allow mixing of numeric and date types in the same query.
132      *
133      * @throws JsonParseException
134      * @throws IOException
135      */
136     @Test
137     public void rangeQueryConflictingBoundsTest() throws JsonParseException, IOException {
138
139         String invalidGTAndGTE =
140                 "{ \"field\": \"timestamp\", \"gte\": \"2016-10-06T00:00:00.558+03:00\", \"gt\": \"2016-10-06T23:59:59.558+03:00\"}";
141         String invalidLTAndLTE =
142                 "{ \"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 POJO and unmarshalled to ElasticSearch
186      * 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 = "{ \"field\": \"" + field + "\", \"gte\": \"" + greaterThanDate + "\", \"lte\": \""
204                 + 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: "
213                 + dateRangeQuery.getField(), field.equals(dateRangeQuery.getField()));
214         assertTrue("Unexpected type for 'gte' value.  Expected: String  Actual: "
215                 + dateRangeQuery.getGte().getClass().getName(), dateRangeQuery.getGte() instanceof String);
216         assertTrue("Unexpected type for 'lte' value.  Expected: String  Actual: "
217                 + dateRangeQuery.getLte().getClass().getName(), dateRangeQuery.getLte() instanceof String);
218         assertTrue("Unexpected marshalled value for 'gte'.  Expected: " + greaterThanDate + " Actual: "
219                 + dateRangeQuery.getGte(), greaterThanDate.equals(dateRangeQuery.getGte()));
220         assertTrue("Unexpected marshalled value for 'lte'.  Expected: " + lessThanDate + " Actual: "
221                 + dateRangeQuery.getLte(), lessThanDate.equals(dateRangeQuery.getLte()));
222         assertTrue(
223                 "Unexpected ElasticSearch syntax.  Expected: " + dateRangeExpectedES + " Actual: "
224                         + dateRangeQuery.toElasticSearch(),
225                 dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch()));
226
227
228         // Generate a date range query using 'greater than' and 'less than or
229         // equal' operations.
230         dateRangeJson = "{ \"field\": \"" + field + "\", \"gt\": \"" + greaterThanDate + "\", \"lte\": \""
231                 + lessThanDate + "\"}";
232         dateRangeExpectedES =
233                 "{\"range\": {\"timestamp\": {\"gt\": \"2016-10-06T00:00:00.558+03:00\", \"lte\": \"2016-10-06T23:59:59.558+03:00\"}}}";
234
235         // Validate that the query is marshalled correctly to the POJO and that
236         // the generated ElasticSearch syntax looks as expected.
237         dateRangeQuery = mapper.readValue(dateRangeJson, RangeQuery.class);
238
239         assertTrue("Unexpected marshalled value for 'field'.  Expected: " + field + " Actual: "
240                 + dateRangeQuery.getField(), field.equals(dateRangeQuery.getField()));
241
242         assertTrue("Unexpected type for 'gt' value.  Expected: String  Actual: "
243                 + dateRangeQuery.getGt().getClass().getName(), dateRangeQuery.getGt() instanceof String);
244
245         assertTrue("Unexpected type for 'lte' value.  Expected: String  Actual: "
246                 + dateRangeQuery.getLte().getClass().getName(), dateRangeQuery.getLte() instanceof String);
247
248         assertTrue("Unexpected marshalled value for 'gt'.  Expected: " + greaterThanDate + " Actual: "
249                 + dateRangeQuery.getGt(), greaterThanDate.equals(dateRangeQuery.getGt()));
250
251         assertTrue("Unexpected marshalled value for 'lte'.  Expected: " + lessThanDate + " Actual: "
252                 + dateRangeQuery.getLte(), lessThanDate.equals(dateRangeQuery.getLte()));
253
254         assertTrue(
255                 "Unexpected ElasticSearch syntax.  Expected: " + dateRangeExpectedES + " Actual: "
256                         + dateRangeQuery.toElasticSearch(),
257                 dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch()));
258
259
260         // Generate a date range query using only a 'greater than' operation.
261         dateRangeJson = "{ \"field\": \"" + field + "\", \"gt\": \"" + greaterThanDate + "\"}";
262         dateRangeExpectedES = "{\"range\": {\"timestamp\": {\"gt\": \"2016-10-06T00:00:00.558+03:00\"}}}";
263
264         // Validate that the query is marshalled correctly to the POJO and that
265         // the generated ElasticSearch syntax looks as expected.
266         dateRangeQuery = mapper.readValue(dateRangeJson, RangeQuery.class);
267
268         assertTrue("Unexpected marshalled value for 'field'.  Expected: " + field + " Actual: "
269                 + dateRangeQuery.getField(), field.equals(dateRangeQuery.getField()));
270
271         assertTrue("Unexpected type for 'gt' value.  Expected: String  Actual: "
272                 + dateRangeQuery.getGt().getClass().getName(), dateRangeQuery.getGt() instanceof String);
273
274         assertTrue("Unexpected marshalled value for 'gt'.  Expected: " + greaterThanDate + " Actual: "
275                 + dateRangeQuery.getGt(), greaterThanDate.equals(dateRangeQuery.getGt()));
276
277         assertTrue(
278                 "Unexpected ElasticSearch syntax.  Expected: " + dateRangeExpectedES + " Actual: "
279                         + dateRangeQuery.toElasticSearch(),
280                 dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch()));
281
282     }
283
284     /**
285      * This test validates that numeric range queries can be marshalled to a Java POJO and unmarshalled to ElasticSearch
286      * syntax.
287      *
288      * @throws JsonParseException
289      * @throws JsonMappingException
290      * @throws IOException
291      */
292     @Test
293     public void numericRangeQueryTest() throws JsonParseException, JsonMappingException, IOException {
294
295         String field = "version";
296         Integer greaterThanInt = 5;
297         Integer lessThanInt = 100;
298
299         ObjectMapper mapper = new ObjectMapper();
300
301         // Generate a numeric range query using 'greater than or equal' and 'less
302         // than or equal' operations.
303         String numericRangeJson =
304                 "{ \"field\": \"" + field + "\", \"gte\": " + greaterThanInt + ", \"lte\": " + lessThanInt + "}";
305         String numericRangeExpectedES =
306                 "{\"range\": {\"" + field + "\": {\"gte\": " + greaterThanInt + ", \"lte\": " + lessThanInt + "}}}";
307
308         // Validate that the query is marshalled correctly to the POJO and that
309         // the generated ElasticSearch syntax looks as expected.
310         RangeQuery numericRangeQuery = mapper.readValue(numericRangeJson, RangeQuery.class);
311
312         assertTrue("Unexpected marshalled value for 'field'.  Expected: " + field + " Actual: "
313                 + numericRangeQuery.getField(), field.equals(numericRangeQuery.getField()));
314         assertTrue(
315                 "Unexpected type for 'gte' value.  Expected: Integer  Actual: "
316                         + numericRangeQuery.getGte().getClass().getName(),
317                 numericRangeQuery.getGte() instanceof Integer);
318         assertTrue(
319                 "Unexpected type for 'lte' value.  Expected: Integer  Actual: "
320                         + numericRangeQuery.getLte().getClass().getName(),
321                 numericRangeQuery.getLte() instanceof Integer);
322         assertEquals("Unexpected marshalled value for 'gte'.  Expected: " + greaterThanInt + " Actual: "
323                 + numericRangeQuery.getGte(), greaterThanInt, numericRangeQuery.getGte());
324         assertEquals("Unexpected marshalled value for 'lte'.  Expected: " + lessThanInt + " Actual: "
325                 + numericRangeQuery.getLte(), lessThanInt, numericRangeQuery.getLte());
326         assertTrue(
327                 "Unexpected ElasticSearch syntax.  Expected: " + numericRangeExpectedES + " Actual: "
328                         + numericRangeQuery.toElasticSearch(),
329                 numericRangeExpectedES.equals(numericRangeQuery.toElasticSearch()));
330
331
332         Double greaterThanDouble = 5.0;
333         Double lessThanDouble = 100.0;
334
335         // Generate a date range query using 'greater than' and 'less than or
336         // equal' operations.
337         numericRangeJson =
338                 "{ \"field\": \"" + field + "\", \"gt\": " + greaterThanDouble + ", \"lte\": " + lessThanDouble + "}";
339         numericRangeExpectedES = "{\"range\": {\"" + field + "\": {\"gt\": " + greaterThanDouble + ", \"lte\": "
340                 + lessThanDouble + "}}}";
341
342         // Validate that the query is marshalled correctly to the POJO and that
343         // the generated ElasticSearch syntax looks as expected.
344         numericRangeQuery = mapper.readValue(numericRangeJson, RangeQuery.class);
345
346         assertTrue("Unexpected marshalled value for 'field'.  Expected: " + field + " Actual: "
347                 + numericRangeQuery.getField(), field.equals(numericRangeQuery.getField()));
348
349         assertTrue("Unexpected type for 'gt' value.  Expected: Double  Actual: "
350                 + numericRangeQuery.getGt().getClass().getName(), numericRangeQuery.getGt() instanceof Double);
351
352         assertTrue(
353                 "Unexpected type for 'lte' value.  Expected: Double  Actual: "
354                         + numericRangeQuery.getLte().getClass().getName(),
355                 numericRangeQuery.getLte() instanceof Double);
356
357         assertEquals("Unexpected marshalled value for 'gt'.  Expected: " + greaterThanDouble + " Actual: "
358                 + numericRangeQuery.getGt(), greaterThanDouble, numericRangeQuery.getGt());
359
360         assertEquals("Unexpected marshalled value for 'lte'.  Expected: " + lessThanDouble + " Actual: "
361                 + numericRangeQuery.getLte(), lessThanDouble, numericRangeQuery.getLte());
362
363         assertTrue(
364                 "Unexpected ElasticSearch syntax.  Expected: " + numericRangeExpectedES + " Actual: "
365                         + numericRangeQuery.toElasticSearch(),
366                 numericRangeExpectedES.equals(numericRangeQuery.toElasticSearch()));
367     }
368
369 }