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