/** * 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.solr; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.anyOf; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.greaterThanOrEqualTo; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.isIn; import static org.hamcrest.Matchers.lessThanOrEqualTo; import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.notNullValue; import static org.hamcrest.Matchers.nullValue; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.beans.XMLEncoder; import java.io.BufferedOutputStream; import java.io.Serializable; import java.net.URI; import java.util.AbstractMap.SimpleEntry; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.TimeZone; import java.util.TreeSet; import java.util.UUID; import javax.swing.border.BevelBorder; import org.apache.commons.io.output.ByteArrayOutputStream; import org.codice.solr.factory.impl.ConfigurationStore; import org.geotools.factory.CommonFactoryFinder; import org.geotools.factory.FactoryIteratorProvider; import org.geotools.factory.GeoTools; import org.geotools.filter.FilterFactoryImpl; import org.geotools.filter.FunctionFactory; import org.geotools.filter.SortByImpl; import org.geotools.geometry.jts.spatialschema.geometry.DirectPositionImpl; import org.geotools.geometry.jts.spatialschema.geometry.primitive.PointImpl; import org.geotools.referencing.crs.DefaultGeographicCRS; import org.geotools.styling.UomOgcMapping; import org.geotools.temporal.object.DefaultPeriodDuration; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.mockito.internal.util.collections.Sets; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory; import org.opengis.filter.sort.SortBy; import org.opengis.filter.sort.SortOrder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ddf.catalog.data.AttributeDescriptor; import ddf.catalog.data.ContentType; import ddf.catalog.data.Metacard; import ddf.catalog.data.Result; import ddf.catalog.data.impl.AttributeDescriptorImpl; import ddf.catalog.data.impl.AttributeImpl; import ddf.catalog.data.impl.BasicTypes; import ddf.catalog.data.impl.ContentTypeImpl; import ddf.catalog.data.impl.MetacardImpl; import ddf.catalog.data.impl.MetacardTypeImpl; import ddf.catalog.data.types.Core; import ddf.catalog.data.types.Validation; import ddf.catalog.impl.filter.GeoToolsFunctionFactory; import ddf.catalog.operation.CreateRequest; import ddf.catalog.operation.CreateResponse; import ddf.catalog.operation.DeleteRequest; import ddf.catalog.operation.DeleteResponse; import ddf.catalog.operation.Query; import ddf.catalog.operation.QueryRequest; import ddf.catalog.operation.SourceResponse; import ddf.catalog.operation.Update; import ddf.catalog.operation.UpdateRequest; import ddf.catalog.operation.UpdateResponse; import ddf.catalog.operation.impl.DeleteRequestImpl; import ddf.catalog.operation.impl.QueryImpl; import ddf.catalog.operation.impl.QueryRequestImpl; import ddf.catalog.operation.impl.UpdateRequestImpl; import ddf.catalog.source.IngestException; import ddf.catalog.source.UnsupportedQueryException; /** * Tests the {@link ddf.catalog.source.solr.SolrCatalogProvider}. */ public class SolrProviderTest extends SolrProviderTestCase { protected static final String SHOW_LOW_AIRPORT_POINT_WKT = "POINT (-110.00540924072266 34.265270233154297)"; protected static final String TAMPA_AIRPORT_POINT_WKT = "POINT (-82.533248901367188 27.975471496582031)"; protected static final String GULF_OF_GUINEA_POLYGON_WKT = "POLYGON ((1 1,2 1,2 2,1 2,1 1))"; protected static final String GULF_OF_GUINEA_MULTIPOLYGON_WKT = "MULTIPOLYGON (((1 1,2 1,2 2,1 2,1 1)), ((0 0,1 1,2 0,0 0)))"; protected static final String GULF_OF_GUINEA_LINESTRING_WKT = "LINESTRING (1 1,2 1)"; protected static final String GULF_OF_GUINEA_MULTILINESTRING_WKT = "MULTILINESTRING ((1 1, 2 1), (1 2, 0 0))"; protected static final String GULF_OF_GUINEA_POINT_WKT = "POINT (1 1)"; protected static final String GULF_OF_GUINEA_MULTIPOINT_WKT = "MULTIPOINT ((1 1), (0 0), (2 2))"; protected static final String GULF_OF_GUINEA_MULTIPOINT_SINGLE_WKT = "MULTIPOINT ((1 1))"; protected static final String GULF_OF_GUINEA_GEOMETRYCOLLECTION_WKT = "GEOMETRYCOLLECTION (" + GULF_OF_GUINEA_POINT_WKT + ", " + GULF_OF_GUINEA_LINESTRING_WKT + ", " + GULF_OF_GUINEA_MULTIPOLYGON_WKT + ")"; protected static final String ARABIAN_SEA_OVERLAPPING_GEOMETRYCOLLECTION_WKT = "GEOMETRYCOLLECTION (MULTIPOLYGON (((56 9, 64 9, 60 14, 56 9)), ((61 9, 69 9, 65 14, 61 9)), ((51 9, 59 9, 55 14, 51 9))), LINESTRING (50 8, 50 15, 70 15, 70 8, 50 8), MULTIPOINT ((62.5 14), (67.5 14), (57.5 14), (52.5 14)))"; protected static final String ARABIAN_SEA_POINT_WKT = "POINT (62.5 14)"; protected static final String LAS_VEGAS_POINT_WKT = "POINT (-115.136389 36.175)"; protected static final String MIDWAY_ISLANDS_POINT_WKT = "POINT (-177.372736 28.208365)"; protected static final String ACROSS_INTERNATIONAL_DATELINE_LARGE_CCW_WKT = "POLYGON ((175 30, 175 25, -175 25, -175 30, 175 30))"; protected static final String ACROSS_INTERNATIONAL_DATELINE_LARGE_CW_WKT = "POLYGON ((175 30, -175 30, -175 25, 175 25, 175 30))"; protected static final String ACROSS_INTERNATIONAL_DATELINE_SMALL_WKT = "POLYGON ((179.5 30, 179.5 29, -179.5 29, -179.5 30, 179.5 30))"; protected static final String PHOENIX_POINT_WKT = "POINT (-112.066667 33.45)"; protected static final String COUNTERCLOCKWISE_ARIZONA_RECTANGLE_WKT = "POLYGON ((-108.08349609374837 30.90222470517274, -108.08349609374837 37.45741810263027, -115.70800781249432 37.45741810263027, -115.70800781249432 30.90222470517274, -108.08349609374837 30.90222470517274))"; protected static final String CLOCKWISE_ARIZONA_RECTANGLE_WKT = "POLYGON ((-115.72998046874625 30.921076375385542, -115.72998046874625 37.47485808497204, -108.12744140624321 37.47485808497204, -108.12744140624321 30.921076375385542, -115.72998046874625 30.921076375385542))"; protected static final String ARIZONA_INTERSECTING_LINESTING_WKT = "LINESTRING (-115.33642578125 33.28662109375,-108.17333984375 35.83544921875)"; protected static final String ARIZONA_INTERSECTING_MULTILINESTING_WKT = "MULTILINESTRING ((-115.33642578125 33.28662109375,-108.17333984375 35.83544921875), (-119.15527356533 36.906984126196, -114.40917981533 39.455812251196, -117.22167981533 39.719484126196, -117.26562512783 39.719484126196))"; protected static final String FLAGSTAFF_AIRPORT_POINT_WKT = "POINT (-111.67121887207031 35.138454437255859)"; protected static final String PHOENIX_AND_LAS_VEGAS_MULTIPOINT_WKT = "MULTIPOINT ((-112.066667 33.45), (-115.136389 36.175))"; protected static final String ARIZONA_INTERSECTING_POLYGON_WKT = "POLYGON ((-116.26171901822 34.658206701279, -113.80078151822 38.261722326279, -110.15332058072 35.625003576279, -110.06542995572 33.251956701279, -113.97656276822 32.812503576279, -116.26171901822 34.658206701279))"; protected static final String ARIZONA_INTERSECTING_MULTIPOLYGON_WKT = "MULTIPOLYGON (((-116.26171901822 34.658206701279, -113.80078151822 38.261722326279, -110.15332058072 35.625003576279, -110.06542995572 33.251956701279, -113.97656276822 32.812503576279, -116.26171901822 34.658206701279)), ((-117.88085950283 35.588624751196, -117.66113294033 40.554445063696, -120.60546887783 37.654054438696, -117.88085950283 35.588624751196)))"; protected static final String ARIZONA_INTERSECTING_GEOMETRYCOLLECTION_WKT = "GEOMETRYCOLLECTION (" + FLAGSTAFF_AIRPORT_POINT_WKT + ", " + ARIZONA_INTERSECTING_LINESTING_WKT + ", " + ARIZONA_INTERSECTING_MULTIPOLYGON_WKT + ")"; protected static final String ARIZONA_POLYGON_WKT = "POLYGON ((-114.52062730304343 33.02770735822419, -114.55908930307925 33.03678235823264, -114.6099253031266 33.027002358223534, -114.63396730314898 33.03356735822965, -114.6451593031594 33.044412358239754, -114.66395130317692 33.038922358234636, -114.71135530322107 33.09538235828722, -114.70946330321931 33.122375358312354, -114.6781203031901 33.16725035835415, -114.6800513031919 33.224595358407555, -114.68771130319904 33.23925835842121, -114.67769330318971 33.268016358447994, -114.73542730324348 33.3057083584831, -114.70360330321384 33.352418358526606, -114.7249363032337 33.41105935858121, -114.64509230315934 33.419116358588724, -114.63057330314584 33.439425358607636, -114.621089303137 33.468599358634805, -114.59808630311556 33.48612735865113, -114.5870613031053 33.50944535867285, -114.52942030305162 33.56007335872, -114.5402473030617 33.58050735873903, -114.52717030304953 33.622136358777794, -114.52526330304775 33.66550435881818, -114.53643330305815 33.682735358834236, -114.49567630302019 33.70836935885811, -114.5102873030338 33.74320035889055, -114.50455830302846 33.7717143589171, -114.5211223030439 33.82603135896769, -114.51172230303513 33.84196535898253, -114.52096230304375 33.862926359002046, -114.49818830302253 33.925036359059895, -114.5256323030481 33.95241335908539, -114.51820830304118 33.96506335909717, -114.42898030295808 34.02984435915751, -114.42402930295347 34.07833235920266, -114.41016630294055 34.10265435922531, -114.32279930285918 34.1412973592613, -114.28536830282434 34.17123135928918, -114.23577630277813 34.186222359303144, -114.14991230269818 34.266979359378354, -114.12523030267519 34.272621359383606, -114.13412730268348 34.31454835942266, -114.15341530270143 34.33644735944305, -114.18208030272814 34.36520635946984, -114.2578423027987 34.40548835950735, -114.2833943028225 34.41206935951348, -114.30286530284062 34.43575435953554, -114.33263630286835 34.454873359553346, -114.3765073029092 34.45967935955782, -114.38386230291606 34.47708535957403, -114.3768283029095 34.536563359629426, -114.40974230294016 34.58372335967334, -114.43430230296303 34.59896335968754, -114.42227030295183 34.61089535969865, -114.46563730299222 34.70987335979083, -114.49780430302218 34.74475735982332, -114.52555330304801 34.74891135982719, -114.54204030306337 34.759958359837476, -114.5702173030896 34.83186035990444, -114.62726330314274 34.875533359945116, -114.63047530314574 34.919501359986064, -114.62100730313692 34.943609360008516, -114.63227630314742 34.997651360058846, -114.62106830313698 34.99891436006002, -114.63378030314881 35.041863360100024, -114.59563230311329 35.07605836013187, -114.6359093031508 35.11865536017154, -114.62644130314197 35.13390636018575, -114.58261630310116 35.132560360184485, -114.57225530309151 35.14006736019148, -114.56104030308107 35.17434636022341, -114.5595833030797 35.22018336026609, -114.58789030310608 35.304768360344866, -114.58958430310764 35.358378360394795, -114.64539630315963 35.450760360480835, -114.6722153031846 35.515754360541365, -114.64979230316374 35.54663736057013, -114.65313430316684 35.5848333606057, -114.63986630315449 35.611348360630394, -114.65406630316771 35.64658436066321, -114.66848630318114 35.65639936067235, -114.66509130317797 35.69309936070653, -114.68882030320007 35.73259536074332, -114.68273930319441 35.76470336077322, -114.68986730320105 35.84744236085027, -114.66246230317552 35.870960360872175, -114.66160030317472 35.88047336088104, -114.69927630320981 35.91161236091004, -114.7362123032442 35.987648360980856, -114.71767330322695 36.036758361026585, -114.72896630323746 36.058753361047074, -114.7281503032367 36.08596236107242, -114.71276130322238 36.10518136109032, -114.62161030313749 36.141966361124574, -114.59893530311636 36.13833536112119, -114.5305733030527 36.15509036113679, -114.46661330299312 36.1247113611085, -114.44394530297203 36.1210533611051, -114.38080330291321 36.15099136113298, -114.34423430287916 36.137480361120396, -114.31609530285294 36.11143836109614, -114.30385730284155 36.08710836107348, -114.30758730284502 36.06223336105032, -114.233472302776 36.01833136100943, -114.20676930275113 36.017255361008424, -114.12902330267872 36.04173036103122, -114.10777530265894 36.12109036110513, -114.04510530260056 36.19397836117301, -114.03739230259339 36.21602336119354, -114.04371630259928 36.84184936177639, -114.04393930259948 36.99653836192046, -112.89998330153409 36.99622736192016, -112.54252130120118 36.99799436192181, -112.23725830091688 36.995492361919474, -111.3561643000963 37.001709361925265, -110.7400632995225 37.002488361926, -110.48408929928411 37.003926361927334, -110.45223629925445 36.991746361915986, -109.99707629883055 36.99206736191629, -109.0484802979471 36.99664136192055, -109.0478462979465 35.99666436098925, -109.04664129794538 34.95464636001879, -109.04865229794726 34.59178035968085, -109.05034929794884 33.7833023589279, -109.050526297949 33.20516435838946, -109.05134629794976 32.779550357993074, -109.04949529794804 32.44204435767875, -109.04561529794442 31.34345335665561, -110.45257829925477 31.33766035665021, -111.07196429983162 31.335634356648328, -111.36952130010873 31.431531356737636, -113.32911130193375 32.04362135730769, -114.82176130332388 32.487169357720774, -114.80939430331236 32.6160443578408, -114.72204930323102 32.720857357938414, -114.71269530322232 32.7350133579516, -114.69404030320493 32.74142535795757, -114.60394230312102 32.72628535794347, -114.60352230312063 32.73588635795241, -114.57195930309123 32.73743935795386, -114.57221030309148 32.74882935796447, -114.56075130308079 32.74893635796457, -114.56158230308156 32.760753357975574, -114.54300430306427 32.76074935797557, -114.54318730306444 32.77123235798533, -114.53009530305225 32.7714113579855, -114.53507730305688 32.788047358000995, -114.52621930304863 32.80991235802135, -114.4614363029883 32.84542235805443, -114.47644430300228 32.9359083581387, -114.46838730299478 32.9777893581777, -114.52062730304343 33.02770735822419))"; protected static final String WEST_USA_CONTAINING_POLYGON_WKT = "POLYGON ((-125 49, -125 30, -100 30, -100 49, -125 49))"; protected static final String AIRPORT_QUERY_PHRASE = "Airport"; protected static final String TAMPA_QUERY_PHRASE = "Tampa"; protected static final String FLAGSTAFF_QUERY_PHRASE = "Flagstaff"; protected static final String PURCHASE_ORDER_QUERY_PHRASE = "Lawnmower"; protected static final String SAMPLE_CONTENT_TYPE_1 = "contentType1"; protected static final String SAMPLE_CONTENT_TYPE_2 = "contentType2"; protected static final String SAMPLE_CONTENT_TYPE_3 = "content-Type"; protected static final String SAMPLE_CONTENT_TYPE_4 = "ct1=3"; protected static final String SAMPLE_CONTENT_VERSION_1 = "version1"; protected static final String SAMPLE_CONTENT_VERSION_2 = "vers:ion2"; protected static final String SAMPLE_CONTENT_VERSION_3 = "DDFv20"; protected static final String SAMPLE_CONTENT_VERSION_4 = "vers+4"; protected static final String DEFAULT_TEST_ESCAPE = "\\"; protected static final String DEFAULT_TEST_SINGLE_WILDCARD = "?"; protected static final String DEFAULT_TEST_WILDCARD = "*"; protected static final long MINUTES_IN_MILLISECONDS = 60000; protected static final double METERS_PER_KM = 1000.0; protected static final int ONE_HIT = 1; private static final Logger LOGGER = LoggerFactory.getLogger(SolrProviderTest.class); @BeforeClass public static void setUp() { GeoTools.addFactoryIteratorProvider(new FactoryIteratorProvider() { @Override public <T> Iterator<T> iterator(Class<T> category) { if (FunctionFactory.class == category) { List<FunctionFactory> l = new LinkedList<>(); l.add(new GeoToolsFunctionFactory()); return (Iterator<T>) l.iterator(); } return null; } }); CommonFactoryFinder.reset(); } /** * Testing that you cannot instantiate with a null Solr client. */ @Test(expected = IllegalArgumentException.class) public void testSolrClientNull() { new SolrCatalogProvider(null, null, null); } /** * Testing that if we create a record, it is truly ingested and we can retrieve all the fields * we intend to be retrievable. * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testCreateOperation() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); create(metacard); FilterFactory filterFactory = new FilterFactoryImpl(); // SIMPLE TITLE SEARCH Filter filter = filterFactory.like(filterFactory.property(Metacard.TITLE), MockMetacard.DEFAULT_TITLE, DEFAULT_TEST_WILDCARD, DEFAULT_TEST_SINGLE_WILDCARD, DEFAULT_TEST_ESCAPE, false); QueryImpl query = new QueryImpl(filter); query.setStartIndex(1); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); List<Result> results = sourceResponse.getResults(); Metacard mResult = results.get(0) .getMetacard(); assertEquals(1, results.size()); assertNotNull(mResult.getId()); assertEquals(MockMetacard.DEFAULT_TITLE, mResult.getTitle()); assertEquals(MockMetacard.DEFAULT_LOCATION, mResult.getLocation()); assertEquals(MockMetacard.DEFAULT_TYPE, mResult.getContentTypeName()); assertEquals(MockMetacard.DEFAULT_VERSION, mResult.getContentTypeVersion()); assertNotNull(mResult.getMetadata()); assertThat(mResult.getMetadata(), containsString( "<title>Flagstaff Chamber of Commerce</title>")); assertTrue(!mResult.getMetadata() .isEmpty()); assertFalse(mResult.getCreatedDate() .after(new Date())); assertFalse(mResult.getModifiedDate() .after(new Date())); assertEquals(metacard.getEffectiveDate(), mResult.getEffectiveDate()); assertEquals(metacard.getExpirationDate(), mResult.getExpirationDate()); assertTrue(Arrays.equals(metacard.getThumbnail(), mResult.getThumbnail())); assertEquals(metacard.getLocation(), mResult.getLocation()); assertEquals(MASKED_ID, mResult.getSourceId()); // --- Simple KEYWORD SEARCH filter = filterFactory.like(filterFactory.property(Metacard.METADATA), MockMetacard.DEFAULT_TITLE, DEFAULT_TEST_WILDCARD, DEFAULT_TEST_SINGLE_WILDCARD, DEFAULT_TEST_ESCAPE, false); query = new QueryImpl(filter); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); results = sourceResponse.getResults(); mResult = results.get(0) .getMetacard(); assertEquals(1, results.size()); assertNotNull(mResult.getId()); assertEquals(MockMetacard.DEFAULT_TITLE, mResult.getTitle()); assertEquals(MockMetacard.DEFAULT_LOCATION, mResult.getLocation()); assertEquals(MockMetacard.DEFAULT_TYPE, mResult.getContentTypeName()); assertEquals(MockMetacard.DEFAULT_VERSION, mResult.getContentTypeVersion()); assertNotNull(mResult.getMetadata()); assertTrue(!mResult.getMetadata() .isEmpty()); assertFalse(mResult.getCreatedDate() .after(new Date())); assertFalse(mResult.getModifiedDate() .after(new Date())); assertEquals(metacard.getEffectiveDate(), mResult.getEffectiveDate()); assertEquals(metacard.getExpirationDate(), mResult.getExpirationDate()); assertTrue(Arrays.equals(metacard.getThumbnail(), mResult.getThumbnail())); assertEquals(metacard.getLocation(), mResult.getLocation()); assertEquals(MASKED_ID, mResult.getSourceId()); } @Test(expected = IngestException.class) public void testCreateOperationWithSourceIdNoId() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); metacard.setSourceId("ddfChild"); Date oneDayAgo = new DateTime().minusDays(1) .toDate(); metacard.setCreatedDate(oneDayAgo); metacard.setExpirationDate(oneDayAgo); metacard.setEffectiveDate(oneDayAgo); metacard.setModifiedDate(oneDayAgo); create(metacard); } @Test public void testCreateOperationWithSourceId() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); String id = UUID.randomUUID() .toString(); metacard.setId(id); metacard.setSourceId("ddfChild"); Date oneDayAgo = new DateTime().minusDays(1) .toDate(); metacard.setCreatedDate(oneDayAgo); metacard.setExpirationDate(oneDayAgo); metacard.setEffectiveDate(oneDayAgo); metacard.setModifiedDate(oneDayAgo); CreateResponse createResponse = create(metacard); Metacard createdMetacard = createResponse.getCreatedMetacards() .get(0); assertNotNull(createdMetacard.getId()); assertEquals(MockMetacard.DEFAULT_TITLE, createdMetacard.getTitle()); assertEquals(MockMetacard.DEFAULT_LOCATION, createdMetacard.getLocation()); assertEquals(MockMetacard.DEFAULT_TYPE, createdMetacard.getContentTypeName()); assertEquals(MockMetacard.DEFAULT_VERSION, createdMetacard.getContentTypeVersion()); assertNotNull(createdMetacard.getMetadata()); assertThat(createdMetacard.getMetadata(), containsString( "<title>Flagstaff Chamber of Commerce</title>")); assertThat(createdMetacard.getMetadata() .isEmpty(), is(not(true))); assertThat(createdMetacard.getCreatedDate(), is(oneDayAgo)); assertThat(createdMetacard.getModifiedDate(), is(oneDayAgo)); assertThat(createdMetacard.getEffectiveDate(), is(oneDayAgo)); assertThat(createdMetacard.getExpirationDate(), is(oneDayAgo)); assertTrue(Arrays.equals(metacard.getThumbnail(), createdMetacard.getThumbnail())); assertEquals(metacard.getLocation(), createdMetacard.getLocation()); assertThat(createdMetacard.getSourceId(), is(metacard.getSourceId())); // -------------------- FilterFactory filterFactory = new FilterFactoryImpl(); // SIMPLE TITLE SEARCH Filter filter = filterFactory.like(filterFactory.property(Metacard.TITLE), MockMetacard.DEFAULT_TITLE, DEFAULT_TEST_WILDCARD, DEFAULT_TEST_SINGLE_WILDCARD, DEFAULT_TEST_ESCAPE, false); QueryImpl query = new QueryImpl(filter); query.setStartIndex(1); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); List<Result> results = sourceResponse.getResults(); Metacard mResult = results.get(0) .getMetacard(); assertEquals(1, results.size()); assertNotNull(mResult.getId()); assertEquals(MockMetacard.DEFAULT_TITLE, mResult.getTitle()); assertEquals(MockMetacard.DEFAULT_LOCATION, mResult.getLocation()); assertEquals(MockMetacard.DEFAULT_TYPE, mResult.getContentTypeName()); assertEquals(MockMetacard.DEFAULT_VERSION, mResult.getContentTypeVersion()); assertNotNull(mResult.getMetadata()); assertThat(mResult.getMetadata(), containsString( "<title>Flagstaff Chamber of Commerce</title>")); assertThat(mResult.getMetadata() .isEmpty(), is(not(true))); assertThat(mResult.getCreatedDate(), is(oneDayAgo)); assertThat(mResult.getModifiedDate(), is(oneDayAgo)); assertThat(mResult.getEffectiveDate(), is(oneDayAgo)); assertThat(mResult.getExpirationDate(), is(oneDayAgo)); assertTrue(Arrays.equals(metacard.getThumbnail(), mResult.getThumbnail())); assertEquals(metacard.getLocation(), mResult.getLocation()); // assertThat(mResult.getSourceId(), is("ddf")); } /** * Tests what happens when the whole request is null. * * @throws IngestException * @throws UnsupportedQueryException */ @Test(expected = IngestException.class) public void testCreateNull() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); provider.create(null); fail(); } @Test public void testCreateNullList() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); CreateResponse response = provider.create(new CreateRequest() { @Override public boolean hasProperties() { return false; } @Override public Serializable getPropertyValue(String name) { return null; } @Override public Set<String> getPropertyNames() { return null; } @Override public Map<String, Serializable> getProperties() { return null; } @Override public boolean containsPropertyName(String name) { return false; } @Override public List<Metacard> getMetacards() { return null; } }); assertThat(response.getCreatedMetacards() .size(), is(0)); } @Test public void testCreatedDates() throws Exception { deleteAllIn(provider); /* ALL NULL */ MockMetacard mockMetacard = new MockMetacard(Library.getFlagstaffRecord()); mockMetacard.setEffectiveDate(null); mockMetacard.setExpirationDate(null); mockMetacard.setCreatedDate(null); mockMetacard.setModifiedDate(null); List<Metacard> list = Arrays.asList((Metacard) mockMetacard); CreateResponse createResponse = create(list); assertEquals(1, createResponse.getCreatedMetacards() .size()); Metacard createdMetacard = createResponse.getCreatedMetacards() .get(0); assertNotNull(createdMetacard.getId()); assertEquals(MockMetacard.DEFAULT_TITLE, createdMetacard.getTitle()); assertEquals(MockMetacard.DEFAULT_LOCATION, createdMetacard.getLocation()); assertEquals(MockMetacard.DEFAULT_TYPE, createdMetacard.getContentTypeName()); assertEquals(MockMetacard.DEFAULT_VERSION, createdMetacard.getContentTypeVersion()); assertNotNull(createdMetacard.getMetadata()); assertTrue(!createdMetacard.getMetadata() .isEmpty()); // DATES assertEquals(mockMetacard.getCreatedDate(), createdMetacard.getCreatedDate()); assertThat(createdMetacard.getCreatedDate(), nullValue()); assertEquals(mockMetacard.getModifiedDate(), createdMetacard.getModifiedDate()); assertThat(createdMetacard.getModifiedDate(), nullValue()); assertEquals(mockMetacard.getEffectiveDate(), createdMetacard.getEffectiveDate()); assertThat(createdMetacard.getEffectiveDate(), nullValue()); assertEquals(mockMetacard.getExpirationDate(), createdMetacard.getExpirationDate()); assertThat(createdMetacard.getExpirationDate(), nullValue()); assertTrue(Arrays.equals(mockMetacard.getThumbnail(), createdMetacard.getThumbnail())); assertEquals(mockMetacard.getLocation(), createdMetacard.getLocation()); assertEquals(MASKED_ID, createdMetacard.getSourceId()); } /** * Tests that multivalued attributes are stored and returned * * @throws UnsupportedQueryException * @throws IngestException */ @Test public void testCreateMultivaluedAttribute() throws UnsupportedQueryException, IngestException { deleteAllIn(provider); FilterFactory filterFactory = new FilterFactoryImpl(); MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); List<Serializable> a = new ArrayList<>(); a.add("sample-validator"); a.add("sample-validator2"); AttributeImpl attribute = new AttributeImpl(Validation.VALIDATION_WARNINGS, a); metacard.setAttribute(attribute); create(metacard); Filter filter = filterFactory.like(filterFactory.property(Metacard.TITLE), MockMetacard.DEFAULT_TITLE, DEFAULT_TEST_WILDCARD, DEFAULT_TEST_SINGLE_WILDCARD, DEFAULT_TEST_ESCAPE, false); QueryImpl query = new QueryImpl(filter); query.setStartIndex(1); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); List<Result> results = sourceResponse.getResults(); Metacard mResult = results.get(0) .getMetacard(); assertThat(mResult.getAttribute(Validation.VALIDATION_WARNINGS) .getValues() .size(), is(2)); } /** * Testing that if records are properly updated. * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testUpdateOperationSimple() throws IngestException, UnsupportedQueryException { // Single Update deleteAllIn(provider); MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); CreateResponse createResponse = create(metacard); String id = createResponse.getCreatedMetacards() .get(0) .getId(); metacard.setContentTypeName("newContentType"); UpdateResponse response = update(id, metacard); Update update = response.getUpdatedMetacards() .get(0); Metacard newMetacard = update.getNewMetacard(); Metacard oldMetacard = update.getOldMetacard(); assertEquals(1, response.getUpdatedMetacards() .size()); assertEquals("newContentType", newMetacard.getContentTypeName()); assertEquals(MockMetacard.DEFAULT_TYPE, oldMetacard.getContentTypeName()); } /** * Tests if a partial update is handled appropriately. * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testUpdatePartial() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); CreateResponse createResponse = create(metacard); String id = createResponse.getCreatedMetacards() .get(0) .getId(); metacard.setContentTypeName("newContentType"); String[] ids = {id, "no_such_record"}; UpdateResponse response = update(ids, Arrays.asList((Metacard) metacard, metacard)); assertEquals(1, response.getUpdatedMetacards() .size()); } /** * Tests what happens when the whole request is null. * * @throws IngestException * @throws UnsupportedQueryException */ @Test(expected = IngestException.class) public void testUpdateNull() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); provider.update(null); fail(); } /** * Tests null list in UpdateRequest * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testUpdateNullList() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); UpdateResponse response = provider.update(new UpdateRequestImpl(null, Metacard.ID, null)); assertEquals(0, response.getUpdatedMetacards() .size()); } /** * Tests empty list in UpdateRequest * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testUpdateEmptyList() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); UpdateResponse response = provider.update(new UpdateRequestImpl(new ArrayList<Entry<Serializable, Metacard>>(), Metacard.ID, null)); assertEquals(0, response.getUpdatedMetacards() .size()); } @Test public void testUpdateByMetacardId() throws Exception { deleteAllIn(provider); MockMetacard metacard1 = new MockMetacard(Library.getFlagstaffRecord()); MockMetacard metacard2 = new MockMetacard(Library.getShowLowRecord()); String uri1 = "http://youwillfindme.com/here"; String uri2 = "http://youwillfindme.com/there"; metacard1.setResourceURI(new URI(uri1)); metacard1.setContentTypeName("oldNitf"); metacard2.setResourceURI(new URI(uri2)); metacard2.setContentTypeName("oldNitf2"); metacard2.setResourceSize("25L"); List<Metacard> list = Arrays.asList((Metacard) metacard1, metacard2); CreateResponse createResponse = create(list); List<String> responseStrings = MockMetacard.toStringList(createResponse.getCreatedMetacards()); assertEquals(2, responseStrings.size()); /** UPDATE **/ MockMetacard updatedMetacard1 = new MockMetacard(Library.getTampaRecord()); MockMetacard updatedMetacard2 = new MockMetacard(Library.getFlagstaffRecord()); updatedMetacard1.setId(metacard1.getId()); updatedMetacard1.setContentTypeName("nitf"); updatedMetacard2.setId(metacard2.getId()); updatedMetacard2.setResourceURI(new URI(uri2)); updatedMetacard2.setContentTypeName("nitf2"); updatedMetacard2.setResourceSize("50L"); list = Arrays.asList((Metacard) updatedMetacard1, updatedMetacard2); String[] ids = {metacard1.getId(), metacard2.getId()}; UpdateResponse updateResponse = update(ids, list); assertEquals("Testing Update operation: ", 2, updateResponse.getUpdatedMetacards() .size()); List<Update> updatedMetacards = updateResponse.getUpdatedMetacards(); for (Update up : updatedMetacards) { Metacard newCard = up.getNewMetacard(); Metacard oldCard = up.getOldMetacard(); assertNotNull(oldCard.getResourceURI()); assertEquals(provider.getId(), oldCard.getSourceId()); assertEquals(provider.getId(), newCard.getSourceId()); if (oldCard.getContentTypeName() .equals("oldNitf")) { assertEquals("nitf", newCard.getContentTypeName()); // TPA is unique to the document assertTrue(newCard.getMetadata() .indexOf("TPA") != ALL_RESULTS); assertThat(newCard.getResourceURI(), is(nullValue())); assertThat(oldCard.getResourceURI() .toString(), equalTo(uri1)); assertEquals(oldCard.getId(), newCard.getId()); // Title assertEquals(MockMetacard.DEFAULT_TITLE, oldCard.getTitle()); assertEquals(MockMetacard.DEFAULT_TITLE, newCard.getTitle()); // Location (decimal points make them not exact Strings POINT(1 // 0) as opposed to POINT( 1.0 0.0) ) assertEquals(MockMetacard.DEFAULT_LOCATION.substring(0, 8), oldCard.getLocation() .substring(0, 8)); assertEquals(MockMetacard.DEFAULT_LOCATION.substring(0, 8), newCard.getLocation() .substring(0, 8)); // Metadata assertNotNull(oldCard.getMetadata()); assertNotNull(newCard.getMetadata()); assertTrue(!oldCard.getMetadata() .isEmpty()); assertTrue(!newCard.getMetadata() .isEmpty()); // Created Date assertFalse(oldCard.getCreatedDate() .after(new Date())); assertFalse(newCard.getCreatedDate() .after(new Date())); assertTrue(newCard.getCreatedDate() .after(oldCard.getCreatedDate())); // Modified Date assertTrue(newCard.getModifiedDate() .after(oldCard.getModifiedDate())); // Effective Date assertTrue(newCard.getEffectiveDate() .after(oldCard.getEffectiveDate())); // Expiration Date assertTrue(newCard.getExpirationDate() .after(oldCard.getExpirationDate())); // Thumbnail assertTrue(Arrays.equals(newCard.getThumbnail(), oldCard.getThumbnail())); } else if (oldCard.getContentTypeName() .equals("oldNitf2")) { assertEquals("nitf2", newCard.getContentTypeName()); // Cardinals is unique to the document assertTrue(newCard.getMetadata() .indexOf("Cardinals") != ALL_RESULTS); assertTrue("50L".equals(newCard.getResourceSize())); assertEquals(uri2, newCard.getResourceURI() .toString()); assertEquals(oldCard.getId(), newCard.getId()); // Title assertEquals(MockMetacard.DEFAULT_TITLE, oldCard.getTitle()); assertEquals(MockMetacard.DEFAULT_TITLE, newCard.getTitle()); // Location (decimal points make them not exact in Strings assertEquals(MockMetacard.DEFAULT_LOCATION.substring(0, 8), oldCard.getLocation() .substring(0, 8)); assertEquals(MockMetacard.DEFAULT_LOCATION.substring(0, 8), newCard.getLocation() .substring(0, 8)); // Metadata assertNotNull(oldCard.getMetadata()); assertNotNull(newCard.getMetadata()); assertTrue(!oldCard.getMetadata() .isEmpty()); assertTrue(!newCard.getMetadata() .isEmpty()); // Created Date assertFalse(oldCard.getCreatedDate() .after(new Date())); assertFalse(newCard.getCreatedDate() .after(new Date())); assertTrue(newCard.getCreatedDate() .after(oldCard.getCreatedDate())); // Modified Date assertTrue(newCard.getModifiedDate() .after(oldCard.getModifiedDate())); // Effective Date assertTrue(newCard.getEffectiveDate() .after(oldCard.getEffectiveDate())); // Expiration Date assertTrue(newCard.getExpirationDate() .after(oldCard.getExpirationDate())); // Thumbnail assertTrue(Arrays.equals(newCard.getThumbnail(), oldCard.getThumbnail())); } else { Assert.fail("Expecting one or the other of the updated records."); } } /** READ **/ CommonQueryBuilder builder = new CommonQueryBuilder(); QueryImpl query = builder.queryByProperty(Metacard.RESOURCE_URI, uri2); QueryRequestImpl queryRequest = new QueryRequestImpl(query); SourceResponse sourceResponse = provider.query(queryRequest); assertEquals(1, sourceResponse.getResults() .size()); for (Result r : sourceResponse.getResults()) { assertTrue(r.getMetacard() .getMetadata() .indexOf("Cardinals") != ALL_RESULTS); assertEquals(uri2, r.getMetacard() .getResourceURI() .toString()); } /** UPDATE with null thumbnail **/ updatedMetacard1.setThumbnail(null); updateResponse = update(updatedMetacard1.getId(), updatedMetacard1); assertEquals("Testing Update operation: ", 1, updateResponse.getUpdatedMetacards() .size()); Metacard newCard = updateResponse.getUpdatedMetacards() .get(0) .getNewMetacard(); Metacard oldCard = updateResponse.getUpdatedMetacards() .get(0) .getOldMetacard(); assertNotNull(oldCard.getThumbnail()); assertEquals(null, newCard.getThumbnail()); /** UPDATE with null WKT **/ // updatedMetacard1.setLocation(null); // updateResponse = provider.update(new // UpdateRequestImpl(updatedMetacard1.getId(), updatedMetacard1)); // // // // assertEquals("Testing Update operation: ", 1, // updateResponse.getUpdatedMetacards().size()); // // newCard = // updateResponse.getUpdatedMetacards().get(0).getNewMetacard(); // oldCard = // updateResponse.getUpdatedMetacards().get(0).getOldMetacard(); // // assertNotNull(oldCard.getResourceURI()); // assertNotNull(newCard.getResourceURI()); // assertEquals(oldCard.getResourceURI().toString(), // newCard.getResourceURI().toString()); // assertEquals(provider.getId(), oldCard.getSourceId()); // assertEquals(provider.getId(), newCard.getSourceId()); // LOGGER.info("New Metacard location: {}", newCard.getLocation()); // LOGGER.info("Old Metacard location: {}", oldCard.getLocation()); // assertTrue(oldCard.getLocation().contains("POINT")); // assertEquals(null, newCard.getLocation()); /** UPDATE with null expiration date **/ updatedMetacard1.setExpirationDate(null); updateResponse = update(updatedMetacard1.getId(), updatedMetacard1); assertEquals("Testing Update operation: ", ONE_HIT, updateResponse.getUpdatedMetacards() .size()); newCard = updateResponse.getUpdatedMetacards() .get(0) .getNewMetacard(); oldCard = updateResponse.getUpdatedMetacards() .get(0) .getOldMetacard(); assertNotNull(oldCard.getExpirationDate()); assertEquals(null, newCard.getExpirationDate()); /** UPDATE with null content type **/ updatedMetacard1.setContentTypeName(null); updateResponse = update(updatedMetacard1.getId(), updatedMetacard1); assertEquals("Testing Update operation: ", ONE_HIT, updateResponse.getUpdatedMetacards() .size()); newCard = updateResponse.getUpdatedMetacards() .get(0) .getNewMetacard(); oldCard = updateResponse.getUpdatedMetacards() .get(0) .getOldMetacard(); assertNotNull(oldCard.getContentTypeName()); assertThat(newCard.getContentTypeName(), nullValue()); /** UPDATE with empty content type **/ updatedMetacard1.setContentTypeName(""); updateResponse = update(updatedMetacard1.getId(), updatedMetacard1); assertEquals("Testing Update operation: ", ONE_HIT, updateResponse.getUpdatedMetacards() .size()); newCard = updateResponse.getUpdatedMetacards() .get(0) .getNewMetacard(); oldCard = updateResponse.getUpdatedMetacards() .get(0) .getOldMetacard(); assertThat(oldCard.getContentTypeName(), nullValue()); assertThat(newCard.getContentTypeName(), is("")); /** UPDATE with null content type version **/ updatedMetacard1.setContentTypeVersion(null); updateResponse = update(updatedMetacard1.getId(), updatedMetacard1); assertEquals("Testing Update operation: ", ONE_HIT, updateResponse.getUpdatedMetacards() .size()); newCard = updateResponse.getUpdatedMetacards() .get(0) .getNewMetacard(); oldCard = updateResponse.getUpdatedMetacards() .get(0) .getOldMetacard(); assertNotNull(oldCard.getContentTypeVersion()); assertThat(newCard.getContentTypeVersion(), nullValue()); /** UPDATE with empty content type version **/ updatedMetacard1.setContentTypeVersion(""); updateResponse = update(updatedMetacard1.getId(), updatedMetacard1); assertEquals("Testing Update operation: ", ONE_HIT, updateResponse.getUpdatedMetacards() .size()); newCard = updateResponse.getUpdatedMetacards() .get(0) .getNewMetacard(); oldCard = updateResponse.getUpdatedMetacards() .get(0) .getOldMetacard(); assertThat(oldCard.getContentTypeVersion(), nullValue()); assertThat(newCard.getContentTypeVersion(), is("")); /** UPDATE with new resource uri **/ updatedMetacard1.setResourceURI(new URI(uri1 + "Now")); updateResponse = update(updatedMetacard1.getId(), updatedMetacard1); assertEquals("Testing Update operation: ", ONE_HIT, updateResponse.getUpdatedMetacards() .size()); newCard = updateResponse.getUpdatedMetacards() .get(0) .getNewMetacard(); oldCard = updateResponse.getUpdatedMetacards() .get(0) .getOldMetacard(); assertThat(oldCard.getResourceURI(), is(nullValue())); assertEquals(uri1 + "Now", newCard.getResourceURI() .toString()); /** TEST NULL UPDATE **/ updateResponse = provider.update(new UpdateRequest() { @Override public boolean hasProperties() { return false; } @Override public Serializable getPropertyValue(String name) { return null; } @Override public Set<String> getPropertyNames() { return null; } @Override public Map<String, Serializable> getProperties() { return null; } @Override public boolean containsPropertyName(String name) { return false; } @Override public List<Entry<Serializable, Metacard>> getUpdates() { return null; } @Override public String getAttributeName() { return UpdateRequest.UPDATE_BY_ID; } }); assertTrue(updateResponse.getUpdatedMetacards() .isEmpty()); } /** * Testing that if no records are found to update, the provider returns an empty list. * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testUpdateOperationWithNoResults() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); UpdateResponse response = update("BAD_ID", metacard); assertEquals(0, response.getUpdatedMetacards() .size()); } /** * Testing update operation of alternative attribute. Should return positive results. * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testUpdateAlternativeAttribute() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); final MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); create(metacard); UpdateResponse response = provider.update(new UpdateRequest() { @Override public boolean hasProperties() { return false; } @Override public Serializable getPropertyValue(String name) { return null; } @Override public Set<String> getPropertyNames() { return null; } @Override public Map<String, Serializable> getProperties() { return null; } @Override public boolean containsPropertyName(String name) { return false; } @Override public List<Entry<Serializable, Metacard>> getUpdates() { MetacardImpl newMetacard = new MetacardImpl(metacard); newMetacard.setContentTypeName("newContentName"); List<Entry<Serializable, Metacard>> updateList = new ArrayList<Entry<Serializable, Metacard>>(); updateList.add(new SimpleEntry<Serializable, Metacard>(MockMetacard.DEFAULT_TITLE, newMetacard)); return updateList; } @Override public String getAttributeName() { return Metacard.TITLE; } }); Update update = response.getUpdatedMetacards() .get(0); assertThat(update.getNewMetacard() .getId(), is(equalTo(update.getOldMetacard() .getId()))); assertEquals(1, response.getUpdatedMetacards() .size()); } /** * Tests if we catch properly the case that the attribute value matches multiple Metacards. * * @throws IngestException * @throws UnsupportedQueryException */ @Test(expected = IngestException.class) public void testUpdateNonUniqueAttributeValue() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); MockMetacard m1 = new MockMetacard(Library.getFlagstaffRecord()); MockMetacard m2 = new MockMetacard(Library.getFlagstaffRecord()); MockMetacard m3 = new MockMetacard(Library.getFlagstaffRecord()); List<Metacard> list = Arrays.asList((Metacard) m1, m2, m3); create(list); provider.update(new UpdateRequest() { @Override public boolean hasProperties() { return false; } @Override public Serializable getPropertyValue(String name) { return null; } @Override public Set<String> getPropertyNames() { return null; } @Override public Map<String, Serializable> getProperties() { return null; } @Override public boolean containsPropertyName(String name) { return false; } @Override public List<Entry<Serializable, Metacard>> getUpdates() { MockMetacard newMetacard = new MockMetacard(Library.getShowLowRecord()); List<Entry<Serializable, Metacard>> updateList = new ArrayList<Entry<Serializable, Metacard>>(); updateList.add(new SimpleEntry<Serializable, Metacard>(MockMetacard.DEFAULT_TITLE, newMetacard)); return updateList; } @Override public String getAttributeName() { return Metacard.TITLE; } }); } /** * Tests if we catch a rare case where some attribute value match multiple Metacards while * others do not match any records. * * @throws IngestException * @throws UnsupportedQueryException */ @Test(expected = IngestException.class) public void testUpdateNonUniqueAttributeValue2() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); MockMetacard m1 = new MockMetacard(Library.getFlagstaffRecord()); MockMetacard m2 = new MockMetacard(Library.getFlagstaffRecord()); List<Metacard> list = Arrays.asList((Metacard) m1, m2); create(list); provider.update(new UpdateRequest() { @Override public boolean hasProperties() { return false; } @Override public Serializable getPropertyValue(String name) { return null; } @Override public Set<String> getPropertyNames() { return null; } @Override public Map<String, Serializable> getProperties() { return null; } @Override public boolean containsPropertyName(String name) { return false; } @Override public List<Entry<Serializable, Metacard>> getUpdates() { MockMetacard newMetacard = new MockMetacard(Library.getShowLowRecord()); List<Entry<Serializable, Metacard>> updateList = new ArrayList<Entry<Serializable, Metacard>>(); updateList.add(new SimpleEntry<Serializable, Metacard>(MockMetacard.DEFAULT_TITLE, newMetacard)); updateList.add(new SimpleEntry<Serializable, Metacard>(TAMPA_QUERY_PHRASE, newMetacard)); return updateList; } @Override public String getAttributeName() { return Metacard.TITLE; } }); } /** * Testing update operation of unknown attribute. Should return no results. * * @throws IngestException * @throws UnsupportedQueryException */ public void testUpdateUnknownAttribute() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); UpdateResponse response = provider.update(new UpdateRequest() { @Override public boolean hasProperties() { return false; } @Override public Serializable getPropertyValue(String name) { return null; } @Override public Set<String> getPropertyNames() { return null; } @Override public Map<String, Serializable> getProperties() { return null; } @Override public boolean containsPropertyName(String name) { return false; } @Override public List<Entry<Serializable, Metacard>> getUpdates() { MockMetacard newMetacard = new MockMetacard(Library.getShowLowRecord()); List<Entry<Serializable, Metacard>> updateList = new ArrayList<Entry<Serializable, Metacard>>(); updateList.add(new SimpleEntry<Serializable, Metacard>(MockMetacard.DEFAULT_TITLE, newMetacard)); return updateList; } @Override public String getAttributeName() { return "dataAccess"; } }); assertEquals(0, response.getUpdatedMetacards() .size()); } /** * Testing if exception is thrown with a <code>null</code> property. * * @throws IngestException */ @Test(expected = IngestException.class) public void testUpdateNullAttribute() throws IngestException, UnsupportedQueryException { provider.update(new UpdateRequest() { @Override public boolean hasProperties() { return false; } @Override public Serializable getPropertyValue(String name) { return null; } @Override public Set<String> getPropertyNames() { return null; } @Override public Map<String, Serializable> getProperties() { return null; } @Override public boolean containsPropertyName(String name) { return false; } @Override public List<Entry<Serializable, Metacard>> getUpdates() { return null; } @Override public String getAttributeName() { return null; } }); } /** * Testing that if records are properly deleted. * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testDeleteOperation() throws IngestException, UnsupportedQueryException { // Single Deletion deleteAllIn(provider); MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); CreateResponse createResponse = create(metacard); DeleteResponse deleteResponse = delete(createResponse.getCreatedMetacards() .get(0) .getId()); Metacard deletedMetacard = deleteResponse.getDeletedMetacards() .get(0); verifyDeletedRecord(metacard, createResponse, deleteResponse, deletedMetacard); } @Test public void testDeleteList() throws IngestException, UnsupportedQueryException { int metacardCount = 20; addAndDeleteMetacards(metacardCount); } @Test public void testDeleteLargeList() throws IngestException, UnsupportedQueryException { int metacardCount = 2000; addAndDeleteMetacards(metacardCount); } private void addAndDeleteMetacards(int metacardCount) throws IngestException, UnsupportedQueryException { deleteAllIn(provider); List<Metacard> metacards = new ArrayList<Metacard>(); for (int i = 0; i < metacardCount; i++) { metacards.add(new MockMetacard(Library.getFlagstaffRecord())); } CreateResponse createResponse = create(metacards); assertThat(createResponse.getCreatedMetacards() .size(), is(metacards.size())); List<String> ids = new ArrayList<String>(); for (Metacard mc : createResponse.getCreatedMetacards()) { ids.add(mc.getId()); } DeleteResponse deleteResponse = delete(ids.toArray(new String[metacardCount])); List<Metacard> deletedMetacards = deleteResponse.getDeletedMetacards(); assertThat(deletedMetacards.size(), is(metacards.size())); for (int i = 0; i < metacardCount; i++) { assertThat(deletedMetacards.get(i) .getId(), isIn(ids)); } } /** * Tests what happens when the whole request is null. * * @throws IngestException * @throws UnsupportedQueryException */ @Test(expected = IngestException.class) public void testDeleteNull() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); provider.delete(null); fail(); } /** * Tests the provider will allow you to delete nothing. * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testDeleteNothing() throws IngestException, UnsupportedQueryException { // Single Deletion deleteAllIn(provider); DeleteResponse deleteResponse = delete("no_such_record"); assertThat(deleteResponse.getDeletedMetacards() .size(), equalTo(0)); } /** * Testing if another attribute can be used to delete records other than {@link Metacard#ID} * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testDeleteAlternativeAttribute() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); CreateResponse createResponse = create(metacard); DeleteResponse deleteResponse = provider.delete(new DeleteRequest() { @Override public boolean hasProperties() { return false; } @Override public Serializable getPropertyValue(String name) { return null; } @Override public Set<String> getPropertyNames() { return null; } @Override public Map<String, Serializable> getProperties() { return null; } @Override public boolean containsPropertyName(String name) { return false; } @Override public List<? extends Serializable> getAttributeValues() { return Arrays.asList(MockMetacard.DEFAULT_TITLE); } @Override public String getAttributeName() { return Metacard.TITLE; } }); Metacard deletedMetacard = deleteResponse.getDeletedMetacards() .get(0); verifyDeletedRecord(metacard, createResponse, deleteResponse, deletedMetacard); // verify it is really not in SOLR Filter filter = filterBuilder.attribute(Metacard.TITLE) .like() .text(MockMetacard.DEFAULT_TITLE); QueryImpl query = new QueryImpl(filter); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); List<Result> results = sourceResponse.getResults(); assertEquals(0, results.size()); } @Test public void testDeleteNoList() throws IngestException, UnsupportedQueryException { /* EMPTY */ DeleteRequestImpl deleteRequest = new DeleteRequestImpl(new String[0]); DeleteResponse results = provider.delete(deleteRequest); assertNotNull(results.getDeletedMetacards()); assertEquals(0, results.getDeletedMetacards() .size()); assertEquals(deleteRequest, results.getRequest()); /* EMPTY */ DeleteRequestImpl emptyDeleteRequest = new DeleteRequestImpl(new ArrayList<Serializable>(), DeleteRequest.DELETE_BY_ID, null); results = provider.delete(emptyDeleteRequest); assertNotNull(results.getDeletedMetacards()); assertEquals(0, results.getDeletedMetacards() .size()); assertEquals(emptyDeleteRequest, results.getRequest()); /* NULL */ DeleteRequest nullDeleteRequest = new DeleteRequestImpl(null, DeleteRequest.DELETE_BY_ID, null); results = provider.delete(nullDeleteRequest); assertNotNull(results.getDeletedMetacards()); assertEquals(0, results.getDeletedMetacards() .size()); assertEquals(nullDeleteRequest, results.getRequest()); } @Test public void testCreatePendingNrtIndex() throws Exception { deleteAllIn(provider); ConfigurationStore.getInstance() .setForceAutoCommit(false); try { MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); CreateResponse response = create(metacard); String createdId = response.getCreatedMetacards() .get(0) .getId(); Filter titleFilter = filterBuilder.attribute(Metacard.TITLE) .like() .text(MockMetacard.DEFAULT_TITLE); Filter idFilter = filterBuilder.attribute(Metacard.ID) .equalTo() .text(createdId); SourceResponse titleResponse = provider.query(new QueryRequestImpl(new QueryImpl( titleFilter))); SourceResponse idResponse = provider.query(new QueryRequestImpl(new QueryImpl(idFilter))); assertThat(titleResponse.getResults() .size(), is(0)); assertThat(idResponse.getResults() .size(), is(1)); } finally { ConfigurationStore.getInstance() .setForceAutoCommit(true); } } @Test public void testUpdatePendingNrtIndex() throws Exception { deleteAllIn(provider); ConfigurationStore.getInstance() .setForceAutoCommit(false); try { MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); CreateResponse createResponse = create(metacard); String id = createResponse.getCreatedMetacards() .get(0) .getId(); MockMetacard updatedMetacard = new MockMetacard(Library.getFlagstaffRecord()); updatedMetacard.setContentTypeName("first"); UpdateResponse firstUpdateResponse = update(id, updatedMetacard); updatedMetacard = new MockMetacard(Library.getFlagstaffRecord()); updatedMetacard.setContentTypeName("second"); UpdateResponse secondUpdateResponse = update(id, updatedMetacard); verifyContentTypeUpdate(firstUpdateResponse, MockMetacard.DEFAULT_TYPE, "first"); verifyContentTypeUpdate(secondUpdateResponse, "first", "second"); } finally { ConfigurationStore.getInstance() .setForceAutoCommit(true); } } private void verifyContentTypeUpdate(UpdateResponse response, String oldContentType, String newContentType) throws Exception { Update update = response.getUpdatedMetacards() .get(0); Metacard newMetacard = update.getNewMetacard(); Metacard oldMetacard = update.getOldMetacard(); assertThat(response.getUpdatedMetacards() .size(), is(1)); assertThat(oldMetacard.getContentTypeName(), is(oldContentType)); assertThat(newMetacard.getContentTypeName(), is(newContentType)); } @Test public void testDeletePendingNrtIndex() throws Exception { deleteAllIn(provider); ConfigurationStore.getInstance() .setForceAutoCommit(false); try { MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); CreateResponse createResponse = create(metacard); DeleteResponse deleteResponse = delete(createResponse.getCreatedMetacards() .get(0) .getId()); Metacard deletedMetacard = deleteResponse.getDeletedMetacards() .get(0); verifyDeletedRecord(metacard, createResponse, deleteResponse, deletedMetacard); } finally { ConfigurationStore.getInstance() .setForceAutoCommit(true); } } @Test public void testExtensibleMetacards() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); String brandNewField1 = "description"; String brandNewFieldValue1 = "myDescription"; /* BASIC STRINGS */ Set<AttributeDescriptor> descriptors = new HashSet<AttributeDescriptor>(); descriptors.add(new AttributeDescriptorImpl(Metacard.ID, true, true, true, false, BasicTypes.STRING_TYPE)); descriptors.add(new AttributeDescriptorImpl(brandNewField1, true, true, true, false, BasicTypes.STRING_TYPE)); MetacardTypeImpl mType = new MetacardTypeImpl("custom1", descriptors); MetacardImpl customMetacard = new MetacardImpl(mType); // customMetacard.setAttribute("id", "44567880"); customMetacard.setAttribute(brandNewField1, brandNewFieldValue1); create(customMetacard); // search id Query query = new QueryImpl(filterBuilder.attribute("id") .like() .text("*")); QueryRequest request = new QueryRequestImpl(query); SourceResponse response = provider.query(request); assertEquals(1, response.getResults() .size()); assertEquals("custom1", response.getResults() .get(0) .getMetacard() .getMetacardType() .getName()); assertThat(response.getResults() .get(0) .getMetacard() .getMetacardType() .getAttributeDescriptors(), equalTo(descriptors)); // search title - * query = new QueryImpl(filterBuilder.attribute(brandNewField1) .like() .text("*")); request = new QueryRequestImpl(query); response = provider.query(request); assertEquals(1, response.getResults() .size()); assertEquals("custom1", response.getResults() .get(0) .getMetacard() .getMetacardType() .getName()); assertThat(response.getResults() .get(0) .getMetacard() .getMetacardType() .getAttributeDescriptors(), equalTo(descriptors)); // search title - exact query = new QueryImpl(filterBuilder.attribute(brandNewField1) .equalTo() .text(brandNewFieldValue1)); request = new QueryRequestImpl(query); response = provider.query(request); assertEquals(1, response.getResults() .size()); // search negative query = new QueryImpl(filterBuilder.attribute(brandNewField1) .like() .text("no")); request = new QueryRequestImpl(query); response = provider.query(request); assertEquals(0, response.getResults() .size()); // NEW TYPE String brandNewXmlField1 = "author"; String brandNewXmlFieldValue1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" + "<author>john doe</author>"; descriptors = new HashSet<AttributeDescriptor>(); descriptors.add(new AttributeDescriptorImpl(Metacard.ID, true, true, true, false, BasicTypes.STRING_TYPE)); descriptors.add(new AttributeDescriptorImpl(brandNewXmlField1, true, true, true, false, BasicTypes.XML_TYPE)); mType = new MetacardTypeImpl("34ga$^TGHfg:/", descriptors); customMetacard = new MetacardImpl(mType); // customMetacard.setAttribute(Metacard.ID, "44567880"); customMetacard.setAttribute(brandNewXmlField1, brandNewXmlFieldValue1); create(customMetacard); // Two Ids query = new QueryImpl(filterBuilder.attribute(Metacard.ID) .like() .text("*")); request = new QueryRequestImpl(query); response = provider.query(request); assertEquals(2, response.getResults() .size()); // search xml query = new QueryImpl(filterBuilder.attribute(brandNewXmlField1) .like() .caseSensitiveText("doe")); request = new QueryRequestImpl(query); response = provider.query(request); assertEquals(1, response.getResults() .size()); assertEquals("34ga$^TGHfg:/", response.getResults() .get(0) .getMetacard() .getMetacardType() .getName()); assertThat(response.getResults() .get(0) .getMetacard() .getMetacardType() .getAttributeDescriptors(), equalTo(descriptors)); // search xml - negative query = new QueryImpl(filterBuilder.attribute(brandNewXmlField1) .like() .text("author")); request = new QueryRequestImpl(query); response = provider.query(request); assertEquals(0, response.getResults() .size()); // EVERYTHING ELSE type String doubleField = "hertz"; double doubleFieldValue = 16065.435; String floatField = "inches"; float floatFieldValue = 4.435f; String intField = "count"; int intFieldValue = 4; String longField = "milliseconds"; long longFieldValue = 987654322111L; String byteField = "bytes"; byte[] byteFieldValue = {86}; String booleanField = "expected"; boolean booleanFieldValue = true; String dateField = "lost"; Date dateFieldValue = new Date(); String geoField = "geo"; String geoFieldValue = GULF_OF_GUINEA_POINT_WKT; String shortField = "daysOfTheWeek"; short shortFieldValue = 1; String objectField = "payload"; BevelBorder objectFieldValue = new BevelBorder(BevelBorder.RAISED); descriptors = new HashSet<AttributeDescriptor>(); descriptors.add(new AttributeDescriptorImpl(Metacard.ID, true, true, true, false, BasicTypes.STRING_TYPE)); descriptors.add(new AttributeDescriptorImpl(doubleField, true, true, false, false, BasicTypes.DOUBLE_TYPE)); descriptors.add(new AttributeDescriptorImpl(floatField, true, true, false, false, BasicTypes.FLOAT_TYPE)); descriptors.add(new AttributeDescriptorImpl(intField, true, true, false, false, BasicTypes.INTEGER_TYPE)); descriptors.add(new AttributeDescriptorImpl(longField, true, true, false, false, BasicTypes.LONG_TYPE)); descriptors.add(new AttributeDescriptorImpl(byteField, false, true, false, false, BasicTypes.BINARY_TYPE)); descriptors.add(new AttributeDescriptorImpl(booleanField, true, true, false, false, BasicTypes.BOOLEAN_TYPE)); descriptors.add(new AttributeDescriptorImpl(dateField, true, true, false, false, BasicTypes.DATE_TYPE)); descriptors.add(new AttributeDescriptorImpl(geoField, true, true, false, false, BasicTypes.GEO_TYPE)); descriptors.add(new AttributeDescriptorImpl(shortField, true, true, false, false, BasicTypes.SHORT_TYPE)); descriptors.add(new AttributeDescriptorImpl(objectField, false, true, false, false, BasicTypes.OBJECT_TYPE)); mType = new MetacardTypeImpl("numbersMT", descriptors); customMetacard = new MetacardImpl(mType); // customMetacard.setAttribute(Metacard.ID, "245gasg324"); customMetacard.setAttribute(doubleField, doubleFieldValue); customMetacard.setAttribute(floatField, floatFieldValue); customMetacard.setAttribute(intField, intFieldValue); customMetacard.setAttribute(longField, longFieldValue); customMetacard.setAttribute(byteField, byteFieldValue); customMetacard.setAttribute(booleanField, booleanFieldValue); customMetacard.setAttribute(dateField, dateFieldValue); customMetacard.setAttribute(geoField, geoFieldValue); customMetacard.setAttribute(shortField, shortFieldValue); customMetacard.setAttribute(objectField, objectFieldValue); create(customMetacard); // Three Ids query = new QueryImpl(filterBuilder.attribute(Metacard.ID) .like() .text("*")); request = new QueryRequestImpl(query); response = provider.query(request); assertEquals(3, response.getResults() .size()); // search double query = new QueryImpl(filterBuilder.attribute(doubleField) .greaterThan() .number(doubleFieldValue - 1.0)); request = new QueryRequestImpl(query); response = provider.query(request); assertEquals(1, response.getResults() .size()); // search int query = new QueryImpl(filterBuilder.attribute(intField) .greaterThan() .number(intFieldValue - 1)); request = new QueryRequestImpl(query); response = provider.query(request); assertEquals(1, response.getResults() .size()); Metacard resultMetacard = response.getResults() .get(0) .getMetacard(); assertThat(resultMetacard.getAttribute(Metacard.ID), notNullValue()); assertThat((Double) (resultMetacard.getAttribute(doubleField) .getValue()), equalTo(doubleFieldValue)); assertThat((Integer) (resultMetacard.getAttribute(intField) .getValue()), equalTo(intFieldValue)); assertThat((Float) (resultMetacard.getAttribute(floatField) .getValue()), equalTo(floatFieldValue)); assertThat((Long) (resultMetacard.getAttribute(longField) .getValue()), equalTo(longFieldValue)); assertThat((byte[]) (resultMetacard.getAttribute(byteField) .getValue()), equalTo(byteFieldValue)); assertThat((Boolean) (resultMetacard.getAttribute(booleanField) .getValue()), equalTo(booleanFieldValue)); assertThat((Date) (resultMetacard.getAttribute(dateField) .getValue()), equalTo(dateFieldValue)); assertThat((String) (resultMetacard.getAttribute(geoField) .getValue()), equalTo(geoFieldValue)); assertThat((Short) (resultMetacard.getAttribute(shortField) .getValue()), equalTo(shortFieldValue)); assertThat((BevelBorder) (resultMetacard.getAttribute(objectField) .getValue()), instanceOf(BevelBorder.class)); /* * Going to use the XMLEncoder. If it writes out the objects the same way in xml, then they * are the same. */ ByteArrayOutputStream beveledBytesStreamFromSolr = new ByteArrayOutputStream(); XMLEncoder solrXMLEncoder = new XMLEncoder(new BufferedOutputStream( beveledBytesStreamFromSolr)); solrXMLEncoder.writeObject((resultMetacard.getAttribute(objectField) .getValue())); solrXMLEncoder.close(); ByteArrayOutputStream beveledBytesStreamOriginal = new ByteArrayOutputStream(); XMLEncoder currendEncoder = new XMLEncoder(new BufferedOutputStream( beveledBytesStreamOriginal)); currendEncoder.writeObject(objectFieldValue); currendEncoder.close(); assertThat(beveledBytesStreamFromSolr.toByteArray(), equalTo(beveledBytesStreamOriginal.toByteArray())); // search short query = new QueryImpl(filterBuilder.attribute(shortField) .greaterThanOrEqualTo() .number(shortFieldValue)); request = new QueryRequestImpl(query); response = provider.query(request); assertEquals(1, response.getResults() .size()); resultMetacard = response.getResults() .get(0) .getMetacard(); } @Test public void testQueryIsNull() throws Exception { SourceResponse response = provider.query(new QueryRequestImpl(null)); assertEquals(0, response.getHits()); response = provider.query(null); assertEquals(0, response.getHits()); } @Test public void testQueryHasLuceneSpecialCharacters() throws Exception { deleteAllIn(provider); List<Metacard> list = Arrays.asList((Metacard) new MockMetacard(Library.getFlagstaffRecord()), new MockMetacard(Library.getTampaRecord())); create(list); // if + is escaped, this query will be an implicit OR otherwise both both terms would be // required Filter txtFilter = filterBuilder.attribute(Metacard.ANY_TEXT) .like() .text("+Flag?taff +" + TAMPA_QUERY_PHRASE); SourceResponse response = provider.query(new QueryRequestImpl(new QueryImpl(txtFilter))); assertEquals(1, response.getResults() .size()); } /** * Searching Solr with a field not known to the server should return 0 results and should not * give an error. * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testQueryMissingField() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); // TXT FORMAT Filter txtFilter = filterBuilder.attribute("missingField") .like() .text("*"); SourceResponse response = provider.query(quickQuery(txtFilter)); assertEquals(0, response.getResults() .size()); // DATE FORMAT Filter dateFilter = filterBuilder.attribute("missingField") .before() .date(new Date()); response = provider.query(quickQuery(dateFilter)); assertEquals(0, response.getResults() .size()); // GEO FORMAT Filter geoFilter = filterBuilder.attribute("missingField") .intersecting() .wkt("POINT ( 1 0 ) "); response = provider.query(quickQuery(geoFilter)); assertEquals(0, response.getResults() .size()); // NUMERICAL FORMAT Filter numericalFilter = filterBuilder.attribute("missingField") .greaterThanOrEqualTo() .number(23L); response = provider.query(quickQuery(numericalFilter)); assertEquals(0, response.getResults() .size()); } @Test public void testQueryMissingSortField() throws IngestException, UnsupportedQueryException { deleteAllIn(provider); MockMetacard m = new MockMetacard(Library.getTampaRecord()); m.setTitle("Tampa"); List<Metacard> list = Arrays.asList((Metacard) m, new MockMetacard(Library.getFlagstaffRecord())); create(list); Filter txtFilter = filterBuilder.attribute("id") .like() .text("*"); QueryImpl query = new QueryImpl(txtFilter); query.setSortBy(new ddf.catalog.filter.impl.SortByImpl("unknownField", SortOrder.ASCENDING)); SourceResponse response = provider.query(new QueryRequestImpl(query)); assertEquals(2, response.getResults() .size()); } /** * Testing if the temporal search does not fail when no schema field can be found and/or there * is no data in the index * * @throws IngestException * @throws UnsupportedQueryException */ @Test public void testQueryMissingSortFieldTemporal() throws IngestException, UnsupportedQueryException { /* * I have tested this with an empty schema and without an empty schema - both pass, but * there is no regression test for the empty schema scenario TODO there should probably be * an automated test that creates a fresh cache, that would be a better test */ deleteAllIn(provider); Filter txtFilter = filterBuilder.attribute("id") .like() .text("*"); QueryImpl query = new QueryImpl(txtFilter); query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(Result.TEMPORAL, SortOrder.ASCENDING)); SourceResponse response = provider.query(new QueryRequestImpl(query)); assertEquals(0, response.getResults() .size()); } /** * If parts of a query can be understood, the query should be executed whereas the part that has * a missing property should return 0 results. * * @throws Exception */ @Test public void testTwoQueriesWithOneMissingField() throws Exception { deleteAllIn(provider); MockMetacard m = new MockMetacard(Library.getTampaRecord()); m.setTitle("Tampa"); List<Metacard> list = Arrays.asList((Metacard) m, new MockMetacard(Library.getFlagstaffRecord())); create(list); Filter filter = filterBuilder.anyOf(filterBuilder.attribute(Metacard.TITLE) .text("Tampa"), filterBuilder.attribute("missingField") .text("someText")); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Tampa should be found", 1, sourceResponse.getResults() .size()); } @Test(expected = IngestException.class) public void testDeleteNullAttribute() throws IngestException, UnsupportedQueryException { provider.delete(new DeleteRequest() { @Override public boolean hasProperties() { return false; } @Override public Serializable getPropertyValue(String name) { return null; } @Override public Set<String> getPropertyNames() { return null; } @Override public Map<String, Serializable> getProperties() { return null; } @Override public boolean containsPropertyName(String name) { return false; } @Override public List<? extends Serializable> getAttributeValues() { return null; } @Override public String getAttributeName() { return null; } }); } @Test public void testContextualSimpleWithLogicOperators() throws Exception { deleteAllIn(provider); MockMetacard m = new MockMetacard(Library.getTampaRecord()); m.setTitle("Tampa"); List<Metacard> list = Arrays.asList((Metacard) new MockMetacard(Library.getFlagstaffRecord()), m); assertEquals(2, create(list).getCreatedMetacards() .size()); /** CONTEXTUAL QUERY - AND negative **/ String wildcard = DEFAULT_TEST_WILDCARD; String singleChar = DEFAULT_TEST_SINGLE_WILDCARD; String escape = DEFAULT_TEST_ESCAPE; FilterFactory filterFactory = new FilterFactoryImpl(); Filter filter = filterFactory.and(filterFactory.like(filterFactory.property(Metacard.METADATA), FLAGSTAFF_QUERY_PHRASE, wildcard, singleChar, escape, false), filterFactory.like(filterFactory.property(Metacard.METADATA), TAMPA_QUERY_PHRASE, wildcard, singleChar, escape, false)); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Flagstaff and Tampa", 0, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - AND positive **/ filter = filterFactory.and(filterFactory.like(filterFactory.property(Metacard.METADATA), FLAGSTAFF_QUERY_PHRASE, wildcard, singleChar, escape, false), filterFactory.like(filterFactory.property(Metacard.METADATA), AIRPORT_QUERY_PHRASE, wildcard, singleChar, escape, false)); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Flagstaff and Airport", ONE_HIT, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - OR positive **/ filter = filterFactory.or(filterFactory.like(filterFactory.property(Metacard.METADATA), FLAGSTAFF_QUERY_PHRASE, wildcard, singleChar, escape, false), filterFactory.like(filterFactory.property(Metacard.METADATA), TAMPA_QUERY_PHRASE, wildcard, singleChar, escape, false)); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Flagstaff OR Tampa", 2, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - AND / OR positive **/ filter = filterFactory.or(filterFactory.and(filterFactory.like(filterFactory.property( Metacard.METADATA), AIRPORT_QUERY_PHRASE, wildcard, singleChar, escape, false), filterFactory.like(filterFactory.property(Metacard.METADATA), "AZ", wildcard, singleChar, escape, false)), filterFactory.like(filterFactory.property(Metacard.METADATA), FLAGSTAFF_QUERY_PHRASE, wildcard, singleChar, escape, false)); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Failed: (Airport AND AZ) or Flagstaff", ONE_HIT, sourceResponse.getResults() .size()); /** COMPLEX CONTEXTUAL QUERY **/ filter = filterFactory.and(filterFactory.like(filterFactory.property(Metacard.METADATA), AIRPORT_QUERY_PHRASE, wildcard, singleChar, escape, false), filterFactory.and(filterFactory.like(filterFactory.property(Metacard.METADATA), "AZ", wildcard, singleChar, escape, false), filterFactory.or(filterFactory.like(filterFactory.property( Metacard.METADATA), FLAGSTAFF_QUERY_PHRASE, wildcard, singleChar, escape, false), filterFactory.like(filterFactory.property(Metacard.METADATA), TAMPA_QUERY_PHRASE, wildcard, singleChar, escape, false)))); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("(Airport AND (AZ AND (Flagstaff OR TAMPA)))", ONE_HIT, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - NOT positive **/ filter = filterFactory.and(filterFactory.like(filterFactory.property(Metacard.METADATA), FLAGSTAFF_QUERY_PHRASE, wildcard, singleChar, escape, false), filterFactory.not(filterFactory.like(filterFactory.property(Metacard.METADATA), TAMPA_QUERY_PHRASE, wildcard, singleChar, escape, false))); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Did not find Flagstaff NOT Tampa", ONE_HIT, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - NOT negative **/ filter = filterFactory.and(filterFactory.like(filterFactory.property(Metacard.METADATA), FLAGSTAFF_QUERY_PHRASE, wildcard, singleChar, escape, false), filterFactory.not(filterFactory.like(filterFactory.property(Metacard.METADATA), AIRPORT_QUERY_PHRASE, wildcard, singleChar, escape, false))); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Wrongly found Flagstaff NOT Airport", 0, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - Single NOT positive **/ filter = filterFactory.not(filterFactory.like(filterFactory.property(Metacard.METADATA), TAMPA_QUERY_PHRASE, wildcard, singleChar, escape, false)); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Did not find Flagstaff", ONE_HIT, sourceResponse.getResults() .size()); assertTrue(sourceResponse.getResults() .get(0) .getMetacard() .getMetadata() .contains(FLAGSTAFF_QUERY_PHRASE)); /** CONTEXTUAL QUERY - NOT multi **/ LinkedList<Filter> filters = new LinkedList<Filter>(); filters.add(filterFactory.like(filterFactory.property(Metacard.METADATA), FLAGSTAFF_QUERY_PHRASE, wildcard, singleChar, escape, false)); filters.add(filterFactory.not(filterFactory.like(filterFactory.property(Metacard.METADATA), TAMPA_QUERY_PHRASE, wildcard, singleChar, escape, false))); filters.add(filterFactory.not(filterFactory.like(filterFactory.property(Metacard.METADATA), "Pennsylvania", wildcard, singleChar, escape, false))); filter = filterFactory.and(filters); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Did not find Flagstaff NOT Tampa", ONE_HIT, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - AND / OR **/ filter = filterFactory.or(filterFactory.and(filterFactory.like(filterFactory.property( Metacard.METADATA), AIRPORT_QUERY_PHRASE, wildcard, singleChar, escape, false), filterFactory.like(filterFactory.property(Metacard.METADATA), "AZ", wildcard, singleChar, escape, false)), filterFactory.or(filterFactory.like(filterFactory.property( Metacard.METADATA), FLAGSTAFF_QUERY_PHRASE, wildcard, singleChar, escape, false), filterFactory.like(filterFactory.property(Metacard.METADATA), "AZ", wildcard, singleChar, escape, false))); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Failed: ( Airport ) AND ( AZ ) OR ( Flagstaff ) OR ( AZ ) ", ONE_HIT, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - OR Then NOT **/ filter = filterFactory.or(filterFactory.like(filterFactory.property(Metacard.METADATA), FLAGSTAFF_QUERY_PHRASE, wildcard, singleChar, escape, false), filterFactory.and(filterFactory.like(filterFactory.property(Metacard.METADATA), "AZ", wildcard, singleChar, escape, false), filterFactory.not(filterFactory.like(filterFactory.property( Metacard.METADATA), TAMPA_QUERY_PHRASE, wildcard, singleChar, escape, false)))); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Failed: ( Flagstaff ) OR ( AZ ) NOT ( ( Tampa ) ) ", ONE_HIT, sourceResponse.getResults() .size()); } /** * Testing attributes are properly indexed. * * @throws Exception */ @Test public void testContextualXmlAttributes() throws Exception { deleteAllIn(provider); List<Metacard> list = new ArrayList<Metacard>(); String soughtWord = "self"; MockMetacard metacard1 = new MockMetacard(Library.getFlagstaffRecord()); list.add(metacard1); create(list); queryAndVerifyCount(1, filterBuilder.attribute(Metacard.METADATA) .is() .like() .text(soughtWord)); } @Test public void testContextualXmlTagsNotIndexed() throws Exception { deleteAllIn(provider); create(Arrays.asList((Metacard) new MockMetacard(Library.getFlagstaffRecord()))); String xmlTag = "lastBuildDate"; queryAndVerifyCount(0, filterBuilder.attribute(Metacard.METADATA) .is() .like() .text(xmlTag)); queryAndVerifyCount(0, filterBuilder.attribute(Metacard.METADATA) .is() .like() .text(xmlTag + "*")); } /** * Testing {@link Metacard#ANY_TEXT} * * @throws Exception */ @Test public void testContextualAnyText() throws Exception { deleteAllIn(provider); List<Metacard> list = new ArrayList<Metacard>(); MockMetacard metacard1 = new MockMetacard(Library.getFlagstaffRecord()); String soughtWord = "nitf"; metacard1.setContentTypeName(soughtWord); list.add(metacard1); MockMetacard metacard2 = new MockMetacard(Library.getTampaRecord()); list.add(metacard2); MockMetacard metacard3 = new MockMetacard(Library.getShowLowRecord()); list.add(metacard3); create(list); queryAndVerifyCount(1, filterBuilder.attribute(Metacard.ANY_TEXT) .is() .like() .text(soughtWord)); } /** * Testing Tokenization of the search phrase. * * @throws Exception */ @Test public void testWhitespaceTokenizedFieldWithWildcardSearch() throws Exception { deleteAllIn(provider); List<Metacard> list = new ArrayList<Metacard>(); String title = "AB-12.yz_file"; MockMetacard metacard1 = new MockMetacard(Library.getFlagstaffRecord()); metacard1.setTitle(title); String searchPhrase1 = "AB*12.yz_file"; String searchPhrase2 = "AB-12*yz_file"; String searchPhrase3 = "AB-12.yz*file"; String searchPhrase4 = "AB-12.*_file"; String searchPhrase5 = "Flagstaff Chamb*"; String searchPhrase6 = "Flagstaff Cmmerce"; list.add(metacard1); create(list); queryAndVerifyCount(1, filterBuilder.attribute(Metacard.TITLE) .is() .like() .text(searchPhrase1)); queryAndVerifyCount(1, filterBuilder.attribute(Metacard.TITLE) .is() .like() .text(searchPhrase2)); queryAndVerifyCount(1, filterBuilder.attribute(Metacard.TITLE) .is() .like() .text(searchPhrase3)); queryAndVerifyCount(1, filterBuilder.attribute(Metacard.TITLE) .is() .like() .text(searchPhrase4)); // Matching Phrase with wildcard queryAndVerifyCount(1, filterBuilder.attribute(Metacard.ANY_TEXT) .is() .like() .text(searchPhrase5)); // Non-Matching Phrase without wildcard queryAndVerifyCount(0, filterBuilder.attribute(Metacard.ANY_TEXT) .is() .like() .text(searchPhrase6)); } /** * Testing case sensitive index. * * @throws Exception */ @Test public void testContextualCaseSensitiveSimple() throws Exception { deleteAllIn(provider); List<Metacard> list = Arrays.asList((Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getTampaRecord())); create(list); CommonQueryBuilder queryBuilder = new CommonQueryBuilder(); boolean isCaseSensitive = true; boolean isFuzzy = false; QueryImpl query = null; SourceResponse sourceResponse = null; /** CONTEXTUAL QUERY - REGRESSION TEST OF SIMPLE TERMS **/ // Find one query = queryBuilder.like(Metacard.METADATA, FLAGSTAFF_QUERY_PHRASE, isCaseSensitive, isFuzzy); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(1, sourceResponse.getResults() .size()); // Find the other query = queryBuilder.like(Metacard.METADATA, TAMPA_QUERY_PHRASE, isCaseSensitive, isFuzzy); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(1, sourceResponse.getResults() .size()); // Find nothing query = queryBuilder.like(Metacard.METADATA, "NO_SUCH_WORD", isCaseSensitive, isFuzzy); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(0, sourceResponse.getResults() .size()); // Find both query = queryBuilder.like(Metacard.METADATA, AIRPORT_QUERY_PHRASE, isCaseSensitive, isFuzzy); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(2, sourceResponse.getResults() .size()); // Phrase query = queryBuilder.like(Metacard.METADATA, "Airport TPA in FL", isCaseSensitive, isFuzzy); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(1, sourceResponse.getResults() .size()); /** NEGATIVE CASES **/ query = queryBuilder.like(Metacard.METADATA, "Tamp", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(0, sourceResponse.getResults() .size()); query = queryBuilder.like(Metacard.METADATA, "TAmpa", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(0, sourceResponse.getResults() .size()); query = queryBuilder.like(Metacard.METADATA, "AIrport TPA in FL", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(0, sourceResponse.getResults() .size()); } @Test public void testContextualCaseSensitiveWildcardWithPunctuation() throws Exception { deleteAllIn(provider); List<Metacard> list = Arrays.asList((Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getTampaRecord())); create(list); CommonQueryBuilder queryBuilder = new CommonQueryBuilder(); boolean isCaseSensitive = true; boolean isFuzzy = false; QueryImpl query = null; SourceResponse sourceResponse = null; /** WILDCARD CASE SENSITIVE CONTEXTUAL QUERY **/ query = queryBuilder.like(Metacard.ANY_TEXT, "http://www.flagstaffchamber.com/arizona-cardinals*", isCaseSensitive, isFuzzy); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(1, sourceResponse.getResults() .size()); query = queryBuilder.like(Metacard.ANY_TEXT, "http://*10160", isCaseSensitive, isFuzzy); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(1, sourceResponse.getResults() .size()); /** NEGATIVE CASES **/ query = queryBuilder.like(Metacard.ANY_TEXT, "HTTP://www.flagstaffchamber.com/arizona-cardinals*", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(0, sourceResponse.getResults() .size()); query = queryBuilder.like(Metacard.ANY_TEXT, "10160*", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(0, sourceResponse.getResults() .size()); } @Test public void testContextualFuzzy() throws Exception { deleteAllIn(provider); List<Metacard> list = Arrays.asList((Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getTampaRecord())); /** CREATE **/ create(list); /** CONTEXTUAL QUERY - FUZZY **/ Filter filter = filterBuilder.attribute(Metacard.METADATA) .like() .fuzzyText(FLAGSTAFF_QUERY_PHRASE); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Expected one hit for fuzzy term 'Flagstaff'", ONE_HIT, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - FUZZY PHRASE **/ filter = filterBuilder.attribute(Metacard.METADATA) .like() .fuzzyText("Flagstaff Chamber"); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Expected one hit for fuzzy term 'Flagstaff Chamber'", ONE_HIT, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - FUZZY PHRASE, multiple spaces **/ filter = filterBuilder.attribute(Metacard.METADATA) .like() .fuzzyText("Flagstaff Chamber"); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Expected one hit for fuzzy term 'Flagstaff Chamber'", ONE_HIT, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - FUZZY PHRASE, upper case with insertion **/ filter = filterBuilder.attribute(Metacard.METADATA) .like() .fuzzyText("FLGD"); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Expected two hits for fuzzy term 'FLGD'", 2, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - FUZZY PHRASE, second word missing **/ filter = filterBuilder.attribute(Metacard.METADATA) .like() .fuzzyText("Flagstaff Igloo"); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Expected zero hits for fuzzy term 'Flagstaff Igloo'", 0, sourceResponse.getResults() .size()); /** CONTEXTUAL QUERY - FUZZY - Possible POSITIVE CASE **/ // Possible matches are: // Tampa record has word 'company' // Flagstaff has word 'camp' filter = filterBuilder.attribute(Metacard.METADATA) .like() .fuzzyText("comp"); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertThat("Expected to find any hits for fuzzy 'comp'", sourceResponse.getResults() .size(), is(greaterThanOrEqualTo(1))); /** CONTEXTUAL QUERY - FUZZY - Bad fuzzy field **/ filter = filterBuilder.attribute(Metacard.CREATED) .like() .fuzzyText(new Date().toString()); try { sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); fail("Should not be allowed to run a fuzzy on a date field."); } catch (UnsupportedQueryException e) { LOGGER.info("Properly received exception."); } } @Test public void testContextualWildcard() throws Exception { deleteAllIn(provider); List<Metacard> list = Arrays.asList((Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getTampaRecord())); create(list); /** CONTEXTUAL QUERY - SIMPLE TERMS **/ CommonQueryBuilder queryBuilder = new CommonQueryBuilder(); boolean isCaseSensitive = false; boolean isFuzzy = false; QueryImpl query = null; SourceResponse sourceResponse = null; query = queryBuilder.like(Metacard.METADATA, "Flag*ff Chamber", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(1, sourceResponse.getResults() .size()); // FIX FOR THIS IS IN https://issues.apache.org/jira/browse/SOLR-1604 // Either roll this in yourself or wait for it to come in with Solr query = queryBuilder.like(Metacard.METADATA, "Flag*ff Pulliam", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); // assertEquals(0, sourceResponse.getResults().size()); query = queryBuilder.like(Metacard.METADATA, "*rport", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(2, sourceResponse.getResults() .size()); query = queryBuilder.like(Metacard.METADATA, "*rpor*", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(2, sourceResponse.getResults() .size()); query = queryBuilder.like(Metacard.METADATA, "*", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(2, sourceResponse.getResults() .size()); query = queryBuilder.like(Metacard.METADATA, "airpo*t", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(2, sourceResponse.getResults() .size()); query = queryBuilder.like(Metacard.METADATA, "Airpo*t", isCaseSensitive, isFuzzy); query.setStartIndex(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(2, sourceResponse.getResults() .size()); } @Test public void testPropertyIsLike() throws Exception { deleteAllIn(provider); List<Metacard> list = new ArrayList<Metacard>(); MockMetacard metacard1 = new MockMetacard(Library.getFlagstaffRecord()); metacard1.setTitle("Mary"); list.add(metacard1); MockMetacard metacard2 = new MockMetacard(Library.getTampaRecord()); metacard2.setTitle("Mary had a little"); list.add(metacard2); MockMetacard metacard3 = new MockMetacard(Library.getShowLowRecord()); metacard3.setTitle("Mary had a little l!@#$%^&*()_mb"); list.add(metacard3); create(list); queryAndVerifyCount(3, filterBuilder.attribute(Metacard.TITLE) .is() .like() .text("Mary")); queryAndVerifyCount(2, filterBuilder.attribute(Metacard.TITLE) .is() .like() .text("little")); queryAndVerifyCount(0, filterBuilder.attribute(Metacard.TITLE) .is() .like() .text("gary")); /* EMPTY ATTRIBUTE */ queryAndVerifyCount(3, filterBuilder.attribute(Metacard.DESCRIPTION) .is() .equalTo() .text("")); queryAndVerifyCount(0, filterBuilder.attribute(Metacard.TITLE) .is() .equalTo() .text("")); } @Test public void testPropertyIsEqualTo() throws Exception { deleteAllIn(provider); List<Metacard> list = new ArrayList<Metacard>(); /* STRINGS */ MockMetacard metacard1 = new MockMetacard(Library.getFlagstaffRecord()); metacard1.setTitle("Mary"); Date exactEffectiveDate = new DateTime().minusMinutes(1) .toDate(); metacard1.setEffectiveDate(exactEffectiveDate); list.add(metacard1); MockMetacard metacard2 = new MockMetacard(Library.getTampaRecord()); metacard2.setTitle("Mary had a little"); list.add(metacard2); MockMetacard metacard3 = new MockMetacard(Library.getShowLowRecord()); metacard3.setTitle("Mary had a little l!@#$%^&*()_mb"); list.add(metacard3); create(list); queryAndVerifyCount(1, filterBuilder.attribute(Metacard.TITLE) .is() .equalTo() .text("Mary")); queryAndVerifyCount(0, filterBuilder.attribute(Metacard.TITLE) .is() .equalTo() .text("Mar")); queryAndVerifyCount(0, filterBuilder.attribute(Metacard.TITLE) .is() .equalTo() .text("Mary had")); queryAndVerifyCount(1, filterBuilder.attribute(Metacard.TITLE) .is() .equalTo() .text("Mary had a little")); queryAndVerifyCount(1, filterBuilder.attribute(Metacard.TITLE) .is() .equalTo() .text("Mary had a little l!@#$%^&*()_mb")); /* DATES */ queryAndVerifyCount(1, filterBuilder.attribute(Metacard.EFFECTIVE) .is() .equalTo() .date(exactEffectiveDate)); /* EMPTY ATTRIBUTE */ queryAndVerifyCount(3, filterBuilder.attribute(Metacard.DESCRIPTION) .is() .equalTo() .text("")); queryAndVerifyCount(0, filterBuilder.attribute(Metacard.TITLE) .is() .equalTo() .text("")); } @Test public void testPropertyIsInProximityToAnyText() throws Exception { deleteAllIn(provider); List<Metacard> list = new ArrayList<>(); MockMetacard metacard = new MockMetacard(Library.getTampaRecord()); metacard.setDescription("Mary had a little"); MockMetacard metacard1 = new MockMetacard(Library.getShowLowRecord()); metacard1.setTitle("Mary had a little ham"); list.add(metacard); list.add(metacard1); create(list); queryAndVerifyCount(1, filterBuilder.proximity(Metacard.ANY_TEXT, 3, "Mary ham")); queryAndVerifyCount(0, filterBuilder.proximity(Metacard.ANY_TEXT, 2, "Mary ham")); queryAndVerifyCount(2, filterBuilder.proximity(Metacard.ANY_TEXT, 2, "Mary little")); queryAndVerifyCount(0, filterBuilder.proximity(Metacard.ANY_TEXT, 1, "Mary little")); } @Test public void testPropertyIsInProximityTo() throws Exception { deleteAllIn(provider); List<Metacard> list = new ArrayList<>(); MockMetacard metacard = new MockMetacard(Library.getTampaRecord()); metacard.setTitle("Mary had a little"); MockMetacard metacard1 = new MockMetacard(Library.getShowLowRecord()); metacard1.setTitle("Mary had a little ham"); list.add(metacard); list.add(metacard1); create(list); queryAndVerifyCount(1, filterBuilder.proximity(Core.TITLE, 3, "Mary ham")); queryAndVerifyCount(0, filterBuilder.proximity(Core.TITLE, 2, "Mary ham")); queryAndVerifyCount(2, filterBuilder.proximity(Core.TITLE, 2, "Mary little")); queryAndVerifyCount(0, filterBuilder.proximity(Core.TITLE, 1, "Mary little")); } @Test(expected = UnsupportedQueryException.class) public void testPropertyIsEqualToCaseSensitive() throws Exception { deleteAllIn(provider); CommonQueryBuilder commonBuilder = new CommonQueryBuilder(); // Expect an exception queryAndVerifyCount(0, commonBuilder.equalTo(Metacard.TITLE, "Mary", false)); } @Test public void testTemporalDuring() throws Exception { deleteAllIn(provider); Metacard metacard = new MockMetacard(Library.getFlagstaffRecord()); List<Metacard> list = Arrays.asList(metacard); /** CREATE **/ create(list); /** TEMPORAL QUERY - DURING FILTER (Period) - AKA ABSOLUTE **/ FilterFactory filterFactory = new FilterFactoryImpl(); int minutes = 3; DateTime startDT = new DateTime().plusMinutes(ALL_RESULTS * minutes); DateTime endDT = new DateTime(); CommonQueryBuilder queryBuilder = new CommonQueryBuilder(); QueryImpl query = queryBuilder.during(Metacard.MODIFIED, startDT.toDate(), endDT.toDate()); query.setStartIndex(1); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(1, sourceResponse.getResults() .size()); for (Result content : sourceResponse.getResults()) { String term = FLAGSTAFF_QUERY_PHRASE; LOGGER.debug("RESULT returned: {}", content); String metadata = content.getMetacard() .getMetadata(); assertTrue("Testing if contents has term [" + term + "]", ALL_RESULTS != metadata.indexOf(term)); } /** TEMPORAL QUERY - DURING FILTER (Duration) - AKA RELATIVE **/ DefaultPeriodDuration duration = new DefaultPeriodDuration( minutes * MINUTES_IN_MILLISECONDS); Filter filter = filterFactory.during(filterFactory.property(Metacard.MODIFIED), filterFactory.literal(duration)); query = new QueryImpl(filter); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(1, sourceResponse.getResults() .size()); for (Result content : sourceResponse.getResults()) { String term = FLAGSTAFF_QUERY_PHRASE; LOGGER.debug("RESULT returned: {}", content); String metadata = content.getMetacard() .getMetadata(); assertTrue("Testing if contents has term [" + term + "]", ALL_RESULTS != metadata.indexOf(term)); } provider.isAvailable(); } @Test public void testXpathCompoundContextualQuery() throws Exception { ConfigurationStore.getInstance() .setDisableTextPath(false); deleteAllIn(provider); String nonexistentXpath = "/this/xpath[does/not/@ex:exist]"; MockMetacard tampa = new MockMetacard(Library.getTampaRecord()); tampa.setTitle("Tampa"); tampa.setLocation(TAMPA_AIRPORT_POINT_WKT); MockMetacard flagstaff = new MockMetacard(Library.getFlagstaffRecord()); flagstaff.setLocation(FLAGSTAFF_AIRPORT_POINT_WKT); create(Arrays.asList((Metacard) tampa, flagstaff)); /* XPath AND temporal AND spatial. */ Filter filter = filterBuilder.allOf(filterBuilder.xpath("/rss/channel[item/link]") .exists(), filterBuilder.attribute(Metacard.MODIFIED) .before() .date(new DateTime().plus(1) .toDate()), filterBuilder.attribute(Metacard.GEOGRAPHY) .intersecting() .wkt(FLAGSTAFF_AIRPORT_POINT_WKT)); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("XPath AND temporal AND spatial", ONE_HIT, sourceResponse.getResults() .size()); /* temporal AND (Bad XPath OR XPath) */ filter = filterBuilder.allOf(filterBuilder.attribute(Metacard.MODIFIED) .before() .date(new DateTime().plus(1) .toDate()), filterBuilder.anyOf(filterBuilder.xpath(nonexistentXpath) .exists(), filterBuilder.xpath("//channel/image/title") .is() .like() .text(FLAGSTAFF_QUERY_PHRASE))); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("temporal AND (Bad XPath OR XPath)", ONE_HIT, sourceResponse.getResults() .size()); /* Bad XPath OR (spatial AND XPath) */ filter = filterBuilder.anyOf(filterBuilder.xpath(nonexistentXpath) .is() .like() .text("any phrase"), filterBuilder.allOf(filterBuilder.attribute(Metacard.GEOGRAPHY) .intersecting() .wkt(TAMPA_AIRPORT_POINT_WKT), filterBuilder.xpath( "/rss//item/enclosure/@url") .exists())); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Bad XPath OR (spatial AND XPath)", ONE_HIT, sourceResponse.getResults() .size()); assertEquals("Tampa", sourceResponse.getResults() .get(0) .getMetacard() .getTitle()); /* spatial AND (Bad XPath OR Bad XPath) */ filter = filterBuilder.allOf(filterBuilder.attribute(Metacard.GEOGRAPHY) .intersecting() .wkt(FLAGSTAFF_AIRPORT_POINT_WKT), filterBuilder.anyOf(filterBuilder.xpath( nonexistentXpath) .exists(), filterBuilder.xpath("//also/does/not[@exist]") .is() .like() .text(FLAGSTAFF_QUERY_PHRASE))); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("spatial AND (Bad XPath OR Bad XPath)", 0, sourceResponse.getResults() .size()); } @Test public void testXpathNestedXpathQuery() throws Exception { ConfigurationStore.getInstance() .setDisableTextPath(false); deleteAllIn(provider); String explicitXpath1 = "//rss/channel/itunes:explicit"; String explicitXpath2 = "//rss/channel/ITunes:explicit"; String updateXpath1 = "//rss/channel/sy:updatePeriod"; String updateXpath2 = "//rss/channel/SY:updatePeriod"; String updateFreq1 = "//rss/channel/sy:updateFrequency"; String updateFreq2 = "//rss/channel/SY:updateFrequency"; String existsXpath = "//rss/channel/language"; MockMetacard tampa = new MockMetacard(Library.getTampaRecord()); tampa.setTitle("Tampa"); tampa.setLocation(TAMPA_AIRPORT_POINT_WKT); MockMetacard flagstaff = new MockMetacard(Library.getFlagstaffRecord()); flagstaff.setLocation(FLAGSTAFF_AIRPORT_POINT_WKT); create(Arrays.asList((Metacard) tampa, flagstaff)); /* XPath */ Filter existsFilter = filterBuilder.xpath(existsXpath) .exists(); Filter notFilter = filterBuilder.not(filterBuilder.xpath(existsXpath) .is() .like() .text("en-us")); Filter firstPart = filterBuilder.allOf(existsFilter, notFilter); Filter anyGroupFilter = filterBuilder.anyOf(filterBuilder.xpath(explicitXpath1) .is() .like() .text("no"), filterBuilder.xpath(explicitXpath2) .is() .like() .text("no")); Filter anyABfilter = filterBuilder.anyOf(filterBuilder.xpath(updateXpath1) .is() .like() .text("hourly"), filterBuilder.xpath(updateFreq1) .is() .like() .text("1")); Filter anyACfilter = filterBuilder.anyOf(filterBuilder.xpath(updateXpath2) .is() .like() .text("hourly"), filterBuilder.xpath(updateFreq2) .is() .like() .text("1")); Filter allABACFilter = filterBuilder.allOf(anyABfilter, anyACfilter); Filter secondPart = filterBuilder.anyOf(anyGroupFilter, allABACFilter); Filter totalFilter = filterBuilder.allOf(firstPart, secondPart); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl( totalFilter))); assertEquals("Nested XPath - Find 1 result", ONE_HIT, sourceResponse.getResults() .size()); } @Test public void testXpathNestedNegativeXpathQuery() throws Exception { ConfigurationStore.getInstance() .setDisableTextPath(false); deleteAllIn(provider); String explicitXpath1 = "//rss/channel/itunes:explicit"; String explicitXpath2 = "//rss/channel/ITunes:explicit"; String updateXpath1 = "//rss/channel/sy:updatePeriod"; String updateXpath2 = "//rss/channel/SY:updatePeriod"; String updateFreq1 = "//rss/channel/sy:updateFrequency"; String updateFreq2 = "//rss/channel/SY:updateFrequency"; String existsXpath = "//rss/channel/language"; MockMetacard tampa = new MockMetacard(Library.getTampaRecord()); tampa.setTitle("Tampa"); tampa.setLocation(TAMPA_AIRPORT_POINT_WKT); MockMetacard flagstaff = new MockMetacard(Library.getFlagstaffRecord()); flagstaff.setLocation(FLAGSTAFF_AIRPORT_POINT_WKT); create(Arrays.asList((Metacard) tampa, flagstaff)); /* XPath */ Filter existsFilter = filterBuilder.xpath(existsXpath) .exists(); Filter notFilter = filterBuilder.not(filterBuilder.xpath(existsXpath) .is() .like() .text("en-us")); Filter firstPart = filterBuilder.allOf(existsFilter, notFilter); Filter anyGroupFilter = filterBuilder.anyOf(filterBuilder.xpath(explicitXpath1) .is() .like() .text("yes"), filterBuilder.xpath(explicitXpath2) .is() .like() .text("yes")); Filter anyABfilter = filterBuilder.anyOf(filterBuilder.xpath(updateXpath1) .is() .like() .text("daily"), filterBuilder.xpath(updateFreq1) .is() .like() .text("2")); Filter anyACfilter = filterBuilder.anyOf(filterBuilder.xpath(updateXpath2) .is() .like() .text("daily"), filterBuilder.xpath(updateFreq2) .is() .like() .text("2")); Filter allABACFilter = filterBuilder.allOf(anyABfilter, anyACfilter); Filter secondPart = filterBuilder.anyOf(anyGroupFilter, allABACFilter); Filter totalFilter = filterBuilder.allOf(firstPart, secondPart); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl( totalFilter))); assertEquals("Nested XPath - Find 0 results", 0, sourceResponse.getResults() .size()); } @Test public void testXpathQuery() throws Exception { prepareXPath(false); /** POSITIVE **/ queryXpathPositiveWithSearchPhrase("/rss/channel/itunes:image/@href", "http://www.flagstaffchamber.com/wp-content/plugins/powerpress/itunes_default.jpg", FLAGSTAFF_QUERY_PHRASE); queryXpathPositiveExists("/rss//item", FLAGSTAFF_QUERY_PHRASE); queryXpathPositiveExists("/purchaseOrder/comment", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("/purchaseOrder//comment", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("/purchaseOrder/items//comment", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("/purchaseOrder[items//comment]", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("/purchaseOrder/items/item/comment", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("/purchaseOrder//item/USPrice", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("purchaseOrder/items/item", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("/purchaseOrder/items/item", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("./purchaseOrder/items/item", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("//shipTo[@country]", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("//shipTo[@country='US']", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("/*/items", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("/*/*/item[.//comment]", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("/purchaseOrder/*", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("/purchaseOrder/*/item", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveExists("//*[@country='US']", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveWithSearchPhrase("//shipTo/@country", "US", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveWithSearchPhrase("//shipTo/@country", "us", PURCHASE_ORDER_QUERY_PHRASE, false); queryXpathPositiveWithSearchPhrase("/purchaseOrder/comment", "Hurry, my lawn is going wild!", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveWithSearchPhrase("/purchaseOrder/items//comment", "Confirm this is electric", "Lawnmower"); queryXpathPositiveWithSearchPhrase("//comment", "Hurry, my lawn is going wild!", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveWithSearchPhrase("//comment", "Confirm this is electric", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveWithSearchPhrase("//items//comment", "Confirm this is electric", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveWithSearchPhrase("/purchaseOrder//item/USPrice", "148.95", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveWithSearchPhrase("/purchaseOrder//item/USPrice", "39.98", PURCHASE_ORDER_QUERY_PHRASE); queryXpathPositiveWithSearchPhrase("/purchaseOrder//item[2]/USPrice", "39.98", PURCHASE_ORDER_QUERY_PHRASE); /** NEGATIVE **/ queryXpathNegativeExists("/*/invalid"); queryXpathNegativeExists("//electric"); queryXpathNegativeExists("//partNum"); queryXpathNegativeExists("//shipTo[@country2]"); queryXpathNegativeWithSearchPhrase("//shipTo/@country", "us"); queryXpathNegativeWithSearchPhrase("/purchaseOrder/comment", "invalid"); queryXpathNegativeWithSearchPhrase("/purchaseOrder/billTo", "12345"); queryXpathNegativeWithSearchPhrase("//comment", "invalid"); queryXpathNegativeWithSearchPhrase("/purchaseOrder//item/USPrice", "invalid"); } public void queryXpathPositiveExists(String xpath, String recordMatchPhrase) throws Exception { SourceResponse sourceResponse = queryXpathExists(xpath); assertEquals("Failed to find record for xpath: " + xpath, 1, sourceResponse.getResults() .size()); for (Result r : sourceResponse.getResults()) { assertTrue("Wrong record, keyword was not found.", ALL_RESULTS != r.getMetacard() .getMetadata() .indexOf(recordMatchPhrase)); } } public void queryXpathNegativeExists(String xpath) throws Exception { SourceResponse sourceResponse = queryXpathExists(xpath); assertEquals("Should not have found record for xpath: " + xpath, 0, sourceResponse.getResults() .size()); } private SourceResponse queryXpathExists(String xpath) throws UnsupportedQueryException { Filter filter = filterBuilder.xpath(xpath) .exists(); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); return sourceResponse; } public void queryXpathPositiveWithSearchPhrase(String xpath, String searchPhrase, String recordMatchPhrase) throws Exception { queryXpathPositiveWithSearchPhrase(xpath, searchPhrase, recordMatchPhrase, true); } public void queryXpathPositiveWithSearchPhrase(String xpath, String searchPhrase, String recordMatchPhrase, boolean isCaseSensitive) throws Exception { SourceResponse sourceResponse = queryXpathWithPhrase(xpath, searchPhrase, isCaseSensitive); assertEquals("Failed to find record for xpath: " + xpath, 1, sourceResponse.getResults() .size()); for (Result r : sourceResponse.getResults()) { assertTrue("Wrong record, keyword was not found.", ALL_RESULTS != r.getMetacard() .getMetadata() .indexOf(recordMatchPhrase)); } } public void queryXpathNegativeWithSearchPhrase(String xpath, String searchPhrase) throws Exception { SourceResponse sourceResponse = queryXpathWithPhrase(xpath, searchPhrase, true); assertEquals("Should not have found record for xpath: " + xpath, 0, sourceResponse.getResults() .size()); } private SourceResponse queryXpathWithPhrase(String xpath, String searchPhrase, boolean isCaseSensitive) throws UnsupportedQueryException { Filter filter; if (isCaseSensitive) { filter = filterBuilder.xpath(xpath) .is() .like() .caseSensitiveText(searchPhrase); } else { filter = filterBuilder.xpath(xpath) .is() .like() .text(searchPhrase); } SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); return sourceResponse; } @Test public void testNumericalFields() throws Exception { deleteAllIn(provider); /* SETUP */ String doubleField = "hertz"; double doubleFieldValue = 16065.435; String floatField = "inches"; float floatFieldValue = 4.435f; String intField = "count"; int intFieldValue = 4; String longField = "milliseconds"; long longFieldValue = 9876543293L; String shortField = "daysOfTheWeek"; short shortFieldValue = 1; Set<AttributeDescriptor> descriptors = numericalDescriptors(doubleField, floatField, intField, longField, shortField); MetacardTypeImpl mType = new MetacardTypeImpl("numberMetacardType", descriptors); MetacardImpl customMetacard1 = new MetacardImpl(mType); customMetacard1.setAttribute(Metacard.ID, ""); customMetacard1.setAttribute(doubleField, doubleFieldValue); customMetacard1.setAttribute(floatField, floatFieldValue); customMetacard1.setAttribute(intField, intFieldValue); customMetacard1.setAttribute(longField, longFieldValue); customMetacard1.setAttribute(shortField, shortFieldValue); create(Arrays.asList((Metacard) customMetacard1)); // searching double field with int value greaterThanQueryAssertion(doubleField, intFieldValue, 1); // searching float field with double value greaterThanQueryAssertion(floatField, 4.0, 1); // searching long field with int value greaterThanQueryAssertion(longField, intFieldValue, 1); // searching int field with long value greaterThanQueryAssertion(intField, 3L, 1); // searching int field with long value greaterThanQueryAssertion(shortField, 0L, 1); } @Test() public void testNumericalOperations() throws Exception { deleteAllIn(provider); /* SETUP */ String doubleField = "hertz"; double doubleFieldValue = 16065.435; String floatField = "inches"; float floatFieldValue = 4.435f; String intField = "count"; int intFieldValue = 4; String longField = "milliseconds"; long longFieldValue = 9876543293L; String shortField = "daysOfTheWeek"; short shortFieldValue = 1; Set<AttributeDescriptor> descriptors = numericalDescriptors(doubleField, floatField, intField, longField, shortField); MetacardTypeImpl mType = new MetacardTypeImpl("anotherCustom", descriptors); MetacardImpl customMetacard1 = new MetacardImpl(mType); customMetacard1.setAttribute(Metacard.ID, ""); customMetacard1.setAttribute(doubleField, doubleFieldValue); customMetacard1.setAttribute(floatField, floatFieldValue); customMetacard1.setAttribute(intField, intFieldValue); customMetacard1.setAttribute(longField, longFieldValue); customMetacard1.setAttribute(shortField, shortFieldValue); MetacardImpl customMetacard2 = new MetacardImpl(mType); customMetacard2.setAttribute(Metacard.ID, ""); customMetacard2.setAttribute(doubleField, doubleFieldValue + 10.0); customMetacard2.setAttribute(floatField, (floatFieldValue + 10.0f)); customMetacard2.setAttribute(intField, intFieldValue + 1); customMetacard2.setAttribute(longField, longFieldValue + 10L); customMetacard2.setAttribute(shortField, (shortFieldValue + 1)); create(Arrays.asList((Metacard) customMetacard1, customMetacard2)); // on exact DOUBLE greaterThanQueryAssertion(doubleField, doubleFieldValue, 1); greaterThanOrEqualToQueryAssertion(doubleField, doubleFieldValue, 2); // beyond the DOUBLE greaterThanQueryAssertion(doubleField, doubleFieldValue - 0.00000001, 2); greaterThanOrEqualToQueryAssertion(doubleField, doubleFieldValue - 0.00000001, 2); greaterThanQueryAssertion(doubleField, doubleFieldValue + 12.0, 0); greaterThanOrEqualToQueryAssertion(doubleField, doubleFieldValue + 12.0, 0); // on exact FLOAT greaterThanQueryAssertion(floatField, floatFieldValue, 1); greaterThanOrEqualToQueryAssertion(floatField, floatFieldValue, 2); // beyond the FLOAT greaterThanQueryAssertion(floatField, floatFieldValue - 0.00001f, 2); greaterThanOrEqualToQueryAssertion(floatField, floatFieldValue - 0.00001f, 2); greaterThanQueryAssertion(floatField, floatFieldValue + 12.0f, 0); greaterThanOrEqualToQueryAssertion(floatField, floatFieldValue + 12.0f, 0); // on exact LONG greaterThanQueryAssertion(longField, longFieldValue, 1); greaterThanOrEqualToQueryAssertion(longField, longFieldValue, 2); // beyond the LONG greaterThanQueryAssertion(longField, longFieldValue - 1L, 2); greaterThanOrEqualToQueryAssertion(longField, longFieldValue - 1L, 2); greaterThanQueryAssertion(longField, longFieldValue + 12L, 0); greaterThanOrEqualToQueryAssertion(longField, longFieldValue + 12L, 0); // on exact INT greaterThanQueryAssertion(intField, intFieldValue, 1); greaterThanOrEqualToQueryAssertion(intField, intFieldValue, 2); // beyond the INT greaterThanQueryAssertion(intField, intFieldValue - 1, 2); greaterThanOrEqualToQueryAssertion(intField, intFieldValue - 1, 2); greaterThanQueryAssertion(intField, intFieldValue + 2, 0); greaterThanOrEqualToQueryAssertion(intField, intFieldValue + 2, 0); // on exact SHORT greaterThanQueryAssertion(shortField, shortFieldValue, 1); greaterThanOrEqualToQueryAssertion(shortField, shortFieldValue, 2); // beyond the SHORT greaterThanQueryAssertion(shortField, (short) (shortFieldValue - 1), 2); greaterThanOrEqualToQueryAssertion(shortField, (short) (shortFieldValue - 1), 2); greaterThanQueryAssertion(shortField, (short) (shortFieldValue + 2), 0); greaterThanOrEqualToQueryAssertion(shortField, (short) (shortFieldValue + 2), 0); } private Set<AttributeDescriptor> numericalDescriptors(String doubleField, String floatField, String intField, String longField, String shortField) { Set<AttributeDescriptor> descriptors = new HashSet<AttributeDescriptor>(); descriptors.add(new AttributeDescriptorImpl(Metacard.ID, true, true, true, false, BasicTypes.STRING_TYPE)); descriptors.add(new AttributeDescriptorImpl(doubleField, true, true, true, false, BasicTypes.DOUBLE_TYPE)); descriptors.add(new AttributeDescriptorImpl(floatField, true, true, true, false, BasicTypes.FLOAT_TYPE)); descriptors.add(new AttributeDescriptorImpl(intField, true, true, true, false, BasicTypes.INTEGER_TYPE)); descriptors.add(new AttributeDescriptorImpl(longField, true, true, true, false, BasicTypes.LONG_TYPE)); descriptors.add(new AttributeDescriptorImpl(shortField, true, true, true, false, BasicTypes.SHORT_TYPE)); return descriptors; } private void greaterThanQueryAssertion(String fieldName, Serializable fieldValue, int count) throws UnsupportedQueryException { Filter filter = null; if (fieldValue instanceof Double) { filter = filterBuilder.attribute(fieldName) .greaterThan() .number((Double) fieldValue); } else if (fieldValue instanceof Integer) { filter = filterBuilder.attribute(fieldName) .greaterThan() .number((Integer) fieldValue); } else if (fieldValue instanceof Short) { filter = filterBuilder.attribute(fieldName) .greaterThan() .number((Short) fieldValue); } else if (fieldValue instanceof Long) { filter = filterBuilder.attribute(fieldName) .greaterThan() .number((Long) fieldValue); } else if (fieldValue instanceof Float) { filter = filterBuilder.attribute(fieldName) .greaterThan() .number((Float) fieldValue); } SourceResponse response = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertThat(response.getResults() .size(), is(equalTo(count))); } private void greaterThanOrEqualToQueryAssertion(String fieldName, Serializable fieldValue, int count) throws UnsupportedQueryException { Filter filter = null; if (fieldValue instanceof Double) { filter = filterBuilder.attribute(fieldName) .greaterThanOrEqualTo() .number((Double) fieldValue); } else if (fieldValue instanceof Integer) { filter = filterBuilder.attribute(fieldName) .greaterThanOrEqualTo() .number((Integer) fieldValue); } else if (fieldValue instanceof Short) { filter = filterBuilder.attribute(fieldName) .greaterThanOrEqualTo() .number((Short) fieldValue); } else if (fieldValue instanceof Long) { filter = filterBuilder.attribute(fieldName) .greaterThanOrEqualTo() .number((Long) fieldValue); } else if (fieldValue instanceof Float) { filter = filterBuilder.attribute(fieldName) .greaterThanOrEqualTo() .number((Float) fieldValue); } SourceResponse response = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertThat(response.getResults() .size(), is(equalTo(count))); } @Test() public void testTemporalBefore() throws Exception { deleteAllIn(provider); DateTime now = new DateTime(); addMetacardWithModifiedDate(now); /** POSITIVE CASE **/ Filter filter = filterBuilder.attribute(Metacard.MODIFIED) .before() .date(dateAfterNow(now)); List<Result> results = getResultsForFilteredQuery(filter); assertEquals(1, results.size()); /** NEGATIVE CASE **/ filter = filterBuilder.attribute(Metacard.MODIFIED) .before() .date(dateBeforeNow(now)); results = getResultsForFilteredQuery(filter); assertEquals(0, results.size()); } @Test() public void testTemporalAfter() throws Exception { deleteAllIn(provider); DateTime now = new DateTime(); addMetacardWithModifiedDate(now); /** POSITIVE CASE **/ Filter filter = filterBuilder.attribute(Metacard.MODIFIED) .after() .date(dateBeforeNow(now)); List<Result> results = getResultsForFilteredQuery(filter); assertEquals(1, results.size()); /** NEGATIVE CASE **/ filter = filterBuilder.attribute(Metacard.MODIFIED) .after() .date(dateAfterNow(now)); results = getResultsForFilteredQuery(filter); assertEquals(0, results.size()); } @Test() public void testDateGreaterThan() throws Exception { deleteAllIn(provider); DateTime now = new DateTime(); addMetacardWithModifiedDate(now); /** POSITIVE CASE **/ Filter filter = filterBuilder.dateGreaterThan(Metacard.MODIFIED, dateBeforeNow(now)); List<Result> results = getResultsForFilteredQuery(filter); assertEquals(1, results.size()); /** NEGATIVE CASE **/ filter = filterBuilder.dateGreaterThan(Metacard.MODIFIED, dateAfterNow(now)); results = getResultsForFilteredQuery(filter); assertEquals(0, results.size()); } @Test() public void testDateGreaterThanOrEqualTo() throws Exception { deleteAllIn(provider); DateTime now = new DateTime(); addMetacardWithModifiedDate(now); /** POSITIVE CASE **/ Filter filter = filterBuilder.dateGreaterThanOrEqual(Metacard.MODIFIED, dateBeforeNow(now)); List<Result> results = getResultsForFilteredQuery(filter); assertEquals(1, results.size()); /** NEGATIVE CASE **/ filter = filterBuilder.dateGreaterThanOrEqual(Metacard.MODIFIED, dateAfterNow(now)); results = getResultsForFilteredQuery(filter); assertEquals(0, results.size()); } @Test() public void testDateLessThan() throws Exception { deleteAllIn(provider); DateTime now = new DateTime(); addMetacardWithModifiedDate(now); /** POSITIVE CASE **/ Filter filter = filterBuilder.dateLessThan(Metacard.MODIFIED, dateAfterNow(now)); List<Result> results = getResultsForFilteredQuery(filter); assertEquals(1, results.size()); /** NEGATIVE CASE **/ filter = filterBuilder.dateLessThan(Metacard.MODIFIED, dateNow(now)); results = getResultsForFilteredQuery(filter); assertEquals(0, results.size()); } @Test() public void testDateLessThanOrEqualTo() throws Exception { deleteAllIn(provider); DateTime now = new DateTime(); addMetacardWithModifiedDate(now); /** POSITIVE CASE **/ Filter filter = filterBuilder.dateLessThanOrEqual(Metacard.MODIFIED, dateAfterNow(now)); List<Result> results = getResultsForFilteredQuery(filter); assertEquals(1, results.size()); /** NEGATIVE CASE **/ filter = filterBuilder.dateLessThanOrEqual(Metacard.MODIFIED, dateBeforeNow(now)); results = getResultsForFilteredQuery(filter); assertEquals(0, results.size()); } @Test() public void testDateDuring() throws Exception { deleteAllIn(provider); DateTime now = new DateTime(); addMetacardWithModifiedDate(now); /** POSITIVE CASE **/ Filter filter = filterBuilder.dateIsDuring(Metacard.MODIFIED, dateBeforeNow(now), dateAfterNow(now)); List<Result> results = getResultsForFilteredQuery(filter); assertEquals(1, results.size()); /** NEGATIVE CASES **/ filter = filterBuilder.dateIsDuring(Metacard.MODIFIED, getCannedTime(1980, Calendar.JANUARY, 1, 3), dateBeforeNow(now)); results = getResultsForFilteredQuery(filter); assertEquals(0, results.size()); filter = filterBuilder.dateIsDuring(Metacard.MODIFIED, dateAfterNow(now), getCannedTime(2035, Calendar.JULY, 23, 46)); results = getResultsForFilteredQuery(filter); assertEquals(0, results.size()); } /** * Test for a specific IRAD problem. * * @throws Exception */ @Test public void testSortById() throws Exception { deleteAllIn(provider); List<Metacard> list = new ArrayList<Metacard>(); DateTime now = new DateTime(); for (int i = 0; i < 5; i++) { MockMetacard m = new MockMetacard(Library.getFlagstaffRecord()); m.setEffectiveDate(now.minus(5L * i) .toDate()); m.setTitle("Record " + i); list.add(m); } create(list); Filter filter = filterBuilder.attribute(Metacard.EFFECTIVE) .before() .date(now.plusMillis(1) .toDate()); QueryImpl query = new QueryImpl(filter); query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(Metacard.ID, SortOrder.ASCENDING.name())); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); String currentId = ""; for (Result r : sourceResponse.getResults()) { assertTrue(currentId.compareTo(r.getMetacard() .getId()) < 0); currentId = r.getMetacard() .getId(); } } @Test public void testTextualSort() throws Exception { deleteAllIn(provider); List<Metacard> list = new ArrayList<Metacard>(); DateTime now = new DateTime(); for (int i = 65; i < 65 + 5; i++) { MockMetacard m = new MockMetacard(Library.getFlagstaffRecord()); m.setEffectiveDate(now.minus(5L * i) .toDate()); m.setTitle((char) i + " Record "); list.add(m); } create(list); Filter filter = null; QueryImpl query = null; SourceResponse sourceResponse = null; // Sort all Textual ASCENDING filter = filterBuilder.attribute(Metacard.EFFECTIVE) .before() .date(now.plusMillis(1) .toDate()); query = new QueryImpl(filter); query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(Metacard.TITLE, SortOrder.ASCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); int ascii = 65; for (int i = 0; i < list.size(); i++) { Result r = sourceResponse.getResults() .get(i); assertEquals((char) (i + ascii) + " Record ", r.getMetacard() .getTitle()); } // Sort all Textual DESCENDING query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(Metacard.TITLE, SortOrder.DESCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); int asciiE = 69; for (int i = (list.size() - 1); i >= 0; i--) { Result r = sourceResponse.getResults() .get(i); assertEquals((char) (asciiE - i) + " Record ", r.getMetacard() .getTitle()); } } @Test public void testNumericSort() throws Exception { deleteAllIn(provider); /* SETUP */ String doubleField = "hertz"; double doubleFieldValue = 16065.435; String floatField = "inches"; float floatFieldValue = 4.435f; String intField = "count"; int intFieldValue = 4; String longField = "milliseconds"; long longFieldValue = 9876543293L; String shortField = "daysOfTheWeek"; short shortFieldValue = 1; int factor = 5; List<Metacard> list = new ArrayList<Metacard>(); DateTime now = new DateTime(); for (int i = 0; i < 5; i++) { Set<AttributeDescriptor> descriptors = numericalDescriptors(doubleField, floatField, intField, longField, shortField); MetacardTypeImpl mType = new MetacardTypeImpl("numberMetacardType", descriptors); MetacardImpl customMetacard1 = new MetacardImpl(mType); customMetacard1.setAttribute(Metacard.ID, ""); customMetacard1.setAttribute(doubleField, doubleFieldValue + factor * i); customMetacard1.setAttribute(floatField, floatFieldValue + factor * i); customMetacard1.setAttribute(intField, intFieldValue + factor * i); customMetacard1.setAttribute(longField, longFieldValue + factor * i); customMetacard1.setAttribute(shortField, shortFieldValue + factor * i); list.add(customMetacard1); } create(list); Filter filter = null; QueryImpl query = null; SourceResponse sourceResponse = null; // Sort all Double ASCENDING filter = filterBuilder.attribute(Metacard.ANY_TEXT) .like() .text("*"); query = new QueryImpl(filter); query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(doubleField, SortOrder.ASCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); for (int i = 0; i < list.size(); i++) { Result r = sourceResponse.getResults() .get(i); assertEquals(doubleFieldValue + factor * i, r.getMetacard() .getAttribute(doubleField) .getValue()); } // Sort all double DESCENDING query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(doubleField, SortOrder.DESCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); int counter = 0; for (int i = (list.size() - 1); i >= 0; i--) { Result r = sourceResponse.getResults() .get(i); assertEquals(doubleFieldValue + factor * counter, r.getMetacard() .getAttribute(doubleField) .getValue()); counter++; } // Sort all Float ASCENDING query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(floatField, SortOrder.ASCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); for (int i = 0; i < list.size(); i++) { Result r = sourceResponse.getResults() .get(i); assertEquals(floatFieldValue + factor * i, r.getMetacard() .getAttribute(floatField) .getValue()); } // Sort all Float DESCENDING query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(floatField, SortOrder.DESCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); counter = 0; for (int i = (list.size() - 1); i >= 0; i--) { Result r = sourceResponse.getResults() .get(i); assertEquals(floatFieldValue + factor * counter, r.getMetacard() .getAttribute(floatField) .getValue()); counter++; } // Sort all int ASCENDING query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(intField, SortOrder.ASCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); for (int i = 0; i < list.size(); i++) { Result r = sourceResponse.getResults() .get(i); assertEquals(intFieldValue + factor * i, r.getMetacard() .getAttribute(intField) .getValue()); } // Sort all int DESCENDING query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(intField, SortOrder.DESCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); counter = 0; for (int i = (list.size() - 1); i >= 0; i--) { Result r = sourceResponse.getResults() .get(i); assertEquals(intFieldValue + factor * counter, r.getMetacard() .getAttribute(intField) .getValue()); counter++; } // Sort all long ASCENDING query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(longField, SortOrder.ASCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); for (int i = 0; i < list.size(); i++) { Result r = sourceResponse.getResults() .get(i); assertEquals(longFieldValue + factor * i, r.getMetacard() .getAttribute(longField) .getValue()); } // Sort all long DESCENDING query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(longField, SortOrder.DESCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); counter = 0; for (int i = (list.size() - 1); i >= 0; i--) { Result r = sourceResponse.getResults() .get(i); assertEquals(longFieldValue + factor * counter, r.getMetacard() .getAttribute(longField) .getValue()); counter++; } // Sort all short ASCENDING query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(shortField, SortOrder.ASCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); for (int i = 0; i < list.size(); i++) { Result r = sourceResponse.getResults() .get(i); assertEquals((short) (shortFieldValue + factor * i), r.getMetacard() .getAttribute(shortField) .getValue()); } // Sort all short DESCENDING query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(shortField, SortOrder.DESCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); counter = 0; for (int i = (list.size() - 1); i >= 0; i--) { Result r = sourceResponse.getResults() .get(i); assertEquals((short) (shortFieldValue + factor * counter), r.getMetacard() .getAttribute(shortField) .getValue()); counter++; } } @Test public void testSorting() throws Exception { deleteAllIn(provider); List<Metacard> list = new ArrayList<Metacard>(); DateTime now = new DateTime(); for (int i = 0; i < 5; i++) { MockMetacard m = new MockMetacard(Library.getFlagstaffRecord()); m.setEffectiveDate(now.minus(5L * i) .toDate()); m.setTitle("Record " + i); list.add(m); } create(list); Filter filter = null; QueryImpl query = null; SourceResponse sourceResponse = null; // Sort all TEMPORAL DESC filter = filterBuilder.attribute(Metacard.EFFECTIVE) .before() .date(now.plusMillis(1) .toDate()); query = new QueryImpl(filter); query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(Metacard.EFFECTIVE, SortOrder.DESCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); for (int i = 0; i < list.size(); i++) { Result r = sourceResponse.getResults() .get(i); assertEquals("Record " + i, r.getMetacard() .getTitle()); } // Sort all TEMPORAL ASC query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(Metacard.EFFECTIVE, SortOrder.ASCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); int index = 0; for (int i = (list.size() - 1); i >= 0; i--) { Result r = sourceResponse.getResults() .get(index); assertEquals("Record " + i, r.getMetacard() .getTitle()); index++; } // Sort all Relevancy score DESC filter = filterBuilder.attribute(Metacard.METADATA) .like() .text(FLAGSTAFF_QUERY_PHRASE); query = new QueryImpl(filter); query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(Result.RELEVANCE, SortOrder.DESCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); double currentScore = Integer.MAX_VALUE; for (Result r : sourceResponse.getResults()) { assertThat(currentScore, greaterThanOrEqualTo(r.getRelevanceScore())); currentScore = r.getRelevanceScore(); } // Sort all Relevancy score DESC filter = filterBuilder.attribute(Metacard.METADATA) .like() .text(FLAGSTAFF_QUERY_PHRASE); query = new QueryImpl(filter); query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(Result.RELEVANCE, SortOrder.ASCENDING.name())); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(list.size(), sourceResponse.getResults() .size()); currentScore = 0; for (Result r : sourceResponse.getResults()) { assertThat(currentScore, lessThanOrEqualTo(r.getRelevanceScore())); currentScore = r.getRelevanceScore(); } } @Test public void testStartIndexWithSorting() throws Exception { deleteAllIn(provider); List<Metacard> metacards = new ArrayList<Metacard>(); DateTime dt = new DateTime(1985, 1, 1, 1, 1, 1, 1, DateTimeZone.UTC); TreeSet<Date> calculatedDates = new TreeSet<Date>(); for (int j = 0; j < 10; j++) { for (int i = 0; i < 100; i = i + 10) { MetacardImpl metacard = new MockMetacard(Library.getFlagstaffRecord()); // ingest sporadically the effective dates so the default return // order won't be ordered Date calculatedDate = dt.plusDays(100 - i + 10 - j) .toDate(); calculatedDates.add(calculatedDate); metacard.setEffectiveDate(calculatedDate); metacards.add(metacard); } } // The TreeSet will sort them, the array will give me access to everyone // without an iterator Date[] dates = new Date[calculatedDates.size()]; calculatedDates.toArray(dates); /** CREATE **/ CreateResponse response = create(metacards); LOGGER.info("CREATED {} records.", response.getCreatedMetacards() .size()); CommonQueryBuilder queryBuilder = new CommonQueryBuilder(); QueryImpl query = queryBuilder.queryByProperty(Metacard.CONTENT_TYPE, MockMetacard.DEFAULT_TYPE); int maxSize = 20; int startIndex = 2; // STARTINDEX=2, MAXSIZE=20 query.setPageSize(maxSize); query.setStartIndex(startIndex); SortByImpl sortBy = new SortByImpl(queryBuilder.filterFactory.property(Metacard.EFFECTIVE), org.opengis.filter.sort.SortOrder.ASCENDING); query.setSortBy(sortBy); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(maxSize, sourceResponse.getResults() .size()); for (int i = 0; i < sourceResponse.getResults() .size(); i++) { Result r = sourceResponse.getResults() .get(i); Date effectiveDate = r.getMetacard() .getEffectiveDate(); DateTime currentDate = new DateTime(effectiveDate.getTime()); LOGGER.debug("Testing current index: {}", startIndex + i); assertEquals(new DateTime(dates[startIndex - 1 + i].getTime()).getDayOfYear(), currentDate.getDayOfYear()); } // STARTINDEX=20, MAXSIZE=5 // a match-all queryByProperty query = queryBuilder.queryByProperty(Metacard.CONTENT_TYPE, MockMetacard.DEFAULT_TYPE); maxSize = 5; startIndex = 20; query.setPageSize(maxSize); query.setStartIndex(startIndex); sortBy = new SortByImpl(queryBuilder.filterFactory.property(Metacard.EFFECTIVE), org.opengis.filter.sort.SortOrder.ASCENDING); query.setSortBy(sortBy); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(maxSize, sourceResponse.getResults() .size()); for (int i = 0; i < sourceResponse.getResults() .size(); i++) { Result r = sourceResponse.getResults() .get(i); Date effectiveDate = r.getMetacard() .getEffectiveDate(); DateTime currentDate = new DateTime(effectiveDate.getTime()); LOGGER.debug("Testing current index: {}", startIndex + i); assertEquals(new DateTime(dates[startIndex - 1 + i].getTime()).getDayOfYear(), currentDate.getDayOfYear()); } // STARTINDEX=80, MAXSIZE=20 // a match-all queryByProperty query = queryBuilder.queryByProperty(Metacard.CONTENT_TYPE, MockMetacard.DEFAULT_TYPE); maxSize = 20; startIndex = 80; query.setPageSize(maxSize); query.setStartIndex(startIndex); sortBy = new SortByImpl(queryBuilder.filterFactory.property(Metacard.EFFECTIVE), org.opengis.filter.sort.SortOrder.ASCENDING); query.setSortBy(sortBy); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(maxSize, sourceResponse.getResults() .size()); for (int i = 0; i < sourceResponse.getResults() .size(); i++) { Result r = sourceResponse.getResults() .get(i); Date effectiveDate = r.getMetacard() .getEffectiveDate(); DateTime currentDate = new DateTime(effectiveDate.getTime()); LOGGER.debug("Testing current index: {}", startIndex + i); assertEquals(new DateTime(dates[startIndex - 1 + i].getTime()).getDayOfYear(), currentDate.getDayOfYear()); } // STARTINDEX=1, MAXSIZE=100 // a match-all queryByProperty query = queryBuilder.queryByProperty(Metacard.CONTENT_TYPE, MockMetacard.DEFAULT_TYPE); maxSize = 100; startIndex = 1; query.setPageSize(maxSize); query.setStartIndex(startIndex); sortBy = new SortByImpl(queryBuilder.filterFactory.property(Metacard.EFFECTIVE), org.opengis.filter.sort.SortOrder.ASCENDING); query.setSortBy(sortBy); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(maxSize, sourceResponse.getResults() .size()); for (int i = 0; i < sourceResponse.getResults() .size(); i++) { Result r = sourceResponse.getResults() .get(i); Date effectiveDate = r.getMetacard() .getEffectiveDate(); DateTime currentDate = new DateTime(effectiveDate.getTime()); LOGGER.debug("Testing current index: {}", startIndex + i); assertEquals(new DateTime(dates[startIndex - 1 + i].getTime()).getDayOfYear(), currentDate.getDayOfYear()); } } /** * Tests the offset aka start index (startIndex) functionality. * * @throws Exception */ @Test public void testStartIndex() throws Exception { deleteAllIn(provider); List<Metacard> list = Arrays.asList((Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getFlagstaffRecord()), (Metacard) new MockMetacard(Library.getFlagstaffRecord())); /** CREATE **/ create(list); /** CONTEXTUAL QUERY **/ CommonQueryBuilder queryBuilder = new CommonQueryBuilder(); QueryImpl query = queryBuilder.queryByProperty(Metacard.TITLE, FLAGSTAFF_QUERY_PHRASE); int index = 0; int maxSize = 9; int startIndex = 1; query.setPageSize(maxSize); query.setStartIndex(startIndex); query.setRequestsTotalResultsCount(true); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(9, sourceResponse.getResults() .size()); assertEquals(9L, sourceResponse.getHits()); LinkedList<Result> allItems = new LinkedList<Result>(); for (Result r : sourceResponse.getResults()) { allItems.add(r); } // 1 maxSize = 1; startIndex = 2; index = startIndex - 1; query.setPageSize(maxSize); query.setStartIndex(startIndex); query.setRequestsTotalResultsCount(true); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(ONE_HIT, sourceResponse.getResults() .size()); assertEquals(9L, sourceResponse.getHits()); for (Result r : sourceResponse.getResults()) { assertEquals("Testing when startIndex = " + startIndex, allItems.get(index) .getMetacard() .getMetadata(), r.getMetacard() .getMetadata()); index++; } // 4 maxSize = 1; startIndex = 4; index = startIndex - 1; query.setPageSize(maxSize); query.setStartIndex(startIndex); query.setRequestsTotalResultsCount(false); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(ONE_HIT, sourceResponse.getResults() .size()); assertThat(sourceResponse.getHits(), anyOf(equalTo(-1L), equalTo(9L))); for (Result r : sourceResponse.getResults()) { assertEquals("Testing when startIndex = " + startIndex, allItems.get(index) .getMetacard() .getMetadata(), r.getMetacard() .getMetadata()); index++; } // 5 maxSize = 5; startIndex = 5; index = startIndex - 1; query.setPageSize(maxSize); query.setStartIndex(startIndex); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(5, sourceResponse.getResults() .size()); for (Result r : sourceResponse.getResults()) { assertEquals("Testing when startIndex = " + startIndex, allItems.get(index) .getMetacard() .getMetadata(), r.getMetacard() .getMetadata()); index++; } // 9 maxSize = 9; startIndex = 9; index = startIndex - 1; query.setPageSize(maxSize); query.setStartIndex(startIndex); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(ONE_HIT, sourceResponse.getResults() .size()); for (Result r : sourceResponse.getResults()) { assertEquals("Testing when startIndex = " + startIndex, allItems.get(index) .getMetacard() .getMetadata(), r.getMetacard() .getMetadata()); index++; } // Max size is very large maxSize = 100; startIndex = 9; index = startIndex - 1; query.setPageSize(maxSize); query.setStartIndex(startIndex); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(ONE_HIT, sourceResponse.getResults() .size()); for (Result r : sourceResponse.getResults()) { assertEquals(allItems.get(index) .getMetacard() .getMetadata(), r.getMetacard() .getMetadata()); index++; } // bad start index maxSize = 2; startIndex = ALL_RESULTS; index = startIndex - 1; query.setPageSize(maxSize); query.setStartIndex(startIndex); try { sourceResponse = provider.query(new QueryRequestImpl(query)); Assert.fail( "Expected an exception stating that the start index should be greater than 0. "); } catch (UnsupportedQueryException e) { assertTrue(e.getMessage() .indexOf("greater than 0") != ALL_RESULTS); } } @Test public void testSpatialPointRadius() throws Exception { deleteAllIn(provider); MetacardImpl metacard1 = new MockMetacard(Library.getFlagstaffRecord()); MetacardImpl metacard2 = new MockMetacard(Library.getTampaRecord()); MetacardImpl metacard3 = new MockMetacard(Library.getShowLowRecord()); // Add in the geometry metacard1.setLocation(FLAGSTAFF_AIRPORT_POINT_WKT); metacard2.setLocation(TAMPA_AIRPORT_POINT_WKT); metacard3.setLocation(SHOW_LOW_AIRPORT_POINT_WKT); List<Metacard> list = Arrays.asList((Metacard) metacard1, metacard2, metacard3); /** CREATE **/ create(list); Filter filter = filterBuilder.attribute(Metacard.ID) .is() .like() .text("*"); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Failed to find all records.", 3, sourceResponse.getResults() .size()); CommonQueryBuilder builder = new CommonQueryBuilder(); // Right on Flagstaff QueryImpl query = builder.pointRadius(-111.67121887207031, 35.138454437255859, 10.0); query.setPageSize(1); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals("Failed to find Flagstaff record only.", 1, sourceResponse.getResults() .size()); for (Result r : sourceResponse.getResults()) { assertTrue("Wrong record, Flagstaff keyword was not found.", ALL_RESULTS != r.getMetacard() .getMetadata() .indexOf(FLAGSTAFF_QUERY_PHRASE)); LOGGER.info("Distance to Flagstaff: {}", r.getDistanceInMeters()); // assertTrue(r.getDistanceInMeters() != null); } // Right on Flagstaff, finding 2 records with 195 km radius query = builder.pointRadius(-111.67121887207031, 35.138454437255859, 195000); query.setSortBy(new ddf.catalog.filter.impl.SortByImpl("foo", SortOrder.ASCENDING)); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals("Failed to find the two records.", 2, sourceResponse.getResults() .size()); ArrayList<Result> results = new ArrayList<Result>(); for (Result r : sourceResponse.getResults()) { results.add(r); } // must be in order because that was specified by the Sortby in the // querybuilder for (int i = 0; i < 2; i++) { Result result = results.get(i); LOGGER.info("Distance of [{}]]: {}", i, result.getDistanceInMeters()); if (i == 0) { assertTrue("Grabbed the wrong record.", ALL_RESULTS != result.getMetacard() .getMetadata() .indexOf(FLAGSTAFF_QUERY_PHRASE)); } if (i == 1) { assertTrue("Grabbed the wrong record - should be Show Low.", ALL_RESULTS != result.getMetacard() .getMetadata() .indexOf("Show Low")); } } // NEGATIVE CASE query = builder.pointRadius(80.1, 25, 195000); query.setPageSize(3); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals("Should have not found any records.", 0, sourceResponse.getResults() .size()); // FEET double[] coords = {-111.67121887207031, 35.138454437255859}; query = new QueryImpl(builder.filterFactory.dwithin(Metacard.ANY_GEO, new PointImpl(new DirectPositionImpl(coords), DefaultGeographicCRS.WGS84), 195000, UomOgcMapping.FOOT.name())); query.setStartIndex(1); SortByImpl sortby = new SortByImpl(builder.filterFactory.property(Result.DISTANCE), org.opengis.filter.sort.SortOrder.ASCENDING); query.setSortBy(sortby); query.setPageSize(3); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(1, sourceResponse.getResults() .size()); } @Test public void testSortedPointRadiusWithComplexQuery() throws Exception { deleteAllIn(provider); MetacardImpl metacard1 = new MockMetacard(Library.getFlagstaffRecord()); MetacardImpl metacard2 = new MockMetacard(Library.getTampaRecord()); MetacardImpl metacard3 = new MockMetacard(Library.getShowLowRecord()); // Add in the geometry metacard1.setLocation(FLAGSTAFF_AIRPORT_POINT_WKT); metacard2.setLocation(TAMPA_AIRPORT_POINT_WKT); metacard3.setLocation(SHOW_LOW_AIRPORT_POINT_WKT); // Add in a content type metacard1.setAttribute(Metacard.CONTENT_TYPE, "product"); List<Metacard> list = Arrays.asList((Metacard) metacard1, metacard2, metacard3); /** CREATE **/ create(list); // create a filter that has spatial and content type criteria Filter contentFilter = filterBuilder.attribute(Metacard.CONTENT_TYPE) .is() .text("product"); Filter spatialFilter = filterBuilder.attribute(Metacard.GEOGRAPHY) .intersecting() .wkt(FLAGSTAFF_AIRPORT_POINT_WKT); Filter finalFilter = filterBuilder.allOf(filterBuilder.attribute(Metacard.ANY_TEXT) .like() .text("flagstaff"), filterBuilder.allOf(contentFilter, spatialFilter)); // sort by distance QueryImpl query = new QueryImpl(finalFilter); SortBy sortby = new ddf.catalog.filter.impl.SortByImpl(Result.DISTANCE, org.opengis.filter.sort.SortOrder.DESCENDING); query.setSortBy(sortby); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals(1, sourceResponse.getResults() .size()); } @Test public void testSpatialNearestNeighbor() throws Exception { deleteAllIn(provider); MetacardImpl metacard1 = new MockMetacard(Library.getFlagstaffRecord()); MetacardImpl metacard2 = new MockMetacard(Library.getTampaRecord()); MetacardImpl metacard3 = new MockMetacard(Library.getShowLowRecord()); // Add in the geometry metacard1.setLocation(FLAGSTAFF_AIRPORT_POINT_WKT); metacard2.setLocation(TAMPA_AIRPORT_POINT_WKT); metacard3.setLocation(SHOW_LOW_AIRPORT_POINT_WKT); List<Metacard> list = Arrays.asList((Metacard) metacard1, metacard2, metacard3); create(list); // Ascending Filter positiveFilter = filterBuilder.attribute(Metacard.GEOGRAPHY) .beyond() .wkt(PHOENIX_POINT_WKT, 0); QueryImpl query = new QueryImpl(positiveFilter); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals("Failed to find two records within 1000 nautical miles.", 2, sourceResponse.getResults() .size()); assertTrue("Flagstaff record was not first in ascending order.", sourceResponse.getResults() .get(0) .getMetacard() .getMetadata() .indexOf(FLAGSTAFF_QUERY_PHRASE) > 0); // Descending SortBy sortby = new ddf.catalog.filter.impl.SortByImpl(Result.DISTANCE, org.opengis.filter.sort.SortOrder.DESCENDING); query.setSortBy(sortby); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals("Failed to find two records within 1000 nautical miles.", 2, sourceResponse.getResults() .size()); assertTrue("Flagstaff record was not last in descending order.", sourceResponse.getResults() .get(1) .getMetacard() .getMetadata() .indexOf(FLAGSTAFF_QUERY_PHRASE) > 0); // Using WKT polygon positiveFilter = filterBuilder.attribute(Metacard.GEOGRAPHY) .beyond() .wkt(ARIZONA_POLYGON_WKT, 0); query = new QueryImpl(positiveFilter); sourceResponse = provider.query(new QueryRequestImpl(query)); assertEquals("Failed to find two records based on polygon centroid.", 2, sourceResponse.getResults() .size()); } @Test public void testNearestNeighborBadConfig() { ConfigurationStore.getInstance() .setNearestNeighborDistanceLimit(Double.valueOf(1000)); ConfigurationStore.getInstance() .setNearestNeighborDistanceLimit(Double.valueOf(-3)); assertTrue(ConfigurationStore.getInstance() .getNearestNeighborDistanceLimit() != -3); ConfigurationStore.getInstance() .setNearestNeighborDistanceLimit(Double.valueOf(12)); assertTrue(ConfigurationStore.getInstance() .getNearestNeighborDistanceLimit() == 12); ConfigurationStore.getInstance() .setNearestNeighborDistanceLimit(Double.valueOf(1000)); } @Test public void testSpatialDistanceWithinPolygon() throws Exception { Filter positiveFilter = filterBuilder.attribute(Metacard.GEOGRAPHY) .withinBuffer() .wkt(ARIZONA_POLYGON_WKT, 50 * METERS_PER_KM); Filter negativeFilter = filterBuilder.attribute(Metacard.GEOGRAPHY) .withinBuffer() .wkt(ARIZONA_POLYGON_WKT, 10 * METERS_PER_KM); testSpatialWithWkt(LAS_VEGAS_POINT_WKT, positiveFilter, negativeFilter); } @Test public void testSpatialDistanceCalculationExactPoint() throws Exception { deleteAllIn(provider); // given double radiusInKilometers = 50; double radiusInMeters = radiusInKilometers * METERS_PER_KM; Filter positiveFilter = filterBuilder.attribute(Metacard.GEOGRAPHY) .withinBuffer() .wkt(LAS_VEGAS_POINT_WKT, radiusInMeters); MetacardImpl metacard = new MockMetacard(Library.getFlagstaffRecord()); metacard.setLocation(LAS_VEGAS_POINT_WKT); List<Metacard> list = Arrays.asList((Metacard) metacard); create(list); QueryImpl query = new QueryImpl(positiveFilter); query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(Result.DISTANCE, SortOrder.ASCENDING)); // when SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); // then assertEquals("Failed to find metacard WKT with filter", 1, sourceResponse.getResults() .size()); Result result = sourceResponse.getResults() .get(0); assertThat(result.getDistanceInMeters(), is(notNullValue())); assertThat("Point radius search should be less than the radius given.", result.getDistanceInMeters(), is(lessThanOrEqualTo(radiusInMeters))); double oneMeter = 1.0; assertThat("The distance should be close to zero since we are right upon the point.", result.getDistanceInMeters(), is(lessThanOrEqualTo(oneMeter))); } @Test public void testSpatialDistanceCalculationBetweenTwoPointsUsingDistanceSortBy() throws Exception { spatialDistanceCalculationBetweenTwoPoints(Metacard.GEOGRAPHY, Result.DISTANCE); } @Test public void testSpatialDistanceCalculationBetweenTwoPointsUsingAttributeSortBy() throws Exception { spatialDistanceCalculationBetweenTwoPoints("geoattribute", "geoattribute"); } private void spatialDistanceCalculationBetweenTwoPoints(String attribute, String sortBy) throws Exception { deleteAllIn(provider); // given double radiusInKilometers = 500; double radiusInMeters = radiusInKilometers * METERS_PER_KM; Filter positiveFilter = filterBuilder.attribute(attribute) .withinBuffer() .wkt(PHOENIX_POINT_WKT, radiusInMeters); MetacardImpl metacard; if (attribute.equals(Metacard.GEOGRAPHY)) { metacard = new MockMetacard(Library.getFlagstaffRecord()); } else { metacard = new MockMetacard(Library.getFlagstaffRecord(), new MetacardTypeImpl( "distanceTest", BasicTypes.BASIC_METACARD, Sets.newSet(new AttributeDescriptorImpl(attribute, true, true, true, true, BasicTypes.GEO_TYPE)))); } metacard.setAttribute(attribute, LAS_VEGAS_POINT_WKT); List<Metacard> list = Arrays.asList((Metacard) metacard); create(list); QueryImpl query = new QueryImpl(positiveFilter); query.setSortBy(new ddf.catalog.filter.impl.SortByImpl(sortBy, SortOrder.ASCENDING)); // when SourceResponse sourceResponse = provider.query(new QueryRequestImpl(query)); // then assertEquals("Failed to find metacard WKT with filter", 1, sourceResponse.getResults() .size()); Result result = sourceResponse.getResults() .get(0); assertThat(result.getDistanceInMeters(), is(notNullValue())); assertThat("Point radius search should be less than the radius given.", result.getDistanceInMeters(), is(lessThanOrEqualTo(radiusInMeters))); // expected distance calculated from // http://www.movable-type.co.uk/scripts/latlong.html double expectedDistanceBetweenCitiesInMeters = 412700; double precisionPercentage = .001; // +/-0.1% double lowerBound = expectedDistanceBetweenCitiesInMeters * (1 - precisionPercentage); double upperBound = expectedDistanceBetweenCitiesInMeters * (1 + precisionPercentage); assertThat("The distance returned should at least be above the lower bound of error.", result.getDistanceInMeters(), is(greaterThanOrEqualTo(lowerBound))); assertThat("The distance returned should at least be below the upper bound of error.", result.getDistanceInMeters(), is(lessThanOrEqualTo(upperBound))); } @Test public void testSpatialWithin() throws Exception { Filter positiveFilter = filterBuilder.attribute(Metacard.GEOGRAPHY) .within() .wkt(ARIZONA_POLYGON_WKT); Filter negativeFilter = filterBuilder.attribute(Metacard.GEOGRAPHY) .within() .wkt(GULF_OF_GUINEA_POLYGON_WKT); testSpatialWithWkt(FLAGSTAFF_AIRPORT_POINT_WKT, positiveFilter, negativeFilter); } @Test public void testSpatialQueryWithClockwiseRectangle() throws Exception { deleteAllIn(provider); MetacardImpl metacard = new MockMetacard(Library.getFlagstaffRecord()); metacard.setLocation(FLAGSTAFF_AIRPORT_POINT_WKT); List<Metacard> list = Arrays.asList((Metacard) metacard); /** CREATE **/ create(list); /** POSITIVE **/ Filter filter = filterBuilder.attribute(Metacard.GEOGRAPHY) .intersecting() .wkt(CLOCKWISE_ARIZONA_RECTANGLE_WKT); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Failed to find Flagstaff record.", 1, sourceResponse.getResults() .size()); for (Result r : sourceResponse.getResults()) { assertTrue("Wrong record, Flagstaff keyword was not found.", ALL_RESULTS != r.getMetacard() .getMetadata() .indexOf(FLAGSTAFF_QUERY_PHRASE)); } } @Test public void testSpatialQueryAcrossInternationalDateLine() throws Exception { deleteAllIn(provider); MetacardImpl metacard = new MockMetacard(Library.getFlagstaffRecord()); metacard.setLocation(MIDWAY_ISLANDS_POINT_WKT); List<Metacard> list = Arrays.asList((Metacard) metacard); create(list); /** POSITIVE - Counter Clockwise Orientation **/ Filter filter = filterBuilder.attribute(Metacard.GEOGRAPHY) .intersecting() .wkt(ACROSS_INTERNATIONAL_DATELINE_LARGE_CCW_WKT); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Failed to find the correct record. ", 1, sourceResponse.getResults() .size()); for (Result r : sourceResponse.getResults()) { assertTrue("Wrong record, Flagstaff keyword was not found.", ALL_RESULTS != r.getMetacard() .getMetadata() .indexOf(FLAGSTAFF_QUERY_PHRASE)); } /** POSITIVE - Clockwise Orientation **/ filter = filterBuilder.attribute(Metacard.GEOGRAPHY) .intersecting() .wkt(ACROSS_INTERNATIONAL_DATELINE_LARGE_CW_WKT); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Failed to find the correct record. ", 1, sourceResponse.getResults() .size()); for (Result r : sourceResponse.getResults()) { assertTrue("Wrong record, Flagstaff keyword was not found.", ALL_RESULTS != r.getMetacard() .getMetadata() .indexOf(FLAGSTAFF_QUERY_PHRASE)); } /** NEGATIVE **/ filter = filterBuilder.attribute(Metacard.GEOGRAPHY) .intersecting() .wkt(ACROSS_INTERNATIONAL_DATELINE_SMALL_WKT); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Should not find a record. ", 0, sourceResponse.getResults() .size()); } @Test public void testSpatialCreateAndUpdateWithClockwiseRectangle() throws Exception { deleteAllIn(provider); /** CREATE **/ MockMetacard metacard = new MockMetacard(Library.getFlagstaffRecord()); metacard.setLocation(CLOCKWISE_ARIZONA_RECTANGLE_WKT); CreateResponse createResponse = create(Arrays.asList((Metacard) metacard)); assertEquals(1, createResponse.getCreatedMetacards() .size()); Filter filter = filterBuilder.attribute(Metacard.GEOGRAPHY) .intersecting() .wkt(FLAGSTAFF_AIRPORT_POINT_WKT); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Failed to find correct record.", 1, sourceResponse.getResults() .size()); /** UPDATE **/ MockMetacard updatedMetacard = new MockMetacard(Library.getTampaRecord()); updatedMetacard.setLocation(CLOCKWISE_ARIZONA_RECTANGLE_WKT); String[] ids = {metacard.getId()}; UpdateResponse updateResponse = update(ids, Arrays.asList((Metacard) updatedMetacard)); assertEquals(1, updateResponse.getUpdatedMetacards() .size()); filter = filterBuilder.attribute(Metacard.GEOGRAPHY) .intersecting() .wkt(FLAGSTAFF_AIRPORT_POINT_WKT); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Failed to find correct record.", 1, sourceResponse.getResults() .size()); } @Test public void testSpatialQueryWithCounterClockwiseRectangle() throws Exception { deleteAllIn(provider); MetacardImpl metacard = new MockMetacard(Library.getFlagstaffRecord()); metacard.setLocation(FLAGSTAFF_AIRPORT_POINT_WKT); List<Metacard> list = Arrays.asList((Metacard) metacard); /** CREATE **/ create(list); /** POSITIVE **/ Filter filter = filterBuilder.attribute(Metacard.GEOGRAPHY) .intersecting() .wkt(COUNTERCLOCKWISE_ARIZONA_RECTANGLE_WKT); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Failed to find Flagstaff record.", 1, sourceResponse.getResults() .size()); for (Result r : sourceResponse.getResults()) { assertTrue("Wrong record, Flagstaff keyword was not found.", ALL_RESULTS != r.getMetacard() .getMetadata() .indexOf(FLAGSTAFF_QUERY_PHRASE)); } } @Test public void testSpatialPointIntersectsPoint() throws Exception { testSpatialIntersectsWithWkt(FLAGSTAFF_AIRPORT_POINT_WKT, FLAGSTAFF_AIRPORT_POINT_WKT, GULF_OF_GUINEA_POINT_WKT); } @Test public void testSpatialMultiPointIntersectsPoint() throws Exception { testSpatialIntersectsWithWkt(GULF_OF_GUINEA_POINT_WKT, GULF_OF_GUINEA_MULTIPOINT_WKT, FLAGSTAFF_AIRPORT_POINT_WKT); } @Test public void testSpatialMultiPointSingleIntersectsPoint() throws Exception { testSpatialIntersectsWithWkt(GULF_OF_GUINEA_POINT_WKT, GULF_OF_GUINEA_MULTIPOINT_SINGLE_WKT, FLAGSTAFF_AIRPORT_POINT_WKT); } @Test public void testSpatialPolygonIntersectsPoint() throws Exception { testSpatialIntersectsWithWkt(ARIZONA_POLYGON_WKT, FLAGSTAFF_AIRPORT_POINT_WKT, GULF_OF_GUINEA_POINT_WKT); } @Test public void testSpatialPolygonIntersectsLineString() throws Exception { testSpatialIntersectsWithWkt(ARIZONA_POLYGON_WKT, ARIZONA_INTERSECTING_LINESTING_WKT, GULF_OF_GUINEA_LINESTRING_WKT); } @Test public void testSpatialPolygonIntersectsPolygon() throws Exception { testSpatialIntersectsWithWkt(ARIZONA_POLYGON_WKT, ARIZONA_INTERSECTING_POLYGON_WKT, GULF_OF_GUINEA_POLYGON_WKT); } @Test public void testSpatialPolygonIntersectsMultiPoint() throws Exception { testSpatialIntersectsWithWkt(ARIZONA_POLYGON_WKT, PHOENIX_AND_LAS_VEGAS_MULTIPOINT_WKT, GULF_OF_GUINEA_MULTIPOINT_WKT); } @Test public void testSpatialPolygonIntersectsMultiLineString() throws Exception { testSpatialIntersectsWithWkt(ARIZONA_POLYGON_WKT, ARIZONA_INTERSECTING_MULTILINESTING_WKT, GULF_OF_GUINEA_MULTILINESTRING_WKT); } @Test public void testSpatialPolygonIntersectsMultiPolygon() throws Exception { testSpatialIntersectsWithWkt(ARIZONA_POLYGON_WKT, ARIZONA_INTERSECTING_MULTIPOLYGON_WKT, GULF_OF_GUINEA_MULTIPOLYGON_WKT); } @Test public void testSpatialPolygonIntersectsGeometryCollection() throws Exception { testSpatialIntersectsWithWkt(ARIZONA_POLYGON_WKT, ARIZONA_INTERSECTING_GEOMETRYCOLLECTION_WKT, GULF_OF_GUINEA_GEOMETRYCOLLECTION_WKT); } @Test public void testSpatialGeometryCollectionIntersectsPoint() throws Exception { testSpatialIntersectsWithWkt(ARABIAN_SEA_OVERLAPPING_GEOMETRYCOLLECTION_WKT, ARABIAN_SEA_POINT_WKT, GULF_OF_GUINEA_GEOMETRYCOLLECTION_WKT); } @Test public void testSpatialPointWithinPolygon() throws Exception { testSpatialWithinWithWkt(FLAGSTAFF_AIRPORT_POINT_WKT, WEST_USA_CONTAINING_POLYGON_WKT, GULF_OF_GUINEA_POLYGON_WKT); } @Test public void testSpatialLineStringWithinPolygon() throws Exception { testSpatialWithinWithWkt(ARIZONA_INTERSECTING_LINESTING_WKT, WEST_USA_CONTAINING_POLYGON_WKT, GULF_OF_GUINEA_POLYGON_WKT); } @Test public void testSpatialPolygonWithinPolygon() throws Exception { testSpatialWithinWithWkt(ARIZONA_INTERSECTING_POLYGON_WKT, WEST_USA_CONTAINING_POLYGON_WKT, GULF_OF_GUINEA_POLYGON_WKT); } @Test public void testSpatialMultiPointWithinPolygon() throws Exception { testSpatialWithinWithWkt(PHOENIX_AND_LAS_VEGAS_MULTIPOINT_WKT, WEST_USA_CONTAINING_POLYGON_WKT, GULF_OF_GUINEA_POLYGON_WKT); } @Test public void testSpatialMultiLineStringWithinPolygon() throws Exception { testSpatialWithinWithWkt(ARIZONA_INTERSECTING_MULTILINESTING_WKT, WEST_USA_CONTAINING_POLYGON_WKT, GULF_OF_GUINEA_POLYGON_WKT); } @Test public void testSpatialMultiPolygonWithinPolygon() throws Exception { testSpatialWithinWithWkt(ARIZONA_INTERSECTING_MULTIPOLYGON_WKT, WEST_USA_CONTAINING_POLYGON_WKT, GULF_OF_GUINEA_POLYGON_WKT); } @Test public void testSpatialGeometryCollectionWithinPolygon() throws Exception { testSpatialWithinWithWkt(ARIZONA_INTERSECTING_GEOMETRYCOLLECTION_WKT, WEST_USA_CONTAINING_POLYGON_WKT, GULF_OF_GUINEA_POLYGON_WKT); } @Test public void testSpatialPolygonContainsPoint() throws Exception { Filter positiveFilter = filterBuilder.attribute(Metacard.GEOGRAPHY) .containing() .wkt(FLAGSTAFF_AIRPORT_POINT_WKT); Filter negativeFilter = filterBuilder.attribute(Metacard.GEOGRAPHY) .containing() .wkt(GULF_OF_GUINEA_POINT_WKT); testSpatialWithWkt(ARIZONA_POLYGON_WKT, positiveFilter, negativeFilter); } @Test public void testSpatialAnyGeo() throws Exception { Filter positiveFilter = filterBuilder.attribute(Metacard.ANY_GEO) .within() .wkt(ARIZONA_POLYGON_WKT); Filter negativeFilter = filterBuilder.attribute(Metacard.ANY_GEO) .within() .wkt(GULF_OF_GUINEA_POLYGON_WKT); testSpatialWithWkt(FLAGSTAFF_AIRPORT_POINT_WKT, positiveFilter, negativeFilter); } private void testSpatialWithinWithWkt(String metacardWkt, String positiveWkt, String negativeWkt) throws Exception { Filter positiveFilter = filterBuilder.attribute(Metacard.ANY_GEO) .within() .wkt(positiveWkt); Filter negativeFilter = filterBuilder.attribute(Metacard.ANY_GEO) .within() .wkt(negativeWkt); testSpatialWithWkt(metacardWkt, positiveFilter, negativeFilter); } private void testSpatialIntersectsWithWkt(String metacardWkt, String positiveWkt, String negativeWkt) throws Exception { Filter positiveFilter = filterBuilder.attribute(Metacard.ANY_GEO) .intersecting() .wkt(positiveWkt); Filter negativeFilter = filterBuilder.attribute(Metacard.ANY_GEO) .intersecting() .wkt(negativeWkt); testSpatialWithWkt(metacardWkt, positiveFilter, negativeFilter); positiveFilter = filterBuilder.attribute(Metacard.ANY_GEO) .intersecting() .wkt(metacardWkt); testSpatialWithWkt(positiveWkt, positiveFilter, negativeFilter); } private void testSpatialWithWkt(String metacardWkt, Filter positiveFilter, Filter negativeFilter) throws Exception { deleteAllIn(provider, 4); MetacardImpl metacard = new MockMetacard(Library.getFlagstaffRecord()); metacard.setLocation(metacardWkt); List<Metacard> list = Arrays.asList((Metacard) metacard); create(list); SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl( positiveFilter))); assertEquals("Failed to find metacard WKT with filter", 1, sourceResponse.getResults() .size()); sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(negativeFilter))); assertEquals("Should not have found metacard record.", 0, sourceResponse.getResults() .size()); } @Test public void testGetContentTypesSimple() throws Exception { deleteAllIn(provider); MockMetacard metacard1 = new MockMetacard(Library.getFlagstaffRecord()); MockMetacard metacard2 = new MockMetacard(Library.getShowLowRecord()); MockMetacard metacard3 = new MockMetacard(Library.getTampaRecord()); metacard1.setContentTypeName(SAMPLE_CONTENT_TYPE_1); metacard2.setContentTypeName(SAMPLE_CONTENT_TYPE_2); metacard3.setContentTypeName(SAMPLE_CONTENT_TYPE_2); metacard3.setContentTypeVersion(SAMPLE_CONTENT_VERSION_3); List<Metacard> list = Arrays.asList((Metacard) metacard1, metacard2, metacard3); create(list); Set<ContentType> contentTypes = provider.getContentTypes(); assertEquals(3, contentTypes.size()); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_1, MockMetacard.DEFAULT_VERSION))); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_2, MockMetacard.DEFAULT_VERSION))); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_2, SAMPLE_CONTENT_VERSION_3))); } @Test public void testGetContentTypesComplicated() throws Exception { deleteAllIn(provider); List<Metacard> list = new ArrayList<Metacard>(); // Single content type and version MockMetacard metacard1 = new MockMetacard(Library.getFlagstaffRecord()); metacard1.setContentTypeName(SAMPLE_CONTENT_TYPE_1); metacard1.setContentTypeVersion(SAMPLE_CONTENT_VERSION_1); list.add(metacard1); // one content type with multiple versions metacard1 = new MockMetacard(Library.getFlagstaffRecord()); metacard1.setContentTypeName(SAMPLE_CONTENT_TYPE_2); metacard1.setContentTypeVersion(SAMPLE_CONTENT_VERSION_1); list.add(metacard1); MockMetacard metacard2 = new MockMetacard(Library.getFlagstaffRecord()); metacard2.setContentTypeName(SAMPLE_CONTENT_TYPE_2); metacard2.setContentTypeVersion(SAMPLE_CONTENT_VERSION_2); list.add(metacard2); // multiple records with different content type but same version metacard1 = new MockMetacard(Library.getFlagstaffRecord()); metacard1.setContentTypeName(SAMPLE_CONTENT_TYPE_3); metacard1.setContentTypeVersion(SAMPLE_CONTENT_VERSION_3); list.add(metacard1); metacard2 = new MockMetacard(Library.getFlagstaffRecord()); metacard2.setContentTypeName(SAMPLE_CONTENT_TYPE_3); metacard2.setContentTypeVersion(SAMPLE_CONTENT_VERSION_4); list.add(metacard2); // multiple records with different content type and different version metacard1 = new MockMetacard(Library.getFlagstaffRecord()); metacard1.setContentTypeName(SAMPLE_CONTENT_TYPE_4); metacard1.setContentTypeVersion(SAMPLE_CONTENT_VERSION_1); list.add(metacard1); metacard2 = new MockMetacard(Library.getFlagstaffRecord()); metacard2.setContentTypeName(SAMPLE_CONTENT_TYPE_1); metacard2.setContentTypeVersion(SAMPLE_CONTENT_VERSION_4); list.add(metacard2); metacard1 = new MockMetacard(Library.getFlagstaffRecord()); metacard1.setContentTypeName(SAMPLE_CONTENT_TYPE_4); metacard1.setContentTypeVersion(SAMPLE_CONTENT_VERSION_1); list.add(metacard1); metacard2 = new MockMetacard(Library.getFlagstaffRecord()); metacard2.setContentTypeName(SAMPLE_CONTENT_TYPE_1); metacard2.setContentTypeVersion(SAMPLE_CONTENT_VERSION_4); list.add(metacard2); create(list); Set<ContentType> contentTypes = provider.getContentTypes(); assertEquals(7, contentTypes.size()); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_1, SAMPLE_CONTENT_VERSION_1))); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_2, SAMPLE_CONTENT_VERSION_1))); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_2, SAMPLE_CONTENT_VERSION_2))); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_3, SAMPLE_CONTENT_VERSION_3))); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_3, SAMPLE_CONTENT_VERSION_4))); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_4, SAMPLE_CONTENT_VERSION_1))); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_1, SAMPLE_CONTENT_VERSION_4))); } @Test public void testGetContentTypesOne() throws Exception { deleteAllIn(provider); MockMetacard metacard1 = new MockMetacard(Library.getFlagstaffRecord()); metacard1.setContentTypeName(SAMPLE_CONTENT_TYPE_1); List<Metacard> list = Arrays.asList((Metacard) metacard1); create(list); Set<ContentType> contentTypes = provider.getContentTypes(); assertEquals(1, contentTypes.size()); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_1, MockMetacard.DEFAULT_VERSION))); } @Test public void testGetContentTypesOneNoVersion() throws Exception { deleteAllIn(provider); MockMetacard metacard1 = new MockMetacard(Library.getFlagstaffRecord()); metacard1.setContentTypeName(SAMPLE_CONTENT_TYPE_1); metacard1.setContentTypeVersion(null); List<Metacard> list = Arrays.asList((Metacard) metacard1); create(list); Set<ContentType> contentTypes = provider.getContentTypes(); assertEquals(1, contentTypes.size()); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_1, null))); } @Test public void testGetContentTypesVersionsAndNullVersions() throws Exception { deleteAllIn(provider); MockMetacard metacard1 = new MockMetacard(Library.getFlagstaffRecord()); MockMetacard metacard2 = new MockMetacard(Library.getShowLowRecord()); MockMetacard metacard3 = new MockMetacard(Library.getTampaRecord()); metacard1.setContentTypeName(SAMPLE_CONTENT_TYPE_1); metacard1.setContentTypeVersion(null); metacard2.setContentTypeName(SAMPLE_CONTENT_TYPE_2); metacard3.setContentTypeName(SAMPLE_CONTENT_TYPE_2); metacard3.setContentTypeVersion(SAMPLE_CONTENT_VERSION_3); List<Metacard> list = Arrays.asList((Metacard) metacard1, metacard2, metacard3); create(list); Set<ContentType> contentTypes = provider.getContentTypes(); assertEquals(3, contentTypes.size()); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_1, null))); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_2, MockMetacard.DEFAULT_VERSION))); assertThat(contentTypes, hasItem((ContentType) new ContentTypeImpl(SAMPLE_CONTENT_TYPE_2, SAMPLE_CONTENT_VERSION_3))); } @Test public void testGetContentTypesNone() throws Exception { deleteAllIn(provider); assertEquals(0, provider.getContentTypes() .size()); } @Test public void testIsAvalaible() throws Exception { assertTrue(provider.isAvailable()); } /** * Test that makes sure sourceId is returned for deletions, creates, and updates. * * @throws Exception */ @Test public void testSourceId() throws Exception { assertThat(provider.getId(), notNullValue()); // need more here, how can we test this further } @Test public void testDescribable() throws Exception { LOGGER.debug("version: {}", provider.getVersion()); LOGGER.debug("description: {}", provider.getDescription()); LOGGER.debug("org: {}", provider.getOrganization()); LOGGER.debug("name: {}", provider.getTitle()); assertNotNull(provider.getOrganization()); assertNotNull(provider.getVersion()); assertNotNull(provider.getDescription()); assertNotNull(provider.getOrganization()); assertNotNull(provider.getTitle()); } /** * Checks if it flag is false, text path indexing works * * @throws Exception */ @Test public void testDisableTextPathFalse() throws Exception { prepareXPath(false); queryXpathPositiveExists("//comment", "Hurry, my lawn is going wild!"); queryXpathNegativeExists("//foo"); } /** * If we disable text path support, we expect 0 results. * * @throws Exception */ @Test public void testDisableTextPathTrueExistsFilter() throws Exception { prepareXPath(true); queryXpathNegativeExists("//comment"); } /** * If we disable text path support, we expect 0 results. * * @throws Exception */ @Test public void testDisableTextPathTrueLikeFilter() throws Exception { prepareXPath(true); queryXpathNegativeWithSearchPhrase("//comment", "Hurry, my lawn is going wild!"); } /** * If we disable text path support, we expect 0 results. * * @throws Exception */ @Test public void testDisableTextPathTrueFuzzy() throws Exception { prepareXPath(true); assertNotFilter(filterBuilder.xpath("//comment") .is() .like() .fuzzyText("Hurry, my lawn is going wild!")); } private void prepareXPath(boolean isXpathDisabled) throws IngestException, UnsupportedQueryException { ConfigurationStore.getInstance() .setDisableTextPath(isXpathDisabled); deleteAllIn(provider); MetacardImpl flagstaffMetacard = new MockMetacard(Library.getFlagstaffRecord()); MetacardImpl poMetacard = new MockMetacard(Library.getPurchaseOrderRecord()); List<Metacard> list = Arrays.asList((Metacard) flagstaffMetacard, (Metacard) poMetacard); /** CREATE **/ create(list); } private void assertNotFilter(Filter filter) throws UnsupportedQueryException { SourceResponse sourceResponse = provider.query(new QueryRequestImpl(new QueryImpl(filter))); assertEquals("Found a metacard and should not have.", 0, sourceResponse.getResults() .size()); } private void verifyDeletedRecord(MockMetacard metacard, CreateResponse createResponse, DeleteResponse deleteResponse, Metacard deletedMetacard) { assertEquals(1, deleteResponse.getDeletedMetacards() .size()); assertEquals(createResponse.getCreatedMetacards() .get(0) .getId(), deletedMetacard.getId()); assertEquals(MockMetacard.DEFAULT_TITLE, deletedMetacard.getTitle()); assertEquals(MockMetacard.DEFAULT_LOCATION, deletedMetacard.getLocation()); assertEquals(MockMetacard.DEFAULT_TYPE, deletedMetacard.getContentTypeName()); assertEquals(MockMetacard.DEFAULT_VERSION, deletedMetacard.getContentTypeVersion()); assertNotNull(deletedMetacard.getMetadata()); assertTrue(!deletedMetacard.getMetadata() .isEmpty()); assertFalse(deletedMetacard.getCreatedDate() .after(new Date())); assertFalse(deletedMetacard.getModifiedDate() .after(new Date())); assertEquals(metacard.getEffectiveDate(), deletedMetacard.getEffectiveDate()); assertEquals(metacard.getExpirationDate(), deletedMetacard.getExpirationDate()); assertTrue(Arrays.equals(metacard.getThumbnail(), deletedMetacard.getThumbnail())); assertEquals(metacard.getLocation(), deletedMetacard.getLocation()); } private Date getCannedTime(int year, int month, int day, int hour) { Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("UTC")); calendar.clear(); calendar.set(year, month, day, hour, 59, 56); calendar.set(Calendar.MILLISECOND, 765); return calendar.getTime(); } }