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