2 * ============LICENSE_START=======================================================
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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=========================================================
21 package org.onap.aai.sa.searchdbabstraction.searchapi;
23 import static org.junit.Assert.assertEquals;
24 import static org.junit.Assert.assertTrue;
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;
33 public class QueryTest {
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.
39 * @throws JsonParseException
40 * @throws JsonMappingException
44 public void termQueryTest() throws JsonParseException, JsonMappingException, IOException {
47 String field = "searchTags";
48 String termQueryWithIntegerValueJson = "{\"field\": \"" + field + "\", \"value\": " + intValue + "}";
49 String termQueryWithIntegerValueExpectedES = "{\"term\": {\"" + field + "\" : " + intValue + "}}";
51 Double doubleValue = 5.7;
52 String termQueryWithDoubleValueJson = "{\"field\": \"" + field + "\", \"value\": " + doubleValue + "}";
53 String termQueryWithDoubleValueExpectedES = "{\"term\": {\"" + field + "\" : " + doubleValue + "}}";
55 String stringValue = "theValue";
56 String termQueryWithStringValueJson = "{\"field\": \"" + field + "\", \"value\": \"" + stringValue + "\"}";
57 String termQueryWithStringValueExpectedES = "{\"term\": {\"" + field + "\" : \"" + stringValue + "\"}}";
59 ObjectMapper mapper = new ObjectMapper();
62 // Validate that we can marshal a term query where the supplied value
64 TermQuery integerTermQuery = mapper.readValue(termQueryWithIntegerValueJson, TermQuery.class);
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());
71 assertTrue("ElasticSearch term query translation does not match the expected result",
72 termQueryWithIntegerValueExpectedES.equals(integerTermQuery.toElasticSearch()));
74 // Validate that we can marshal a term query where the supplied value
76 TermQuery doubleTermQuery = mapper.readValue(termQueryWithDoubleValueJson, TermQuery.class);
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()));
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);
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()));
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.
102 * @throws JsonParseException
103 * @throws JsonMappingException
104 * @throws IOException
107 public void parsedQueryTest() throws JsonParseException, JsonMappingException, IOException {
109 String field = "fieldname";
110 String queryString = "The query string";
112 String queryJson = "{\"field\": \"" + field + "\", \"query-string\": \"" + queryString + "\"}";
113 String queryExpectedES =
114 "{\"query_string\": {\"default_field\": \"" + field + "\", \"query\": \"" + queryString + "\"}}";
116 ObjectMapper mapper = new ObjectMapper();
117 ParsedQuery pq = mapper.readValue(queryJson, ParsedQuery.class);
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()));
124 "Unexpected ElasticSearch syntax. Expected: " + queryExpectedES + " Actual: " + pq.toElasticSearch(),
125 queryExpectedES.equals(pq.toElasticSearch()));
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.
133 * @throws JsonParseException
134 * @throws IOException
137 public void rangeQueryConflictingBoundsTest() throws JsonParseException, IOException {
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\"}";
145 ObjectMapper mapper = new ObjectMapper();
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;
151 mapper.readValue(invalidGTAndGTE, RangeQuery.class);
152 } catch (JsonMappingException e) {
153 gotExpectedException = true;
155 assertTrue("Attempting to set both a 'gt' and 'gte' value on the same query should not have been allowed",
156 gotExpectedException);
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;
162 mapper.readValue(invalidLTAndLTE, RangeQuery.class);
163 } catch (JsonMappingException e) {
164 gotExpectedException = true;
166 assertTrue("Attempting to set both a 'lt' and 'lte' value on the same query should not have been allowed",
167 gotExpectedException);
169 // Attempt to parse a query where we are mixing numeric and date values
170 // in the same query.
171 gotExpectedException = false;
173 mapper.readValue(invalidTypes, RangeQuery.class);
174 } catch (JsonMappingException e) {
175 gotExpectedException = true;
177 assertTrue("Attempting to mix numeric and date values in the same query should not have been allowed",
178 gotExpectedException);
185 * This test validates that date range queries can be marshalled to a Java POJO and unmarshalled to ElasticSearch
188 * @throws JsonParseException
189 * @throws JsonMappingException
190 * @throws IOException
193 public void dateRangeQueryTest() throws JsonParseException, JsonMappingException, IOException {
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";
199 ObjectMapper mapper = new ObjectMapper();
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\"}}}";
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);
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()));
223 "Unexpected ElasticSearch syntax. Expected: " + dateRangeExpectedES + " Actual: "
224 + dateRangeQuery.toElasticSearch(),
225 dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch()));
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\"}}}";
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);
239 assertTrue("Unexpected marshalled value for 'field'. Expected: " + field + " Actual: "
240 + dateRangeQuery.getField(), field.equals(dateRangeQuery.getField()));
242 assertTrue("Unexpected type for 'gt' value. Expected: String Actual: "
243 + dateRangeQuery.getGt().getClass().getName(), dateRangeQuery.getGt() instanceof String);
245 assertTrue("Unexpected type for 'lte' value. Expected: String Actual: "
246 + dateRangeQuery.getLte().getClass().getName(), dateRangeQuery.getLte() instanceof String);
248 assertTrue("Unexpected marshalled value for 'gt'. Expected: " + greaterThanDate + " Actual: "
249 + dateRangeQuery.getGt(), greaterThanDate.equals(dateRangeQuery.getGt()));
251 assertTrue("Unexpected marshalled value for 'lte'. Expected: " + lessThanDate + " Actual: "
252 + dateRangeQuery.getLte(), lessThanDate.equals(dateRangeQuery.getLte()));
255 "Unexpected ElasticSearch syntax. Expected: " + dateRangeExpectedES + " Actual: "
256 + dateRangeQuery.toElasticSearch(),
257 dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch()));
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\"}}}";
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);
268 assertTrue("Unexpected marshalled value for 'field'. Expected: " + field + " Actual: "
269 + dateRangeQuery.getField(), field.equals(dateRangeQuery.getField()));
271 assertTrue("Unexpected type for 'gt' value. Expected: String Actual: "
272 + dateRangeQuery.getGt().getClass().getName(), dateRangeQuery.getGt() instanceof String);
274 assertTrue("Unexpected marshalled value for 'gt'. Expected: " + greaterThanDate + " Actual: "
275 + dateRangeQuery.getGt(), greaterThanDate.equals(dateRangeQuery.getGt()));
278 "Unexpected ElasticSearch syntax. Expected: " + dateRangeExpectedES + " Actual: "
279 + dateRangeQuery.toElasticSearch(),
280 dateRangeExpectedES.equals(dateRangeQuery.toElasticSearch()));
285 * This test validates that numeric range queries can be marshalled to a Java POJO and unmarshalled to ElasticSearch
288 * @throws JsonParseException
289 * @throws JsonMappingException
290 * @throws IOException
293 public void numericRangeQueryTest() throws JsonParseException, JsonMappingException, IOException {
295 String field = "version";
296 Integer greaterThanInt = 5;
297 Integer lessThanInt = 100;
299 ObjectMapper mapper = new ObjectMapper();
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 + "}}}";
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);
312 assertTrue("Unexpected marshalled value for 'field'. Expected: " + field + " Actual: "
313 + numericRangeQuery.getField(), field.equals(numericRangeQuery.getField()));
315 "Unexpected type for 'gte' value. Expected: Integer Actual: "
316 + numericRangeQuery.getGte().getClass().getName(),
317 numericRangeQuery.getGte() instanceof Integer);
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());
327 "Unexpected ElasticSearch syntax. Expected: " + numericRangeExpectedES + " Actual: "
328 + numericRangeQuery.toElasticSearch(),
329 numericRangeExpectedES.equals(numericRangeQuery.toElasticSearch()));
332 Double greaterThanDouble = 5.0;
333 Double lessThanDouble = 100.0;
335 // Generate a date range query using 'greater than' and 'less than or
336 // equal' operations.
338 "{ \"field\": \"" + field + "\", \"gt\": " + greaterThanDouble + ", \"lte\": " + lessThanDouble + "}";
339 numericRangeExpectedES = "{\"range\": {\"" + field + "\": {\"gt\": " + greaterThanDouble + ", \"lte\": "
340 + lessThanDouble + "}}}";
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);
346 assertTrue("Unexpected marshalled value for 'field'. Expected: " + field + " Actual: "
347 + numericRangeQuery.getField(), field.equals(numericRangeQuery.getField()));
349 assertTrue("Unexpected type for 'gt' value. Expected: Double Actual: "
350 + numericRangeQuery.getGt().getClass().getName(), numericRangeQuery.getGt() instanceof Double);
353 "Unexpected type for 'lte' value. Expected: Double Actual: "
354 + numericRangeQuery.getLte().getClass().getName(),
355 numericRangeQuery.getLte() instanceof Double);
357 assertEquals("Unexpected marshalled value for 'gt'. Expected: " + greaterThanDouble + " Actual: "
358 + numericRangeQuery.getGt(), greaterThanDouble, numericRangeQuery.getGt());
360 assertEquals("Unexpected marshalled value for 'lte'. Expected: " + lessThanDouble + " Actual: "
361 + numericRangeQuery.getLte(), lessThanDouble, numericRangeQuery.getLte());
364 "Unexpected ElasticSearch syntax. Expected: " + numericRangeExpectedES + " Actual: "
365 + numericRangeQuery.toElasticSearch(),
366 numericRangeExpectedES.equals(numericRangeQuery.toElasticSearch()));