/**
* Copyright (c) Codice Foundation
* <p/>
* This is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
* General Public License as published by the Free Software Foundation, either version 3 of the
* License, or any later version.
* <p/>
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details. A copy of the GNU Lesser General Public License
* is distributed along with this program and can be found at
* <http://www.gnu.org/licenses/lgpl.html>.
*/
package ddf.catalog.source.opensearch;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Date;
import org.apache.cxf.jaxrs.client.WebClient;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
import org.junit.Test;
import org.opengis.filter.Filter;
import org.opengis.filter.sort.SortBy;
import org.opengis.filter.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ddf.catalog.data.Result;
import ddf.catalog.filter.impl.SortByImpl;
import ddf.catalog.impl.filter.SpatialDistanceFilter;
import ddf.catalog.impl.filter.SpatialFilter;
import ddf.catalog.impl.filter.TemporalFilter;
import ddf.catalog.operation.Query;
import ddf.catalog.operation.impl.QueryImpl;
public class TestOpenSearchSiteUtil {
private static final Logger LOGGER = LoggerFactory.getLogger(TestOpenSearchSiteUtil.class);
private final StringBuilder url = new StringBuilder(
"http://localhost:8080/services/catalog/query");
@Test
public void populateContextual() {
String searchPhrase = "TestQuery123";
assertTrue(url.indexOf(OpenSearchSiteUtil.SEARCH_TERMS) != -1);
WebClient webClient = WebClient.create(url.toString());
OpenSearchSiteUtil.populateContextual(webClient, searchPhrase, Arrays.asList(
"q,src,mr,start,count,mt,dn,lat,lon,radius,bbox,polygon,dtstart,dtend,dateName,filter,sort"
.split(",")));
String urlStr = webClient.getCurrentURI().toString();
assertTrue(urlStr.indexOf(searchPhrase) != -1);
assertTrue(urlStr.indexOf("?" + OpenSearchSiteUtil.SEARCH_TERMS) != -1);
try {
new URL(urlStr.toString());
} catch (MalformedURLException mue) {
fail("URL is not valid: " + mue.getMessage());
}
LOGGER.info("URL after contextual population: {}", urlStr.toString());
}
/**
* Verify that passing in null will still remove the parameters from the URL.
*/
@Test
public void populateNullContextual() {
WebClient webClient = WebClient.create(url.toString());
OpenSearchSiteUtil.populateContextual(webClient, null, Arrays.asList(
"q,src,mr,start,count,mt,dn,lat,lon,radius,bbox,polygon,dtstart,dtend,dateName,filter,sort"
.split(",")));
String urlStr = webClient.getCurrentURI().toString();
assertTrue(urlStr.indexOf("?" + OpenSearchSiteUtil.SEARCH_TERMS) == -1);
}
@Test
public void populateTemporal() {
// TODO have actual set time strings to compare to
DateTimeFormatter fmt = ISODateTimeFormat.dateTime();
Date start = new Date(System.currentTimeMillis() - 10000000);
Date end = new Date(System.currentTimeMillis());
StringBuilder resultStr = new StringBuilder(url);
TemporalFilter temporal = new TemporalFilter(start, end);
WebClient webClient = WebClient.create(url.toString());
OpenSearchSiteUtil.populateTemporal(webClient, temporal, Arrays.asList(
"q,src,mr,start,count,mt,dn,lat,lon,radius,bbox,polygon,dtstart,dtend,dateName,filter,sort"
.split(",")));
String urlStr = webClient.getCurrentURI().toString();
String startT = fmt.print(start.getTime());
try {
assertTrue(urlStr.indexOf(URLEncoder.encode(startT, "UTF-8")) != -1);
} catch (UnsupportedEncodingException e) {
fail(e.getMessage());
}
String endT = fmt.print(end.getTime());
try {
assertTrue(urlStr.indexOf(URLEncoder.encode(endT, "UTF-8")) != -1);
} catch (UnsupportedEncodingException e) {
fail(e.getMessage());
}
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.TIME_START) != -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.TIME_END) != -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.TIME_NAME) == -1);
try {
new URL(resultStr.toString());
} catch (MalformedURLException mue) {
fail("URL is not valid: " + mue.getMessage());
}
LOGGER.info("URL after temporal population: {}", resultStr.toString());
}
/**
* Verify that passing in null will still remove the parameters from the URL.
*/
@Test
public void populateNullTemporal() {
StringBuilder resultStr = new StringBuilder(url);
WebClient webClient = WebClient.create(url.toString());
OpenSearchSiteUtil.populateTemporal(webClient, null, Arrays.asList(
"q,src,mr,start,count,mt,dn,lat,lon,radius,bbox,polygon,dtstart,dtend,dateName,filter,sort"
.split(",")));
String urlStr = webClient.getCurrentURI().toString();
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.TIME_START) == -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.TIME_END) == -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.TIME_NAME) == -1);
}
@Test
public void populateSearchOptions() throws UnsupportedEncodingException {
String maxResults = "2000";
String timeout = "30000";
//this wasn't url encoded in the previous test, should have been
String sort = "date%3Adesc";
SortBy sortBy = new SortByImpl(Result.TEMPORAL, SortOrder.DESCENDING);
Filter filter = mock(Filter.class);
Query query = new QueryImpl(filter, 0, 2000, sortBy, true, 30000);
WebClient webClient = WebClient.create(url.toString());
OpenSearchSiteUtil.populateSearchOptions(webClient, query, null, Arrays.asList(
"q,src,mr,start,count,mt,dn,lat,lon,radius,bbox,polygon,dtstart,dtend,dateName,filter,sort"
.split(",")));
String urlStr = webClient.getCurrentURI().toString();
assertTrue(urlStr.indexOf(maxResults) != -1);
assertTrue(urlStr.indexOf(timeout) != -1);
assertThat(urlStr, containsString(sort));
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.COUNT) != -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.MAX_RESULTS) != -1);
//src is handled when the params are added to the url
// assertTrue(urlStr.indexOf(OpenSearchSiteUtil.SRC) != -1);
// assertTrue(urlStr.indexOf(OpenSearchSiteUtil.USER_DN) != -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.MAX_TIMEOUT) != -1);
//filter isn't even used, removed from test
// assertTrue(urlStr.indexOf(OpenSearchSiteUtil.FILTER) != -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.SORT) != -1);
}
/**
* Verify that passing in null will still remove the parameters from the URL.
*/
@Test
public void populateNullSearchOptions() {
WebClient webClient = WebClient.create(url.toString());
OpenSearchSiteUtil.populateSearchOptions(webClient, null, null, Arrays.asList(
"q,src,mr,start,count,mt,dn,lat,lon,radius,bbox,polygon,dtstart,dtend,dateName,filter,sort"
.split(",")));
String urlStr = webClient.getCurrentURI().toString();
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.COUNT) == -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.MAX_RESULTS) == -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.SRC) == -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.USER_DN) == -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.MAX_TIMEOUT) == -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.FILTER) == -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.SORT) == -1);
}
@Test
public void convertWKTtoLatLonAry() {
String lat = "43.25";
String lon = "-123.45";
String wktPoint = "POINT(" + lon + " " + lat + ")";
String[] latLonAry = OpenSearchSiteUtil.createLatLonAryFromWKT(wktPoint);
assertEquals(2, latLonAry.length);
assertEquals(lon, latLonAry[0]);
assertEquals(lat, latLonAry[1]);
}
@Test
public void convertWKTtoPolyAry() {
String lat[] = new String[] {"1", "1", "5", "5", "1"};
String lon[] = new String[] {"1", "5", "5", "1", "1"};
// TODO make the poly string programatically from the above arrays
String wktPolygon = "POLYGON((1 1,5 1,5 5,1 5,1 1))";
String[] polyAry = OpenSearchSiteUtil.createPolyAryFromWKT(wktPolygon);
assertEquals(lat.length + lon.length, polyAry.length);
for (int i = 0; i < polyAry.length; i++) {
if (i % 2 == 0) {
assertEquals(lon[i / 2], polyAry[i]);
} else {
assertEquals(lat[(int) Math.round((double) i / 2.0) - 1], polyAry[i]);
}
}
}
@Test
public void convertWKTtoPolyArySpaces() {
String lat[] = new String[] {"10", "30", "30", "10", "-10", "10"};
String lon[] = new String[] {"0", "0", "20", "20", "10", "0"};
String wktPolygon = "POLYGON((0 10, 0 30, 20 30, 20 10, 10 -10, 0 10))";
String[] polyAry = OpenSearchSiteUtil.createPolyAryFromWKT(wktPolygon);
assertEquals(lat.length + lon.length, polyAry.length);
for (int i = 0; i < polyAry.length; i++) {
if (i % 2 == 0) {
assertEquals(lon[i / 2], polyAry[i]);
} else {
assertEquals(lat[(int) Math.round((double) i / 2.0) - 1], polyAry[i]);
}
}
}
@Test
public void populatePolyGeospatial() throws Exception {
String wktPolygon = "POLYGON((1 1,5 1,5 5,1 5,1 1))";
String expectedStr = "1,1,1,5,5,5,5,1,1,1";
SpatialFilter spatial = new SpatialFilter(wktPolygon);
WebClient webClient = WebClient.create(url.toString());
OpenSearchSiteUtil.populateGeospatial(webClient, spatial, false, Arrays.asList(
"q,src,mr,start,count,mt,dn,lat,lon,radius,bbox,polygon,dtstart,dtend,dateName,filter,sort"
.split(",")));
String urlStr = webClient.getCurrentURI().toString();
assertTrue(urlStr.indexOf(expectedStr) != -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.GEO_POLY) != -1);
}
@Test
public void populateLatLonRadGeospatial() throws Exception {
String lat = "43.25";
String lon = "-123.45";
String radius = "10000";
String wktPoint = "POINT(" + lon + " " + lat + ")";
SpatialDistanceFilter spatial = new SpatialDistanceFilter(wktPoint, radius);
WebClient webClient = WebClient.create(url.toString());
OpenSearchSiteUtil.populateGeospatial(webClient, spatial, false, Arrays.asList(
"q,src,mr,start,count,mt,dn,lat,lon,radius,bbox,polygon,dtstart,dtend,dateName,filter,sort"
.split(",")));
String urlStr = webClient.getCurrentURI().toString();
assertTrue(urlStr.indexOf(lat) != -1);
assertTrue(urlStr.indexOf(lon) != -1);
assertTrue(urlStr.indexOf(radius) != -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.GEO_LAT) != -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.GEO_LON) != -1);
assertTrue(urlStr.indexOf(OpenSearchSiteUtil.GEO_RADIUS) != -1);
try {
new URL(urlStr.toString());
} catch (MalformedURLException mue) {
fail("URL is not valid: " + mue.getMessage());
}
LOGGER.info("URL after lat lon geospatial population: {}", urlStr.toString());
}
/**
* Verify that passing in null will still remove the parameters from the URL.
*/
@Test
public void populateNullGeospatial() throws Exception {
SpatialDistanceFilter spatial = null;
WebClient webClient = WebClient.create(url.toString());
OpenSearchSiteUtil.populateGeospatial(webClient, spatial, true, Arrays.asList(
"q,src,mr,start,count,mt,dn,lat,lon,radius,bbox,polygon,dtstart,dtend,dateName,filter,sort"
.split(",")));
URI urlStr = webClient.getCurrentURI();
assertTrue(urlStr.toString().indexOf(OpenSearchSiteUtil.GEO_LAT) == -1);
assertTrue(urlStr.toString().indexOf(OpenSearchSiteUtil.GEO_LON) == -1);
assertTrue(urlStr.toString().indexOf(OpenSearchSiteUtil.GEO_RADIUS) == -1);
}
@Test
public void convertPointRadiusToBBox() {
double lat = 30;
double lon = 15;
double radius = 200000;
double[] bbox = OpenSearchSiteUtil.createBBoxFromPointRadius(lon, lat, radius);
LOGGER.info("minX = " + bbox[0]);
assertEquals(3.3531, bbox[0], 0.0001);
LOGGER.info("minY = " + bbox[1]);
assertEquals(28.2034, bbox[1], 0.0001);
LOGGER.info("maxX = " + bbox[2]);
assertEquals(26.6468, bbox[2], 0.0001);
LOGGER.info("maxY = " + bbox[3]);
assertEquals(31.7965, bbox[3], 0.0001);
}
}