/* (c) 2017 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.opensearch.eo.kvp;
import static org.geoserver.opensearch.eo.OpenSearchParameters.*;
import static org.geoserver.opensearch.eo.kvp.SearchRequestKvpReader.COUNT_KEY;
import static org.geoserver.opensearch.eo.kvp.SearchRequestKvpReader.PARENT_ID_KEY;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.Matchers.hasEntry;
import static org.hamcrest.Matchers.instanceOf;
import static org.junit.Assert.*;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.geoserver.opensearch.eo.OSEOInfo;
import org.geoserver.opensearch.eo.OSEOTestSupport;
import org.geoserver.opensearch.eo.OpenSearchParameters;
import org.geoserver.opensearch.eo.SearchRequest;
import org.geoserver.opensearch.eo.store.OpenSearchAccess;
import org.geoserver.platform.GeoServerExtensions;
import org.geoserver.platform.OWS20Exception;
import org.geotools.data.Parameter;
import org.geotools.data.Query;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.filter.text.ecql.ECQL;
import org.geotools.util.Converters;
import org.junit.Before;
import org.junit.Test;
import org.opengis.filter.And;
import org.opengis.filter.BinaryComparisonOperator;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory2;
import org.opengis.filter.Or;
import org.opengis.filter.PropertyIsEqualTo;
import org.opengis.filter.PropertyIsGreaterThan;
import org.opengis.filter.PropertyIsGreaterThanOrEqualTo;
import org.opengis.filter.PropertyIsLessThan;
import org.opengis.filter.PropertyIsLessThanOrEqualTo;
import org.opengis.filter.expression.Literal;
import org.opengis.filter.expression.PropertyName;
import org.opengis.filter.spatial.BinarySpatialOperator;
import org.opengis.filter.spatial.Contains;
import org.opengis.filter.spatial.Disjoint;
import org.opengis.filter.spatial.Intersects;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.io.WKTReader;
public class SearchRequestKvpReaderTest extends OSEOTestSupport {
private SearchRequestKvpReader reader;
private static FilterFactory2 FF = CommonFactoryFinder.getFilterFactory2();
@Before
public void getReader() {
reader = GeoServerExtensions.bean(SearchRequestKvpReader.class);
}
private Map<String, String> toMap(String... kvp) {
Map params = new HashMap<>();
for (int i = 0; i < kvp.length; i += 2) {
String name = kvp[i];
String value = kvp[i + 1];
params.put(name, value);
}
return params;
}
private SearchRequest parseSearchRequest(Map<String, String> map) throws Exception {
return (SearchRequest) reader.read(reader.createRequest(), map, map);
}
@Test
public void testGetAll() throws Exception {
SearchRequest request = parseSearchRequest(Collections.emptyMap());
assertEquals(null, request.getParentId());
final Query query = request.getQuery();
assertNotNull(query);
assertEquals(Filter.INCLUDE, query.getFilter());
assertNull(query.getStartIndex());
assertEquals(OSEOInfo.DEFAULT_RECORDS_PER_PAGE, query.getMaxFeatures());
}
@Test
public void testParseSearchTerms() throws Exception {
final String searchTermsValue = "a b \"c and d\"";
Map<String, String> map = toMap(SEARCH_TERMS.key, searchTermsValue);
SearchRequest request = parseSearchRequest(map);
assertEquals(null, request.getParentId());
final Query query = request.getQuery();
assertNotNull(query);
final String expectedCql = "htmlDescription ILIKE '%a%' OR htmlDescription ILIKE '%b%' OR htmlDescription ILIKE '%c and d%'";
assertEquals(expectedCql, ECQL.toCQL(query.getFilter()));
Map<Parameter, String> searchParameters = request.getSearchParameters();
assertEquals(1, searchParameters.size());
assertThat(searchParameters, hasEntry(OpenSearchParameters.SEARCH_TERMS, searchTermsValue));
}
/**
* From spec the parameter keys are case sensitive, and unknown ones should be ignored
*/
@Test
public void testParseSearchTermsWrongCase() throws Exception {
Map<String, String> map = toMap(SEARCH_TERMS.key.toUpperCase(), "a b \"c and d\"");
SearchRequest request = parseSearchRequest(map);
assertEquals(null, request.getParentId());
final Query query = request.getQuery();
assertEquals(Filter.INCLUDE, query.getFilter());
}
@Test
public void testParseGeoUid() throws Exception {
Map<String, String> map = toMap(GEO_UID.key, "abcd");
SearchRequest request = parseSearchRequest(map);
assertEquals(null, request.getParentId());
final Query query = request.getQuery();
assertNotNull(query);
final String expectedCql = "identifier = 'abcd'";
assertEquals(expectedCql, ECQL.toCQL(query.getFilter()));
Map<Parameter, String> searchParameters = request.getSearchParameters();
assertEquals(1, searchParameters.size());
assertThat(searchParameters, hasEntry(OpenSearchParameters.GEO_UID, "abcd"));
}
@Test
public void testParseTimeBox() throws Exception {
Map<String, String> map = toMap(GEO_BOX.key, "10,20,30,40");
SearchRequest request = parseSearchRequest(map);
assertEquals(null, request.getParentId());
final Query query = request.getQuery();
assertNotNull(query);
final String expectedCql = "BBOX(, 10.0,20.0,30.0,40.0)";
assertEquals(expectedCql, ECQL.toCQL(query.getFilter()));
Map<Parameter, String> searchParameters = request.getSearchParameters();
assertEquals(1, searchParameters.size());
assertThat(searchParameters, hasEntry(OpenSearchParameters.GEO_BOX, "10,20,30,40"));
}
@Test
public void testParseBBoxWholeWorld() throws Exception {
Map<String, String> map = toMap(GEO_BOX.key, "-180,-90,180,90");
SearchRequest request = parseSearchRequest(map);
assertEquals(null, request.getParentId());
final Query query = request.getQuery();
assertNotNull(query);
final String expectedCql = "BBOX(, -180.0,-90.0,180.0,90.0)";
assertEquals(expectedCql, ECQL.toCQL(query.getFilter()));
}
@Test
public void testParseBBoxDatelineCrossing() throws Exception {
Map<String, String> map = toMap(GEO_BOX.key, "170,-90,-170,90");
SearchRequest request = parseSearchRequest(map);
assertEquals(null, request.getParentId());
final Query query = request.getQuery();
assertNotNull(query);
final String expectedCql = "BBOX(, 170.0,-90.0,180.0,90.0) OR BBOX(, -180.0,-90.0,-170.0,90.0)";
assertEquals(expectedCql, ECQL.toCQL(query.getFilter()));
}
@Test
public void testPaging() throws Exception {
Map<String, String> map = toMap(START_INDEX.key, "10", COUNT_KEY, "5");
SearchRequest request = parseSearchRequest(map);
assertEquals(null, request.getParentId());
final Query query = request.getQuery();
assertNotNull(query);
assertEquals(Filter.INCLUDE, query.getFilter());
assertEquals(9, (int) query.getStartIndex()); // from 1 based to 0 based
assertEquals(5, query.getMaxFeatures());
Map<Parameter, String> searchParameters = request.getSearchParameters();
assertEquals(2, searchParameters.size());
assertThat(searchParameters, hasEntry(OpenSearchParameters.START_INDEX, "10"));
// does not work but yet to figure out why
// assertThat(searchParameters, hasEntry(hasProperty("name", equalTo("count")), "5"));
}
@Test
public void testStartIndexNegative() throws Exception {
try {
parseSearchRequest(toMap(START_INDEX.key, "-10"));
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
}
}
@Test
public void testStartIndexNotNumber() throws Exception {
try {
parseSearchRequest(toMap(START_INDEX.key, "abc"));
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
}
}
@Test
public void testStartIndexFloat() throws Exception {
try {
parseSearchRequest(toMap(START_INDEX.key, "1.23"));
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
}
}
@Test
public void testCountIndexNegative() throws Exception {
try {
parseSearchRequest(toMap(COUNT_KEY, "-10"));
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
}
}
@Test
public void testCountIndexNotNumber() throws Exception {
try {
parseSearchRequest(toMap(COUNT_KEY, "abc"));
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
}
}
@Test
public void testCountTooBig() throws Exception {
try {
parseSearchRequest(toMap(COUNT_KEY, "1000"));
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
}
}
@Test
public void testCountIndexFloat() throws Exception {
try {
parseSearchRequest(toMap(COUNT_KEY, "1.23"));
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
}
}
@Test
public void testParentId() throws Exception {
Map<String, String> map = toMap(PARENT_ID_KEY, "SENTINEL2");
SearchRequest request = parseSearchRequest(map);
assertEquals("SENTINEL2", request.getParentId());
final Query query = request.getQuery();
assertNotNull(query);
// no filter here, the parent id needs to be translate to an internal identifier
assertEquals(Filter.INCLUDE, query.getFilter());
}
@Test
public void testDistanceFromPoint() throws Exception {
Map<String, String> map = toMap(GEO_LON.key, "12", GEO_LAT.key, "45", GEO_RADIUS.key, "20000");
SearchRequest request = parseSearchRequest(map);
final Query query = request.getQuery();
assertNotNull(query);
final String expectedCql = "DWITHIN(\"\", POINT (12 45), 20000.0, m)";
assertEquals(expectedCql, ECQL.toCQL(query.getFilter()));
}
@Test
public void testNegativeDistanceFromPoint() throws Exception {
try {
Map<String, String> map = toMap(GEO_LON.key, "12", GEO_LAT.key, "45", GEO_RADIUS.key, "-10");
parseSearchRequest(map);
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
}
}
@Test
public void testTimeRelationInvalid() throws Exception {
try {
Map<String, String> map = toMap(TIME_RELATION.key, "abcd");
parseSearchRequest(map);
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
assertEquals("timeRelation", e.getLocator());
}
}
@Test
public void testTimeRelationAlone() throws Exception {
try {
Map<String, String> map = toMap(TIME_RELATION.key, "intersects");
parseSearchRequest(map);
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
assertEquals("timeRelation", e.getLocator());
}
}
@Test
public void testTimeStartInvalid() throws Exception {
try {
Map<String, String> map = toMap(TIME_START.key, "abcd");
parseSearchRequest(map);
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
assertEquals(TIME_START.key, e.getLocator());
}
}
@Test
public void testTimeEndInvalid() throws Exception {
try {
Map<String, String> map = toMap(TIME_END.key, "abcd");
parseSearchRequest(map);
fail("Should have failed");
} catch (OWS20Exception e) {
assertEquals("InvalidParameterValue", e.getCode());
assertEquals(TIME_END.key, e.getLocator());
}
}
@Test
public void testTimeFilterStartOnly() throws Exception {
Map<String, String> map;
// intersection behavior, the features must overlap the provided range
map = toMap(TIME_START.key, "2010-09-01T00:00:00Z");
assertEquals(ECQL.toFilter("timeEnd >= 2010-09-01T00:00:00Z OR timeEnd IS NULL"), parseAndGetFilter(map));
// intersection behavior again, explicit
map = toMap(TIME_START.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "intersects");
assertEquals(ECQL.toFilter("timeEnd >= 2010-09-01T00:00:00Z OR timeEnd IS NULL"), parseAndGetFilter(map));
// contains (the feature must contain the requested interval)
map = toMap(TIME_START.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "contains");
assertEquals(ECQL.toFilter("timeStart <= 2010-09-01T00:00:00Z and timeEnd IS NULL"), parseAndGetFilter(map));
// during (the features are inside the requested interval)
map = toMap(TIME_START.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "during");
assertEquals(ECQL.toFilter("timeStart >= 2010-09-01T00:00:00Z"), parseAndGetFilter(map));
// disjoint (the features are outside the requested interval)
map = toMap(TIME_START.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "disjoint");
assertEquals(ECQL.toFilter("timeEnd < 2010-09-01T00:00:00Z"), parseAndGetFilter(map));
// equal (the features have the same interval of validity
map = toMap(TIME_START.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "equals");
assertEquals(ECQL.toFilter("timeStart = 2010-09-01T00:00:00Z and timeEnd IS NULL"), parseAndGetFilter(map));
}
@Test
public void testTimeFilterEndOnly() throws Exception {
Map<String, String> map;
// intersection behavior, the features must overlap the provided range
map = toMap(TIME_END.key, "2010-09-01T00:00:00Z");
assertEquals(ECQL.toFilter("timeStart <= 2010-09-01T00:00:00Z OR timeStart IS NULL"), parseAndGetFilter(map));
// intersection behavior again, explicit
map = toMap(TIME_END.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "intersects");
assertEquals(ECQL.toFilter("timeStart <= 2010-09-01T00:00:00Z OR timeStart IS NULL"), parseAndGetFilter(map));
// contains (the feature must contain the requested interval)
map = toMap(TIME_END.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "contains");
assertEquals(ECQL.toFilter("timeEnd >= 2010-09-01T00:00:00Z and timeStart IS NULL"), parseAndGetFilter(map));
// during (the features are inside the requested interval)
map = toMap(TIME_END.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "during");
assertEquals(ECQL.toFilter("timeEnd <= 2010-09-01T00:00:00Z"), parseAndGetFilter(map));
// disjoint (the features are outside the requested interval)
map = toMap(TIME_END.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "disjoint");
assertEquals(ECQL.toFilter("timeStart > 2010-09-01T00:00:00Z"), parseAndGetFilter(map));
// equal (the features have the same interval of validity
map = toMap(TIME_END.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "equals");
assertEquals(ECQL.toFilter("timeEnd = 2010-09-01T00:00:00Z and timeStart IS NULL"), parseAndGetFilter(map));
}
@Test
public void testTimeFilterStartEndOnly() throws Exception {
Map<String, String> map;
// intersection behavior, the features must overlap the provided range
map = toMap(TIME_START.key, "2010-08-01T00:00:00Z", TIME_END.key, "2010-09-01T00:00:00Z");
assertEquals(ECQL.toFilter("(timeStart <= 2010-09-01T00:00:00Z or timeStart IS NULL) AND (timeEnd >= 2010-08-01T00:00:00Z or timeEnd IS NULL)"), parseAndGetFilter(map));
// intersection behavior again, explicit
map = toMap(TIME_START.key, "2010-08-01T00:00:00Z", TIME_END.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "intersects");
assertEquals(ECQL.toFilter("(timeStart <= 2010-09-01T00:00:00Z or timeStart IS NULL) AND (timeEnd >= 2010-08-01T00:00:00Z or timeEnd IS NULL)"), parseAndGetFilter(map));
// contains (the feature must contain the requested interval)
map = toMap(TIME_START.key, "2010-08-01T00:00:00Z", TIME_END.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "contains");
assertEquals(ECQL.toFilter("timeStart <= 2010-08-01T00:00:00Z and timeEnd >= 2010-09-01T00:00:00Z"), parseAndGetFilter(map));
// during (the features are inside the requested interval)
map = toMap(TIME_START.key, "2010-08-01T00:00:00Z", TIME_END.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "during");
assertEquals(ECQL.toFilter("timeStart >= 2010-08-01T00:00:00Z and timeEnd <= 2010-09-01T00:00:00Z"), parseAndGetFilter(map));
// disjoint (the features are outside the requested interval)
map = toMap(TIME_START.key, "2010-08-01T00:00:00Z", TIME_END.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "disjoint");
assertEquals(ECQL.toFilter("timeStart > 2010-09-01T00:00:00Z or timeEnd < 2010-08-01T00:00:00Z"), parseAndGetFilter(map));
// equal (the features have the same interval of validity
map = toMap(TIME_START.key, "2010-08-01T00:00:00Z", TIME_END.key, "2010-09-01T00:00:00Z", TIME_RELATION.key, "equals");
assertEquals(ECQL.toFilter("timeStart = 2010-08-01T00:00:00Z and timeEnd = 2010-09-01T00:00:00Z"), parseAndGetFilter(map));
}
@Test
public void testTimeStartOnlyDate() throws Exception {
Map<String, String> map;
// intersection behavior, the features must overlap the provided range
map = toMap(TIME_START.key, "2010-09-01");
assertEquals(ECQL.toFilter("timeEnd >= 2010-09-01T00:00:00Z OR timeEnd IS NULL"), parseAndGetFilter(map));
}
@Test
public void testCollectionSensorTypeSingle() throws Exception {
Map<String, String> map = toMap("sensorType", "OPTICAL");
Filter filter = parseAndGetFilter(map);
assertThat(filter, instanceOf(PropertyIsEqualTo.class));
assertBinaryFilter(filter, OpenSearchAccess.EO_NAMESPACE, "sensorType", "OPTICAL");
}
private void assertBinaryFilter(Filter filter, String expectedNamespace, String expectedName, Object expectedValue) {
BinaryComparisonOperator bce = (BinaryComparisonOperator) filter;
assertThat(bce.getExpression1(), instanceOf(PropertyName.class));
PropertyName pn = (PropertyName) bce.getExpression1();
assertEquals(expectedName, pn.getPropertyName());
assertEquals(expectedNamespace, pn.getNamespaceContext().getURI(""));
assertThat(bce.getExpression2(), instanceOf(Literal.class));
assertEquals(expectedValue, bce.getExpression2().evaluate(null));
}
@Test
public void testCollectionSensorTypeList() throws Exception {
Map<String, String> map = toMap("sensorType", "OPTICAL,RADAR,ALTIMETRIC");
Filter filter = parseAndGetFilter(map);
assertThat(filter, instanceOf(Or.class));
Or or = (Or) filter;
final List<Filter> children = or.getChildren();
assertEquals(3, children.size());
assertBinaryFilter(children.get(0), OpenSearchAccess.EO_NAMESPACE, "sensorType", "OPTICAL");
assertBinaryFilter(children.get(1), OpenSearchAccess.EO_NAMESPACE, "sensorType", "RADAR");
assertBinaryFilter(children.get(2), OpenSearchAccess.EO_NAMESPACE, "sensorType", "ALTIMETRIC");
}
@Test
public void testCloudCoverEmpty() throws Exception {
Map<String, String> map = toMap("parentId", "SENTINEL2", "cloudCover", "");
Filter filter = parseAndGetFilter(map);
assertThat(filter, equalTo(Filter.INCLUDE));
}
@Test
public void testCloudCoverGreater() throws Exception {
Map<String, String> map = toMap("parentId", "SENTINEL2", "cloudCover", "[30");
Filter filter = parseAndGetFilter(map);
assertThat(filter, instanceOf(PropertyIsGreaterThanOrEqualTo.class));
assertBinaryFilter(filter, OpenSearchAccess.ProductClass.OPTICAL.getNamespace(), "cloudCover", 30);
}
@Test
public void testCloudCoverSmaller() throws Exception {
Map<String, String> map = toMap("parentId", "SENTINEL2", "cloudCover", "20]");
Filter filter = parseAndGetFilter(map);
assertThat(filter, instanceOf(PropertyIsLessThanOrEqualTo.class));
assertBinaryFilter(filter, OpenSearchAccess.ProductClass.OPTICAL.getNamespace(), "cloudCover", 20);
}
@Test
public void testCloudCoverClosedRange() throws Exception {
Map<String, String> map = toMap("parentId", "SENTINEL2", "cloudCover", "[20,40]");
Filter filter = parseAndGetFilter(map);
assertThat(filter, instanceOf(And.class));
And and = (And) filter;
final List<Filter> children = and.getChildren();
assertEquals(2, children.size());
BinaryComparisonOperator op1 = (BinaryComparisonOperator) children.get(0);
assertThat(op1, instanceOf(PropertyIsGreaterThanOrEqualTo.class));
assertBinaryFilter(op1, OpenSearchAccess.ProductClass.OPTICAL.getNamespace(), "cloudCover", 20);
BinaryComparisonOperator op2 = (BinaryComparisonOperator) children.get(1);
assertThat(op2, instanceOf(PropertyIsLessThanOrEqualTo.class));
assertBinaryFilter(op2, OpenSearchAccess.ProductClass.OPTICAL.getNamespace(), "cloudCover", 40);
}
@Test
public void testCloudCoverOpenRange() throws Exception {
Map<String, String> map = toMap("parentId", "SENTINEL2", "cloudCover", "]20,40[");
Filter filter = parseAndGetFilter(map);
assertThat(filter, instanceOf(And.class));
And and = (And) filter;
final List<Filter> children = and.getChildren();
assertEquals(2, children.size());
BinaryComparisonOperator op1 = (BinaryComparisonOperator) children.get(0);
assertThat(op1, instanceOf(PropertyIsGreaterThan.class));
assertBinaryFilter(op1, OpenSearchAccess.ProductClass.OPTICAL.getNamespace(), "cloudCover", 20);
BinaryComparisonOperator op2 = (BinaryComparisonOperator) children.get(1);
assertThat(op2, instanceOf(PropertyIsLessThan.class));
assertBinaryFilter(op2, OpenSearchAccess.ProductClass.OPTICAL.getNamespace(), "cloudCover", 40);
}
@Test
public void testGeometryFilter() throws Exception {
String wkt = "POINT(0 0)";
Geometry point = new WKTReader().read(wkt);
// implicit relation
Filter filter = parseAndGetFilter(toMap("geometry", wkt));
assertThat(filter, instanceOf(Intersects.class));
assertBinarySpatialFilter(filter, "", point);
// explicit intersects
filter = parseAndGetFilter(toMap("geometry", wkt, "geoRelation", "intersects"));
assertThat(filter, instanceOf(Intersects.class));
assertBinarySpatialFilter(filter, "", point);
// explicit contains
filter = parseAndGetFilter(toMap("geometry", wkt, "geoRelation", "contains"));
assertThat(filter, instanceOf(Contains.class));
// ... expressions are inverted here, the attribute is contained in the search area
Contains bso = (Contains) filter;
assertThat(bso.getExpression2(), instanceOf(PropertyName.class));
PropertyName pn = (PropertyName) bso.getExpression2();
assertEquals("", pn.getPropertyName());
assertThat(bso.getExpression1(), instanceOf(Literal.class));
assertEquals(point, bso.getExpression1().evaluate(null));
// explict disjoint
filter = parseAndGetFilter(toMap("geometry", wkt, "geoRelation", "disjoint"));
assertThat(filter, instanceOf(Disjoint.class));
assertBinarySpatialFilter(filter, "", point);
}
private void assertBinarySpatialFilter(Filter filter, String expectedName, Object expectedValue) {
BinarySpatialOperator bso = (BinarySpatialOperator) filter;
assertThat(bso.getExpression1(), instanceOf(PropertyName.class));
PropertyName pn = (PropertyName) bso.getExpression1();
assertEquals(expectedName, pn.getPropertyName());
assertThat(bso.getExpression2(), instanceOf(Literal.class));
assertEquals(expectedValue, bso.getExpression2().evaluate(null));
}
@Test
public void testEopCreationDate() throws Exception {
Map<String, String> map = toMap("parentId", "SENTINEL2", "creationDate", "]2016-01-01");
Filter filter = parseAndGetFilter(map);
BinaryComparisonOperator op = (BinaryComparisonOperator) filter;
assertThat(op, instanceOf(PropertyIsGreaterThan.class));
assertBinaryFilter(op, OpenSearchAccess.ProductClass.EOP_GENERIC.getNamespace(), "creationDate", Converters.convert("2016-01-01", Date.class));
}
private Filter parseAndGetFilter(Map<String, String> map) throws Exception {
SearchRequest request = parseSearchRequest(map);
final Query query = request.getQuery();
assertNotNull(query);
Filter filter = query.getFilter();
return filter;
}
}