e229348576fda1290ac1f3fd43804417e8d95dc4
[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             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             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             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 }