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