http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/646d21b4/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java
----------------------------------------------------------------------
diff --git 
a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java
 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java
new file mode 100644
index 0000000..7151b56
--- /dev/null
+++ 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalProviderTest.java
@@ -0,0 +1,222 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.indexing.geotemporal;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+
+import java.util.List;
+
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexSetProvider;
+import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.ValueFactoryImpl;
+
+public class GeoTemporalProviderTest extends GeoTemporalTestBase {
+    private static final String URI_PROPERTY_AT_TIME = "Property:atTime";
+    private GeoTemporalIndexSetProvider provider;
+    private EventStorage events;
+    @Before
+    public void setup() {
+        events = mock(EventStorage.class);
+        provider = new GeoTemporalIndexSetProvider(events);
+    }
+
+    /*
+     * Simplest Happy Path test
+     */
+    @Test
+    public void twoPatternsTwoFilters_test() throws Exception {
+        final ValueFactory vf = new ValueFactoryImpl();
+        final Value geo = vf.createLiteral("Point(0 0)", 
GeoConstants.XMLSCHEMA_OGC_WKT);
+        final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 
12, 30, 12, 00, 0).toString());
+        final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+        final String query =
+            "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+            "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+            "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+            "SELECT * WHERE { " +
+                "?subj <" + tempPred + "> ?time ."+
+                "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+                " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+                " FILTER(time:equals(?time, " + temp + ")) . " +
+            "}";
+        final QuerySegment<EventQueryNode> node = getQueryNode(query);
+        final List<EventQueryNode> nodes = provider.getExternalSets(node);
+        assertEquals(1, nodes.size());
+    }
+
+    @Test
+    public void onePatternTwoFilters_test() throws Exception {
+        final ValueFactory vf = new ValueFactoryImpl();
+        final Value geo = vf.createLiteral("Point(0 0)", 
GeoConstants.XMLSCHEMA_OGC_WKT);
+        final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 
12, 30, 12, 00, 0).toString());
+        final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+        final String query =
+            "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+            "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+            "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+            "SELECT * WHERE { " +
+                "?subj <" + tempPred + "> ?time ."+
+                " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+                " FILTER(time:equals(?time, " + temp + ")) . " +
+            "}";
+        final QuerySegment<EventQueryNode> node = getQueryNode(query);
+        final List<EventQueryNode> nodes = provider.getExternalSets(node);
+        assertEquals(0, nodes.size());
+    }
+
+    @Test
+    public void twoPatternsOneFilter_test() throws Exception {
+        final ValueFactory vf = new ValueFactoryImpl();
+        final Value geo = vf.createLiteral("Point(0 0)", 
GeoConstants.XMLSCHEMA_OGC_WKT);
+        final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 
12, 30, 12, 00, 0).toString());
+        final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+        final String query =
+            "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+            "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+            "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+            "SELECT * WHERE { " +
+                "?subj <" + tempPred + "> ?time ."+
+                "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+                " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+            "}";
+        final QuerySegment<EventQueryNode> node = getQueryNode(query);
+        final List<EventQueryNode> nodes = provider.getExternalSets(node);
+        assertEquals(0, nodes.size());
+    }
+
+    @Test
+    public void twoPatternsNoFilter_test() throws Exception {
+        final ValueFactory vf = new ValueFactoryImpl();
+        final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+        final String query =
+            "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+            "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+            "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+            "SELECT * WHERE { " +
+                "?subj <" + tempPred + "> ?time ."+
+                "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+            "}";
+        final QuerySegment<EventQueryNode> node = getQueryNode(query);
+        final List<EventQueryNode> nodes = provider.getExternalSets(node);
+        assertEquals(0, nodes.size());
+    }
+
+    @Test
+    public void twoPatternsTwoFiltersNotValid_test() throws Exception {
+        final ValueFactory vf = new ValueFactoryImpl();
+        final Value geo = vf.createLiteral("Point(0 0)", 
GeoConstants.XMLSCHEMA_OGC_WKT);
+        final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 
12, 30, 12, 00, 0).toString());
+        final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+        //Only handles geo and temporal filters
+        final String query =
+            "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+            "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+            "PREFIX text: <http://rdf.useekm.com/fts#text>" +
+            "SELECT * WHERE { " +
+                "?subj <" + tempPred + "> ?time ."+
+                "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+                " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+                " FILTER(text:equals(?time, " + temp + ")) . " +
+            "}";
+        final QuerySegment<EventQueryNode> node = getQueryNode(query);
+        final List<EventQueryNode> nodes = provider.getExternalSets(node);
+        assertEquals(0, nodes.size());
+    }
+
+    @Test
+    public void twoSubjOneFilter_test() throws Exception {
+        final ValueFactory vf = new ValueFactoryImpl();
+        final Value geo = vf.createLiteral("Point(0 0)", 
GeoConstants.XMLSCHEMA_OGC_WKT);
+        final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 
12, 30, 12, 00, 0).toString());
+        final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+        final String query =
+            "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+            "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+            "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+            "SELECT * WHERE { " +
+                "?subj <" + tempPred + "> ?time ."+
+                "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+                "?subj2 <" + tempPred + "> ?time2 ."+
+                "?subj2 <" + GeoConstants.GEO_AS_WKT + "> ?loc2 . " +
+                " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+                " FILTER(time:equals(?time, " + temp + ")) . " +
+            "}";
+        final QuerySegment<EventQueryNode> node = getQueryNode(query);
+        final List<EventQueryNode> nodes = provider.getExternalSets(node);
+        assertEquals(1, nodes.size());
+    }
+
+    @Test
+    public void twoNode_test() throws Exception {
+        final ValueFactory vf = new ValueFactoryImpl();
+        final Value geo = vf.createLiteral("Point(0 0)", 
GeoConstants.XMLSCHEMA_OGC_WKT);
+        final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 
12, 30, 12, 00, 0).toString());
+        final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+        final String query =
+            "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+            "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+            "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+            "SELECT * WHERE { " +
+                "?subj <" + tempPred + "> ?time ."+
+                "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+                "?subj2 <" + tempPred + "> ?time2 ."+
+                "?subj2 <" + GeoConstants.GEO_AS_WKT + "> ?loc2 . " +
+                " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+                " FILTER(time:equals(?time, " + temp + ")) . " +
+                " FILTER(geos:sfContains(?loc2, " + geo + ")) . " +
+                " FILTER(time:equals(?time2, " + temp + ")) . " +
+            "}";
+        final QuerySegment<EventQueryNode> node = getQueryNode(query);
+        final List<EventQueryNode> nodes = provider.getExternalSets(node);
+        assertEquals(2, nodes.size());
+    }
+
+    @Test
+    public void twoSubjectMultiFilter_test() throws Exception {
+        final ValueFactory vf = new ValueFactoryImpl();
+        final Value geo = vf.createLiteral("Point(0 0)", 
GeoConstants.XMLSCHEMA_OGC_WKT);
+        final Value temp = vf.createLiteral(new TemporalInstantRfc3339(2015, 
12, 30, 12, 00, 0).toString());
+        final URI tempPred = vf.createURI(URI_PROPERTY_AT_TIME);
+        final String query =
+            "PREFIX geo: <http://www.opengis.net/ont/geosparql#>" +
+            "PREFIX geos: <http://www.opengis.net/def/function/geosparql/>" +
+            "PREFIX time: <tag:rya-rdf.org,2015:temporal#>" +
+            "SELECT * WHERE { " +
+                "?subj <" + tempPred + "> ?time ."+
+                "?subj <" + GeoConstants.GEO_AS_WKT + "> ?loc . " +
+                " FILTER(geos:sfContains(?loc, " + geo + ")) . " +
+                " FILTER(time:equals(?time, " + temp + ")) . " +
+                " FILTER(geos:sfWithin(?loc, " + geo + ")) . " +
+                " FILTER(time:before(?time, " + temp + ")) . " +
+            "}";
+        final QuerySegment<EventQueryNode> node = getQueryNode(query);
+        final List<EventQueryNode> nodes = provider.getExternalSets(node);
+        assertEquals(1, nodes.size());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/646d21b4/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java
----------------------------------------------------------------------
diff --git 
a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java
 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java
new file mode 100644
index 0000000..6b6bf15
--- /dev/null
+++ 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/GeoTemporalTestBase.java
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.indexing.geotemporal;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.apache.rya.indexing.geotemporal.model.EventQueryNode;
+import org.junit.ComparisonFailure;
+import org.mockito.Mockito;
+import org.openrdf.query.algebra.FunctionCall;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
+import org.openrdf.query.algebra.helpers.StatementPatternCollector;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.Point;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.PrecisionModel;
+import com.vividsolutions.jts.geom.impl.PackedCoordinateSequence;
+
+public class GeoTemporalTestBase {
+    private static final GeometryFactory gf = new GeometryFactory(new 
PrecisionModel(), 4326);
+
+    /**
+     * Make an uniform instant with given seconds.
+     */
+    protected static TemporalInstant makeInstant(final int 
secondsMakeMeUnique) {
+        return new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 
secondsMakeMeUnique);
+    }
+
+    protected static Polygon poly(final double[] arr) {
+        final LinearRing r1 = gf.createLinearRing(new 
PackedCoordinateSequence.Double(arr, 2));
+        final Polygon p1 = gf.createPolygon(r1, new LinearRing[] {});
+        return p1;
+    }
+
+    protected static Point point(final double x, final double y) {
+        return gf.createPoint(new Coordinate(x, y));
+    }
+
+    protected static LineString line(final double x1, final double y1, final 
double x2, final double y2) {
+        return new LineString(new PackedCoordinateSequence.Double(new double[] 
{ x1, y1, x2, y2 }, 2), gf);
+    }
+
+    protected static double[] bbox(final double x1, final double y1, final 
double x2, final double y2) {
+        return new double[] { x1, y1, x1, y2, x2, y2, x2, y1, x1, y1 };
+    }
+
+    protected void assertEqualMongo(final Object expected, final Object 
actual) throws ComparisonFailure {
+        try {
+            assertEquals(expected, actual);
+        } catch(final Throwable e) {
+            throw new ComparisonFailure(e.getMessage(), expected.toString(), 
actual.toString());
+        }
+    }
+
+    public List<FunctionCall> getFilters(final String query) throws Exception {
+        final FunctionCallCollector collector = new FunctionCallCollector();
+        new SPARQLParser().parseQuery(query, 
null).getTupleExpr().visit(collector);
+        return collector.getTupleExpr();
+    }
+
+    public List<StatementPattern> getSps(final String query) throws Exception {
+        final StatementPatternCollector collector = new 
StatementPatternCollector();
+        new SPARQLParser().parseQuery(query, 
null).getTupleExpr().visit(collector);
+        return collector.getStatementPatterns();
+    }
+
+    public QuerySegment<EventQueryNode> getQueryNode(final String query) 
throws Exception {
+        final List<QueryModelNode> exprs = getNodes(query);
+        final QuerySegment<EventQueryNode> node = 
Mockito.mock(QuerySegment.class);
+        //provider only cares about Ordered nodes.
+        Mockito.when(node.getOrderedNodes()).thenReturn(exprs);
+        return node;
+    }
+
+    private static List<QueryModelNode> getNodes(final String sparql) throws 
Exception {
+        final NodeCollector collector = new NodeCollector();
+        new SPARQLParser().parseQuery(sparql, 
null).getTupleExpr().visit(collector);
+        return collector.getTupleExpr();
+    }
+
+    private static class NodeCollector extends 
QueryModelVisitorBase<RuntimeException> {
+        private final List<QueryModelNode> stPatterns = new ArrayList<>();
+
+        public List<QueryModelNode> getTupleExpr() {
+            return stPatterns;
+        }
+
+        @Override
+        public void meet(final FunctionCall node) {
+            stPatterns.add(node);
+        }
+
+        @Override
+        public void meet(final StatementPattern node) {
+            stPatterns.add(node);
+        }
+    }
+
+    private static class FunctionCallCollector extends 
QueryModelVisitorBase<RuntimeException> {
+        private final List<FunctionCall> filters = new ArrayList<>();
+
+        public List<FunctionCall> getTupleExpr() {
+            return filters;
+        }
+
+        @Override
+        public void meet(final FunctionCall node) {
+            filters.add(node);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/646d21b4/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java
----------------------------------------------------------------------
diff --git 
a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java
 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java
new file mode 100644
index 0000000..66de3fa
--- /dev/null
+++ 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/MongoGeoTemporalIndexIT.java
@@ -0,0 +1,174 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.indexing.geotemporal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.GeoRyaSailFactory;
+import org.apache.rya.indexing.OptionalConfigUtils;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.geotemporal.mongo.MongoGeoTemporalIndexer;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.apache.rya.mongodb.MockMongoFactory;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.QueryLanguage;
+import org.openrdf.query.TupleQueryResult;
+import org.openrdf.query.impl.MapBindingSet;
+import org.openrdf.repository.sail.SailRepository;
+import org.openrdf.repository.sail.SailRepositoryConnection;
+import org.openrdf.sail.Sail;
+
+import com.mongodb.MongoClient;
+
+public class MongoGeoTemporalIndexIT {
+    private static final String URI_PROPERTY_AT_TIME = "Property:atTime";
+
+    private static final ValueFactory VF = ValueFactoryImpl.getInstance();
+    private MongoDBRdfConfiguration conf;
+    private SailRepositoryConnection conn;
+    private MongoClient mongoClient;
+
+    @Before
+    public void setUp() throws Exception{
+        mongoClient = MockMongoFactory.newFactory().newMongoClient();
+        conf = new MongoDBRdfConfiguration();
+        conf.set(MongoDBRdfConfiguration.MONGO_DB_NAME, "test");
+        conf.set(MongoDBRdfConfiguration.MONGO_COLLECTION_PREFIX, "rya");
+        conf.set(RdfCloudTripleStoreConfiguration.CONF_TBL_PREFIX, "rya");
+        conf.setBoolean(ConfigUtils.USE_MONGO, true);
+        conf.setBoolean(OptionalConfigUtils.USE_GEOTEMPORAL, true);
+        conf.setMongoClient(mongoClient);
+
+        final Sail sail = GeoRyaSailFactory.getInstance(conf);
+        conn = new SailRepository(sail).getConnection();
+        conn.begin();
+
+        addStatements();
+    }
+
+    @Test
+    public void ensureInEventStore_Test() throws Exception {
+        final MongoGeoTemporalIndexer indexer = new MongoGeoTemporalIndexer();
+        indexer.initIndexer(conf, mongoClient);
+
+        final EventStorage events = indexer.getEventStorage(conf);
+        final RyaURI subject = new RyaURI("urn:event1");
+        final Optional<Event> event = events.get(subject);
+        assertTrue(event.isPresent());
+    }
+
+    @Test
+    public void constantSubjQuery_Test() throws Exception {
+        final String query =
+                "PREFIX time: <http://www.w3.org/2006/time#> \n"
+              + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+              + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+              + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+              + "SELECT * "
+              + "WHERE { "
+                + "  <urn:event1> time:atTime ?time . "
+                + "  <urn:event1> geo:asWKT ?point . "
+                + "  FILTER(geof:sfWithin(?point, \"POLYGON((-3 -2, -3 2, 1 2, 
1 -2, -3 -2))\"^^geo:wktLiteral)) "
+                + "  FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
+              + "}";
+
+        final TupleQueryResult rez = 
conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate();
+        final Set<BindingSet> results = new HashSet<>();
+        while(rez.hasNext()) {
+            final BindingSet bs = rez.next();
+            results.add(bs);
+        }
+        final MapBindingSet expected = new MapBindingSet();
+        expected.addBinding("point", VF.createLiteral("POINT (0 0)"));
+        expected.addBinding("time", VF.createLiteral("2015-12-30T12:00:00Z"));
+
+        assertEquals(1, results.size());
+        assertEquals(expected, results.iterator().next());
+    }
+
+    @Test
+    public void variableSubjQuery_Test() throws Exception {
+        final String query =
+                "PREFIX time: <http://www.w3.org/2006/time#> \n"
+              + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+              + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+              + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+              + "SELECT * "
+              + "WHERE { "
+                + "  ?subj time:atTime ?time . "
+                + "  ?subj geo:asWKT ?point . "
+                + "  FILTER(geof:sfWithin(?point, \"POLYGON((-3 -2, -3 2, 1 2, 
1 -2, -3 -2))\"^^geo:wktLiteral)) "
+                + "  FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
+              + "}";
+
+        final TupleQueryResult rez = 
conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate();
+        final List<BindingSet> results = new ArrayList<>();
+        while(rez.hasNext()) {
+            final BindingSet bs = rez.next();
+            results.add(bs);
+        }
+        final MapBindingSet expected1 = new MapBindingSet();
+        expected1.addBinding("point", VF.createLiteral("POINT (0 0)"));
+        expected1.addBinding("time", VF.createLiteral("2015-12-30T12:00:00Z"));
+
+        final MapBindingSet expected2 = new MapBindingSet();
+        expected2.addBinding("point", VF.createLiteral("POINT (1 1)"));
+        expected2.addBinding("time", VF.createLiteral("2015-12-30T12:00:00Z"));
+
+        assertEquals(2, results.size());
+        assertEquals(expected1, results.get(0));
+        assertEquals(expected2, results.get(1));
+    }
+
+    private void addStatements() throws Exception {
+        URI subject = VF.createURI("urn:event1");
+        final URI predicate = VF.createURI(URI_PROPERTY_AT_TIME);
+        Value object = VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 
30, 12, 00, 0).toString());
+        conn.add(VF.createStatement(subject, predicate, object));
+
+        object = VF.createLiteral("Point(0 0)", 
GeoConstants.XMLSCHEMA_OGC_WKT);
+        conn.add(VF.createStatement(subject, GeoConstants.GEO_AS_WKT, object));
+
+        subject = VF.createURI("urn:event2");
+        object = VF.createLiteral(new TemporalInstantRfc3339(2015, 12, 30, 12, 
00, 0).toString());
+        conn.add(VF.createStatement(subject, predicate, object));
+
+        object = VF.createLiteral("Point(1 1)", 
GeoConstants.XMLSCHEMA_OGC_WKT);
+        conn.add(VF.createStatement(subject, GeoConstants.GEO_AS_WKT, object));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/646d21b4/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java
----------------------------------------------------------------------
diff --git 
a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java
 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java
new file mode 100644
index 0000000..d9e0294
--- /dev/null
+++ 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/model/EventQueryNodeTest.java
@@ -0,0 +1,368 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.indexing.geotemporal.model;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.IndexingExpr;
+import org.apache.rya.indexing.IndexingFunctionRegistry;
+import org.apache.rya.indexing.IndexingFunctionRegistry.FUNCTION_TYPE;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.geotemporal.GeoTemporalTestBase;
+import org.apache.rya.indexing.geotemporal.mongo.MongoEventStorage;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.apache.rya.mongodb.MockMongoFactory;
+import org.junit.Test;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.URIImpl;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.QueryEvaluationException;
+import org.openrdf.query.algebra.FunctionCall;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.ValueConstant;
+import org.openrdf.query.algebra.ValueExpr;
+import org.openrdf.query.algebra.Var;
+import org.openrdf.query.impl.MapBindingSet;
+
+import com.mongodb.MongoClient;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.PrecisionModel;
+
+import info.aduna.iteration.CloseableIteration;
+
+/**
+ * Unit tests the methods of {@link EventQueryNode}.
+ */
+public class EventQueryNodeTest extends GeoTemporalTestBase {
+    private static final GeometryFactory GF = new GeometryFactory(new 
PrecisionModel(), 4326);
+    private static final ValueFactory VF = ValueFactoryImpl.getInstance();
+
+    @Test(expected = IllegalStateException.class)
+    public void constructor_differentSubjects() throws Exception {
+        final Var geoSubj = new Var("point");
+        final Var geoPred = new 
Var("-const-http://www.opengis.net/ont/geosparql#asWKT";, 
ValueFactoryImpl.getInstance().createURI("http://www.opengis.net/ont/geosparql#asWKT";));
+        final Var geoObj = new Var("wkt");
+        final StatementPattern geoSP = new StatementPattern(geoSubj, geoPred, 
geoObj);
+
+        final Var timeSubj = new Var("time");
+        final Var timePred = new 
Var("-const-http://www.w3.org/2006/time#inXSDDateTime";, 
ValueFactoryImpl.getInstance().createURI("-const-http://www.w3.org/2006/time#inXSDDateTime";));
+        final Var timeObj = new Var("time");
+        final StatementPattern timeSP = new StatementPattern(timeSubj, 
timePred, timeObj);
+        // This will fail.
+        new EventQueryNode.EventQueryNodeBuilder()
+            .setStorage(mock(EventStorage.class))
+            .setGeoPattern(geoSP)
+            .setTemporalPattern(timeSP)
+            .setGeoFilters(new ArrayList<IndexingExpr>())
+            .setTemporalFilters(new ArrayList<IndexingExpr>())
+            .setUsedFilters(new ArrayList<>())
+            .build();
+    }
+
+    @Test(expected = IllegalStateException.class)
+    public void constructor_variablePredicate() throws Exception {
+        // A pattern that has a variable for its predicate.
+        final Var geoSubj = new Var("point");
+        final Var geoPred = new Var("geo");
+        final Var geoObj = new Var("wkt");
+        final StatementPattern geoSP = new StatementPattern(geoSubj, geoPred, 
geoObj);
+
+        final Var timeSubj = new Var("time");
+        final Var timePred = new 
Var("-const-http://www.w3.org/2006/time#inXSDDateTime";, 
ValueFactoryImpl.getInstance().createURI("-const-http://www.w3.org/2006/time#inXSDDateTime";));
+        final Var timeObj = new Var("time");
+        final StatementPattern timeSP = new StatementPattern(timeSubj, 
timePred, timeObj);
+        // This will fail.
+        new EventQueryNode.EventQueryNodeBuilder()
+        .setStorage(mock(EventStorage.class))
+        .setGeoPattern(geoSP)
+        .setTemporalPattern(timeSP)
+        .setGeoFilters(new ArrayList<IndexingExpr>())
+        .setTemporalFilters(new ArrayList<IndexingExpr>())
+        .setUsedFilters(new ArrayList<>())
+        .build();
+    }
+
+    @Test
+    public void evaluate_constantSubject() throws Exception {
+        final MongoClient client = 
MockMongoFactory.newFactory().newMongoClient();
+        final EventStorage storage = new MongoEventStorage(client, "testDB");
+        RyaURI subject = new RyaURI("urn:event-1111");
+        final Geometry geo = GF.createPoint(new Coordinate(1, 1));
+        final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 
12, 00, 0);
+        final Event event = Event.builder()
+            .setSubject(subject)
+            .setGeometry(geo)
+            .setTemporalInstant(temp)
+            .build();
+
+        subject = new RyaURI("urn:event-2222");
+        final Event otherEvent = Event.builder()
+            .setSubject(subject)
+            .setGeometry(geo)
+            .setTemporalInstant(temp)
+            .build();
+
+        storage.create(event);
+        storage.create(otherEvent);
+
+        final String query =
+                "PREFIX time: <http://www.w3.org/2006/time#> \n"
+              + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+              + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+              + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+              + "SELECT ?event ?time ?point ?wkt "
+              + "WHERE { "
+                + "  <urn:event-1111> time:atTime ?time . "
+                + "  <urn:event-1111> geo:asWKT ?wkt . "
+                + "  FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 
-2, -3 -2))\"^^geo:wktLiteral)) "
+                + "  FILTER(tempo:equals(?time, \"" + temp.toString() + "\")) "
+              + "}";
+
+        final EventQueryNode node = buildNode(storage, query);
+        final CloseableIteration<BindingSet, QueryEvaluationException> rez = 
node.evaluate(new MapBindingSet());
+        final MapBindingSet expected = new MapBindingSet();
+        expected.addBinding("wkt", VF.createLiteral("POINT (1 1)"));
+        expected.addBinding("time", VF.createLiteral(temp.toString()));
+        int count = 0;
+        assertTrue(rez.hasNext());
+        while(rez.hasNext()) {
+            assertEquals(expected, rez.next());
+            count++;
+        }
+        assertEquals(1, count);
+    }
+
+    @Test
+    public void evaluate_variableSubject() throws Exception {
+        final MongoClient client = 
MockMongoFactory.newFactory().newMongoClient();
+        final EventStorage storage = new MongoEventStorage(client, "testDB");
+        RyaURI subject = new RyaURI("urn:event-1111");
+        Geometry geo = GF.createPoint(new Coordinate(1, 1));
+        final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 
12, 00, 0);
+        final Event event = Event.builder()
+            .setSubject(subject)
+            .setGeometry(geo)
+            .setTemporalInstant(temp)
+            .build();
+
+        subject = new RyaURI("urn:event-2222");
+        geo = GF.createPoint(new Coordinate(-1, -1));
+        final Event otherEvent = Event.builder()
+            .setSubject(subject)
+            .setGeometry(geo)
+            .setTemporalInstant(temp)
+            .build();
+
+        storage.create(event);
+        storage.create(otherEvent);
+
+        final String query =
+                "PREFIX time: <http://www.w3.org/2006/time#> \n"
+              + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+              + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+              + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+              + "SELECT ?event ?time ?point ?wkt "
+              + "WHERE { "
+                + "  ?event time:atTime ?time . "
+                + "  ?event geo:asWKT ?wkt . "
+                + "  FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 
-2, -3 -2))\"^^geo:wktLiteral)) "
+                + "  FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
+              + "}";
+
+        final EventQueryNode node = buildNode(storage, query);
+        final CloseableIteration<BindingSet, QueryEvaluationException> rez = 
node.evaluate(new MapBindingSet());
+        final MapBindingSet expected1 = new MapBindingSet();
+        expected1.addBinding("wkt", VF.createLiteral("POINT (1 1)"));
+        expected1.addBinding("time", VF.createLiteral(new 
TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
+        final MapBindingSet expected2 = new MapBindingSet();
+        expected2.addBinding("wkt", VF.createLiteral("POINT (-1 -1)"));
+        expected2.addBinding("time", VF.createLiteral(new 
TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
+
+        final List<BindingSet> actual = new ArrayList<>();
+        while(rez.hasNext()) {
+            actual.add(rez.next());
+        }
+        assertEquals(expected1, actual.get(0));
+        assertEquals(expected2, actual.get(1));
+        assertEquals(2, actual.size());
+    }
+
+    @Test
+    public void evaluate_variableSubject_existingBindingset() throws Exception 
{
+        final MongoClient client = 
MockMongoFactory.newFactory().newMongoClient();
+        final EventStorage storage = new MongoEventStorage(client, "testDB");
+        RyaURI subject = new RyaURI("urn:event-1111");
+        Geometry geo = GF.createPoint(new Coordinate(1, 1));
+        final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 
12, 00, 0);
+        final Event event = Event.builder()
+            .setSubject(subject)
+            .setGeometry(geo)
+            .setTemporalInstant(temp)
+            .build();
+
+        subject = new RyaURI("urn:event-2222");
+        geo = GF.createPoint(new Coordinate(-1, -1));
+        final Event otherEvent = Event.builder()
+            .setSubject(subject)
+            .setGeometry(geo)
+            .setTemporalInstant(temp)
+            .build();
+
+        storage.create(event);
+        storage.create(otherEvent);
+
+        final String query =
+                "PREFIX time: <http://www.w3.org/2006/time#> \n"
+              + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+              + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+              + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+              + "SELECT ?event ?time ?point ?wkt "
+              + "WHERE { "
+                + "  ?event time:atTime ?time . "
+                + "  ?event geo:asWKT ?wkt . "
+                + "  FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 
-2, -3 -2))\"^^geo:wktLiteral)) "
+                + "  FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
+              + "}";
+
+        final EventQueryNode node = buildNode(storage, query);
+        final MapBindingSet existingBindings = new MapBindingSet();
+        existingBindings.addBinding("event", VF.createURI("urn:event-2222"));
+        final CloseableIteration<BindingSet, QueryEvaluationException> rez = 
node.evaluate(existingBindings);
+        final MapBindingSet expected = new MapBindingSet();
+        expected.addBinding("wkt", VF.createLiteral("POINT (-1 -1)"));
+        expected.addBinding("time", VF.createLiteral(new 
TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
+
+        final List<BindingSet> actual = new ArrayList<>();
+        while(rez.hasNext()) {
+            actual.add(rez.next());
+        }
+        assertEquals(1, actual.size());
+        assertEquals(expected, actual.get(0));
+    }
+
+    @Test
+    public void evaluate_variableSubject_existingBindingsetWrongFilters() 
throws Exception {
+        final MongoClient client = 
MockMongoFactory.newFactory().newMongoClient();
+        final EventStorage storage = new MongoEventStorage(client, "testDB");
+        RyaURI subject = new RyaURI("urn:event-1111");
+        Geometry geo = GF.createPoint(new Coordinate(1, 1));
+        final TemporalInstant temp = new TemporalInstantRfc3339(2015, 12, 30, 
12, 00, 0);
+        final Event event = Event.builder()
+            .setSubject(subject)
+            .setGeometry(geo)
+            .setTemporalInstant(temp)
+            .build();
+
+        subject = new RyaURI("urn:event-2222");
+        geo = GF.createPoint(new Coordinate(-10, -10));
+        final Event otherEvent = Event.builder()
+            .setSubject(subject)
+            .setGeometry(geo)
+            .setTemporalInstant(temp)
+            .build();
+
+        storage.create(event);
+        storage.create(otherEvent);
+
+        final String query =
+                "PREFIX time: <http://www.w3.org/2006/time#> \n"
+              + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+              + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+              + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+              + "SELECT ?event ?time ?point ?wkt "
+              + "WHERE { "
+                + "  ?event time:atTime ?time . "
+                + "  ?event geo:asWKT ?wkt . "
+                + "  FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 
-2, -3 -2))\"^^geo:wktLiteral)) "
+                + "  FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) "
+              + "}";
+
+        final EventQueryNode node = buildNode(storage, query);
+        final MapBindingSet existingBindings = new MapBindingSet();
+        existingBindings.addBinding("event", VF.createURI("urn:event-2222"));
+        final CloseableIteration<BindingSet, QueryEvaluationException> rez = 
node.evaluate(existingBindings);
+        final MapBindingSet expected = new MapBindingSet();
+        expected.addBinding("wkt", VF.createLiteral("POINT (-1 -1)"));
+        expected.addBinding("time", VF.createLiteral(new 
TemporalInstantRfc3339(2015, 12, 30, 12, 00, 0).toString()));
+
+        assertFalse(rez.hasNext());
+    }
+
+    private EventQueryNode buildNode(final EventStorage store, final String 
query) throws Exception {
+        final List<IndexingExpr> geoFilters = new ArrayList<>();
+        final List<IndexingExpr> temporalFilters = new ArrayList<>();
+        final List<StatementPattern> sps = getSps(query);
+        final List<FunctionCall> filters = getFilters(query);
+        for(final FunctionCall filter : filters) {
+            final URI filterURI = new URIImpl(filter.getURI());
+            final Var objVar = 
IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, 
filter.getArgs());
+            final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), 
extractArguments(objVar.getName(), filter));
+            if(IndexingFunctionRegistry.getFunctionType(filterURI) == 
FUNCTION_TYPE.GEO) {
+                geoFilters.add(expr);
+            } else {
+                temporalFilters.add(expr);
+            }
+        }
+
+        final StatementPattern geoPattern = sps.get(1);
+        final StatementPattern temporalPattern = sps.get(0);
+
+        return new EventQueryNode.EventQueryNodeBuilder()
+            .setStorage(store)
+            .setGeoPattern(geoPattern)
+            .setTemporalPattern(temporalPattern)
+            .setGeoFilters(geoFilters)
+            .setTemporalFilters(temporalFilters)
+            .setUsedFilters(filters)
+            .build();
+    }
+
+    private Value[] extractArguments(final String matchName, final 
FunctionCall call) {
+        final Value args[] = new Value[call.getArgs().size() - 1];
+        int argI = 0;
+        for (int i = 0; i != call.getArgs().size(); ++i) {
+            final ValueExpr arg = call.getArgs().get(i);
+            if (argI == i && arg instanceof Var && 
matchName.equals(((Var)arg).getName())) {
+                continue;
+            }
+            if (arg instanceof ValueConstant) {
+                args[argI] = ((ValueConstant)arg).getValue();
+            } else if (arg instanceof Var && ((Var)arg).hasValue()) {
+                args[argI] = ((Var)arg).getValue();
+            } else {
+                throw new IllegalArgumentException("Query error: Found " + arg 
+ ", expected a Literal, BNode or URI");
+            }
+            ++argI;
+        }
+        return args;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/646d21b4/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java
----------------------------------------------------------------------
diff --git 
a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java
 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java
new file mode 100644
index 0000000..3f2f9d5
--- /dev/null
+++ 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/EventDocumentConverterTest.java
@@ -0,0 +1,64 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.indexing.geotemporal.mongo;
+
+import static org.junit.Assert.assertEquals;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import 
org.apache.rya.indexing.entity.storage.mongo.DocumentConverter.DocumentConverterException;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.geotemporal.mongo.EventDocumentConverter;
+import org.bson.Document;
+import org.joda.time.DateTime;
+import org.junit.Test;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.PrecisionModel;
+
+/**
+ * Tests the methods of {@link EventDocumentConverter}.
+ */
+public class EventDocumentConverterTest {
+    private static final GeometryFactory GF = new GeometryFactory(new 
PrecisionModel(), 4326);
+
+    @Test
+    public void to_and_from_document() throws DocumentConverterException {
+        final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+        final TemporalInstant instant = new 
TemporalInstantRfc3339(DateTime.now());
+
+        // An Event that will be stored.
+        final Event event = Event.builder()
+                .setSubject(new RyaURI("urn:event/001"))
+                .setGeometry(geo)
+                .setTemporalInstant(instant)
+                .build();
+
+        final Document document = new 
EventDocumentConverter().toDocument(event);
+
+        // Convert the Document back into an Event.
+        final Event converted = new 
EventDocumentConverter().fromDocument(document);
+
+        // Ensure the original matches the round trip converted Event.
+        assertEquals(event, converted);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/646d21b4/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java
----------------------------------------------------------------------
diff --git 
a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java
 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java
new file mode 100644
index 0000000..edce1ec
--- /dev/null
+++ 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/GeoTemporalMongoDBStorageStrategyTest.java
@@ -0,0 +1,469 @@
+/*
+l * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.indexing.geotemporal.mongo;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.rya.api.resolver.RdfToRyaConversions;
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.IndexingExpr;
+import org.apache.rya.indexing.IndexingFunctionRegistry;
+import org.apache.rya.indexing.IndexingFunctionRegistry.FUNCTION_TYPE;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer;
+import org.apache.rya.indexing.geotemporal.GeoTemporalTestBase;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer.GeoPolicy;
+import org.apache.rya.indexing.geotemporal.GeoTemporalIndexer.TemporalPolicy;
+import 
org.apache.rya.indexing.geotemporal.mongo.GeoTemporalMongoDBStorageStrategy;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.model.Resource;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.ContextStatementImpl;
+import org.openrdf.model.impl.URIImpl;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.query.algebra.FunctionCall;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.ValueConstant;
+import org.openrdf.query.algebra.ValueExpr;
+import org.openrdf.query.algebra.Var;
+
+import com.mongodb.DBObject;
+import com.mongodb.util.JSON;
+
+/**
+ * Tests The {@link GeoTemporalMongoDBStorageStrategy}, which turns the filters
+ * into mongo {@link DBObject}s used to query.
+ *
+ * This tests also ensures all possible filter functions are accounted for in 
the test.
+ * @see TemporalPolicy Temporal Filter Functions
+ * @see GeoPolicy Geo Filter Functions
+ */
+public class GeoTemporalMongoDBStorageStrategyTest extends GeoTemporalTestBase 
{
+    private GeoTemporalMongoDBStorageStrategy adapter;
+    @Before
+    public void setup() {
+        adapter = new GeoTemporalMongoDBStorageStrategy();
+    }
+
+    @Test
+    public void emptyFilters_test() throws Exception {
+        final List<IndexingExpr> geoFilters = new ArrayList<>();
+        final List<IndexingExpr> temporalFilters = new ArrayList<>();
+        final DBObject actual = adapter.getFilterQuery(geoFilters, 
temporalFilters);
+        final String expectedString =
+                "{ }";
+        final DBObject expected = (DBObject) JSON.parse(expectedString);
+        assertEqualMongo(expected, actual);
+    }
+
+    @Test
+    public void equalsInstantAfterInterval_onlyOneGeo() throws Exception {
+        final String query =
+          "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+        + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+        + "SELECT ?point ?wkt "
+        + "WHERE { "
+          + "  ?point geo:asWKT ?wkt . "
+          + "  FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 -2, 
-3 -2))\"^^geo:wktLiteral)) "
+        + "}";
+        final List<IndexingExpr> geoFilters = new ArrayList<>();
+        final List<StatementPattern> sps = getSps(query);
+        final List<FunctionCall> filters = getFilters(query);
+        for(final FunctionCall filter : filters) {
+            //should only be one.
+            final Var objVar = 
IndexingFunctionRegistry.getResultVarFromFunctionCall(new 
URIImpl(filter.getURI()), filter.getArgs());
+            final IndexingExpr expr = new IndexingExpr(new 
URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), 
filter));
+            geoFilters.add(expr);
+        }
+        final List<IndexingExpr> temporalFilters = new ArrayList<>();
+        final DBObject actual = adapter.getFilterQuery(geoFilters, 
temporalFilters);
+        final String expectedString =
+            "{ "
+              + "\"location\" : {"
+                + "\"$geoWithin\" : {"
+                  + "\"$polygon\" : [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 , 
2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]"
+                + "}"
+              + "}"
+            + "}";
+        final DBObject expected = (DBObject) JSON.parse(expectedString);
+        assertEqualMongo(expected, actual);
+    }
+
+    @Test
+    public void equalsInstantAfterInterval_onlyGeos() throws Exception {
+
+        /*
+         * TODO: change filter functions for coverage
+         */
+
+
+        final String query =
+                "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+              + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+              + "SELECT ?point ?wkt "
+              + "WHERE { "
+                + "  ?point geo:asWKT ?wkt . "
+                + "  FILTER(geof:sfIntersects(?wkt, \"POLYGON((-3 -2, -3 2, 1 
2, 1 -2, -3 -2))\"^^geo:wktLiteral)) "
+                + "  FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 
-3, -4 -3))\"^^geo:wktLiteral)) "
+              + "}";
+              final List<IndexingExpr> geoFilters = new ArrayList<>();
+              final List<StatementPattern> sps = getSps(query);
+              final List<FunctionCall> filters = getFilters(query);
+              for(final FunctionCall filter : filters) {
+                  final Var objVar = 
IndexingFunctionRegistry.getResultVarFromFunctionCall(new 
URIImpl(filter.getURI()), filter.getArgs());
+                  final IndexingExpr expr = new IndexingExpr(new 
URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), 
filter));
+                  geoFilters.add(expr);
+              }
+              final List<IndexingExpr> temporalFilters = new ArrayList<>();
+              final DBObject actual = adapter.getFilterQuery(geoFilters, 
temporalFilters);
+              final String expectedString =
+                  "{ "
+                    + "\"$and\" : [{"
+                      + "\"location\" : [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 
2.0 , 3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]"
+                      + "}, {"
+                      + "\"location\" : {"
+                        + "\"$geoIntersects\" : {"
+                          + "\"$polygon\" : [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , 
[ 1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]"
+                        + "}"
+                      + "}"
+                    + "}]"
+                  + "}";
+              final DBObject expected = (DBObject) JSON.parse(expectedString);
+              assertEqualMongo(expected, actual);
+    }
+
+    @Test
+    public void equalsInstantAfterInterval_onlyOneTemporal() throws Exception {
+        final String query =
+          "PREFIX time: <http://www.w3.org/2006/time#> \n"
+        + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+        + "SELECT ?event ?time "
+        + "WHERE { "
+          + "  ?event time:atTime ?time . "
+          + "  FILTER(tempo:equals(?time, \"2015-12-30T12:00:00Z\")) . "
+        + "}";
+        final List<IndexingExpr> geoFilters = new ArrayList<>();
+        final List<IndexingExpr> temporalFilters = new ArrayList<>();
+        final List<StatementPattern> sps = getSps(query);
+        final List<FunctionCall> filters = getFilters(query);
+        for(final FunctionCall filter : filters) {
+            //should only be one.
+            final Var objVar = 
IndexingFunctionRegistry.getResultVarFromFunctionCall(new 
URIImpl(filter.getURI()), filter.getArgs());
+            final IndexingExpr expr = new IndexingExpr(new 
URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), 
filter));
+            temporalFilters.add(expr);
+        }
+        final DBObject actual = adapter.getFilterQuery(geoFilters, 
temporalFilters);
+        final String expectedString =
+        "{ "
+        + "\"instant\" : {"
+          + "\"$date\" : \"2015-12-30T12:00:00.000Z\""
+        + "}"
+      + "}";
+        final DBObject expected = (DBObject) JSON.parse(expectedString);
+        assertEqualMongo(expected, actual);
+    }
+
+    @Test
+    public void equalsInstantAfterInterval_onlyTemporal() throws Exception {
+        final String query =
+                "PREFIX time: <http://www.w3.org/2006/time#> \n"
+              + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+              + "SELECT ?event ?time "
+              + "WHERE { "
+                + "  ?event time:atTime ?time . "
+                + "  FILTER(tempo:before(?time, \"2015-12-30T12:00:00Z\")) . "
+                + "  FILTER(tempo:insideInterval(?time, 
\"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
+              + "}";
+              final List<IndexingExpr> geoFilters = new ArrayList<>();
+              final List<IndexingExpr> temporalFilters = new ArrayList<>();
+              final List<StatementPattern> sps = getSps(query);
+              final List<FunctionCall> filters = getFilters(query);
+              for(final FunctionCall filter : filters) {
+                  final Var objVar = 
IndexingFunctionRegistry.getResultVarFromFunctionCall(new 
URIImpl(filter.getURI()), filter.getArgs());
+                  final IndexingExpr expr = new IndexingExpr(new 
URIImpl(filter.getURI()), sps.get(0), extractArguments(objVar.getName(), 
filter));
+                  temporalFilters.add(expr);
+              }
+              final DBObject actual = adapter.getFilterQuery(geoFilters, 
temporalFilters);
+              final String expectedString =
+              "{ "
+              + "\"$and\" : [{"
+                + "\"instant\" : {"
+                  + "\"$gt\" : {"
+                    + "\"$date\" : \"1970-01-01T00:00:00.000Z\""
+                  + "},"
+                  + "\"$lt\" : {"
+                    + "\"$date\" : \"1970-01-01T00:00:01.000Z\""
+                  + "},"
+                + "}}, {"
+                + "\"instant\" : {"
+                  + "\"$lt\" : {"
+                    + "\"$date\" : \"2015-12-30T12:00:00.000Z\""
+                  + "}"
+                + "}"
+              + "}]"
+            + "}";
+              final DBObject expected = (DBObject) JSON.parse(expectedString);
+              assertEqualMongo(expected, actual);
+    }
+
+    @Test
+    public void equalsInstantAfterInterval_GeoTemporalOneEach() throws 
Exception {
+        final String query =
+                "PREFIX time: <http://www.w3.org/2006/time#> \n"
+              + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+              + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+              + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+              + "SELECT ?event ?time ?point ?wkt "
+              + "WHERE { "
+                + "  ?event time:atTime ?time . "
+                + "  ?point geo:asWKT ?wkt . "
+                + "  FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 
-2, -3 -2))\"^^geo:wktLiteral)) "
+                + "  FILTER(tempo:after(?time, \"2015-12-30T12:00:00Z\")) "
+              + "}";
+              final List<IndexingExpr> geoFilters = new ArrayList<>();
+              final List<IndexingExpr> temporalFilters = new ArrayList<>();
+              final List<StatementPattern> sps = getSps(query);
+              final List<FunctionCall> filters = getFilters(query);
+              for(final FunctionCall filter : filters) {
+                  final URI filterURI = new URIImpl(filter.getURI());
+                  final Var objVar = 
IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, 
filter.getArgs());
+                  final IndexingExpr expr = new IndexingExpr(filterURI, 
sps.get(0), extractArguments(objVar.getName(), filter));
+                  if(IndexingFunctionRegistry.getFunctionType(filterURI) == 
FUNCTION_TYPE.GEO) {
+                      geoFilters.add(expr);
+                  } else {
+                      temporalFilters.add(expr);
+                  }
+              }
+              final DBObject actual = adapter.getFilterQuery(geoFilters, 
temporalFilters);
+              final String expectedString =
+              "{ "
+              + "\"$and\" : [{"
+                + "\"location\" : {"
+                  + "\"$geoWithin\" : {"
+                    + "\"$polygon\" : [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 1.0 
, 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]"
+                  + "},"
+                + "}}, {"
+                + "\"instant\" : {"
+                  + "\"$gt\" : {"
+                    + "\"$date\" : \"2015-12-30T12:00:00.000Z\""
+                  + "}"
+                + "}"
+              + "}]"
+            + "}";
+              final DBObject expected = (DBObject) JSON.parse(expectedString);
+              assertEqualMongo(expected, actual);
+    }
+
+    @Test
+    public void equalsInstantAfterInterval_GeoTemporalTwoEach() throws 
Exception {
+        final String query =
+                "PREFIX time: <http://www.w3.org/2006/time#> \n"
+              + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+              + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+              + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+              + "SELECT ?event ?time ?point ?wkt "
+              + "WHERE { "
+                + "  ?event time:atTime ?time . "
+                + "  ?point geo:asWKT ?wkt . "
+                + "  FILTER(geof:sfWithin(?wkt, \"POLYGON((-3 -2, -3 2, 1 2, 1 
-2, -3 -2))\"^^geo:wktLiteral)) "
+                + "  FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 
-3, -4 -3))\"^^geo:wktLiteral)) "
+                + "  FILTER(tempo:hasEndInterval(?time, 
\"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
+                + "  FILTER(tempo:beforeInterval(?time, 
\"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
+              + "}";
+              final List<IndexingExpr> geoFilters = new ArrayList<>();
+              final List<IndexingExpr> temporalFilters = new ArrayList<>();
+              final List<StatementPattern> sps = getSps(query);
+              final List<FunctionCall> filters = getFilters(query);
+              for(final FunctionCall filter : filters) {
+                  final URI filterURI = new URIImpl(filter.getURI());
+                  final Var objVar = 
IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, 
filter.getArgs());
+                  final IndexingExpr expr = new IndexingExpr(filterURI, 
sps.get(0), extractArguments(objVar.getName(), filter));
+                  if(IndexingFunctionRegistry.getFunctionType(filterURI) == 
FUNCTION_TYPE.GEO) {
+                      geoFilters.add(expr);
+                  } else {
+                      temporalFilters.add(expr);
+                  }
+              }
+              final DBObject actual = adapter.getFilterQuery(geoFilters, 
temporalFilters);
+              final String expectedString =
+              "{ "
+              + "\"$and\" : [{"
+                + "\"$and\" : [{"
+                  + "\"location\" : [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 2.0 , 
3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]"
+                  + "}, {"
+                  + "\"location\" : {"
+                    + "\"$geoWithin\" : {"
+                      + "\"$polygon\" : [ [ -3.0 , -2.0] , [ -3.0 , 2.0] , [ 
1.0 , 2.0] , [ 1.0 , -2.0] , [ -3.0 , -2.0]]"
+                    + "}"
+                  + "}"
+                + "}]"
+              + "},{"
+                + "\"$and\" : [{"
+                  + "\"instant\" : {"
+                    + "\"$lt\" : {"
+                      + "\"$date\" : \"1970-01-01T00:00:00.000Z\""
+                    + "},"
+                    + "}"
+                  + "}, {"
+                    + "\"instant\" : {"
+                      + "\"$date\" : \"1970-01-01T00:00:01.000Z\""
+                    + "}"
+                  + "}]"
+                + "}"
+              + "]"
+            + "}";
+              final DBObject expected = (DBObject) JSON.parse(expectedString);
+              assertEqualMongo(expected, actual);
+    }
+
+    @Test
+    public void equalsInstantAfterInterval_GeoTemporalSingleGeoTwoTemporal() 
throws Exception {
+        final String query =
+                "PREFIX time: <http://www.w3.org/2006/time#> \n"
+              + "PREFIX tempo: <tag:rya-rdf.org,2015:temporal#> \n"
+              + "PREFIX geo: <http://www.opengis.net/ont/geosparql#>"
+              + "PREFIX geof: <http://www.opengis.net/def/function/geosparql/>"
+              + "SELECT ?event ?time ?point ?wkt "
+              + "WHERE { "
+                + "  ?event time:atTime ?time . "
+                + "  ?point geo:asWKT ?wkt . "
+                + "  FILTER(geof:sfEquals(?wkt, \"POLYGON((-4 -3, -4 3, 2 3, 2 
-3, -4 -3))\"^^geo:wktLiteral)) ."
+                + "  FILTER(tempo:hasBeginningInterval(?time, 
\"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\")) . "
+                + "  FILTER(tempo:afterInterval(?time, 
\"[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]\"))"
+              + "}";
+        final List<IndexingExpr> geoFilters = new ArrayList<>();
+        final List<IndexingExpr> temporalFilters = new ArrayList<>();
+        final List<StatementPattern> sps = getSps(query);
+        final List<FunctionCall> filters = getFilters(query);
+        for(final FunctionCall filter : filters) {
+            final URI filterURI = new URIImpl(filter.getURI());
+            final Var objVar = 
IndexingFunctionRegistry.getResultVarFromFunctionCall(filterURI, 
filter.getArgs());
+            final IndexingExpr expr = new IndexingExpr(filterURI, sps.get(0), 
extractArguments(objVar.getName(), filter));
+            if(IndexingFunctionRegistry.getFunctionType(filterURI) == 
FUNCTION_TYPE.GEO) {
+                geoFilters.add(expr);
+             } else {
+                temporalFilters.add(expr);
+             }
+        }
+        final DBObject actual = adapter.getFilterQuery(geoFilters, 
temporalFilters);
+        final String expectedString =
+              "{ "
+              + "\"$and\" : [{"
+                  + "\"location\" : [ [ -4.0 , -3.0] , [ -4.0 , 3.0] , [ 2.0 , 
3.0] , [ 2.0 , -3.0] , [ -4.0 , -3.0]]"
+                + "},{"
+                + "\"$and\" : [{"
+                  + "\"instant\" : {"
+                    + "\"$gt\" : {"
+                      + "\"$date\" : \"1970-01-01T00:00:01.000Z\""
+                    + "},"
+                    + "}"
+                  + "}, {"
+                    + "\"instant\" : {"
+                      + "\"$date\" : \"1970-01-01T00:00:00.000Z\""
+                    + "}"
+                  + "}]"
+                + "}"
+              + "]"
+            + "}";
+        final DBObject expected = (DBObject) JSON.parse(expectedString);
+        assertEqualMongo(expected, actual);
+    }
+
+    @Test
+    public void serializeTest() {
+        final ValueFactory vf = new ValueFactoryImpl();
+        final Resource subject = vf.createURI("foo:subj");
+        final Resource context = vf.createURI("foo:context");
+
+        //GEO
+        URI predicate = GeoConstants.GEO_AS_WKT;
+        Value object = vf.createLiteral("Point(-77.03524 38.889468)", 
GeoConstants.XMLSCHEMA_OGC_WKT);
+
+        Statement statement = new ContextStatementImpl(subject, predicate, 
object, context);
+        DBObject actual = 
adapter.serialize(RdfToRyaConversions.convertStatement(statement));
+        String expectedString =
+                "{"
+                  +"_id : -852305321, "
+                  +"location : [ [ -77.03524 , 38.889468]]"
+              + "}";
+        DBObject expected = (DBObject) JSON.parse(expectedString);
+        assertEqualMongo(expected, actual);
+
+        //TIME INSTANT
+        predicate = new URIImpl("Property:event:time");
+        object = vf.createLiteral("2015-12-30T12:00:00Z");
+        statement = new ContextStatementImpl(subject, predicate, object, 
context);
+        actual = 
adapter.serialize(RdfToRyaConversions.convertStatement(statement));
+        expectedString =
+                "{"
+                  +"_id : -852305321, "
+                  +"time: {"
+                    + "instant : {"
+                      +"\"$date\" : \"2015-12-30T12:00:00.000Z\""
+                    + "}"
+                + "}"
+              + "}";
+        expected = (DBObject) JSON.parse(expectedString);
+        assertEqualMongo(expected, actual);
+
+        //TIME INTERVAL
+        predicate = new URIImpl("Property:circa");
+        object = 
vf.createLiteral("[1969-12-31T19:00:00-05:00,1969-12-31T19:00:01-05:00]");
+        statement = new ContextStatementImpl(subject, predicate, object, 
context);
+        actual = 
adapter.serialize(RdfToRyaConversions.convertStatement(statement));
+        expectedString =
+                "{"
+                +"_id : -852305321, "
+                +"time: {"
+                  + "start : {"
+                    +"\"$date\" : \"1970-01-01T00:00:00.000Z\""
+                  + "},"
+                  + "end : {"
+                    +"\"$date\" : \"1970-01-01T00:00:01.000Z\""
+                  + "}"
+              + "}"
+            + "}";
+        expected = (DBObject) JSON.parse(expectedString);
+        assertEqualMongo(expected, actual);
+    }
+
+    private Value[] extractArguments(final String matchName, final 
FunctionCall call) {
+        final Value args[] = new Value[call.getArgs().size() - 1];
+        int argI = 0;
+        for (int i = 0; i != call.getArgs().size(); ++i) {
+            final ValueExpr arg = call.getArgs().get(i);
+            if (argI == i && arg instanceof Var && 
matchName.equals(((Var)arg).getName())) {
+                continue;
+            }
+            if (arg instanceof ValueConstant) {
+                args[argI] = ((ValueConstant)arg).getValue();
+            } else if (arg instanceof Var && ((Var)arg).hasValue()) {
+                args[argI] = ((Var)arg).getValue();
+            } else {
+                throw new IllegalArgumentException("Query error: Found " + arg 
+ ", expected a Literal, BNode or URI");
+            }
+            ++argI;
+        }
+        return args;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/646d21b4/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java
----------------------------------------------------------------------
diff --git 
a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java
 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java
new file mode 100644
index 0000000..5b07460
--- /dev/null
+++ 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoEventStorageTest.java
@@ -0,0 +1,197 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.indexing.geotemporal.mongo;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Optional;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import 
org.apache.rya.indexing.geotemporal.storage.EventStorage.EventAlreadyExistsException;
+import 
org.apache.rya.indexing.geotemporal.storage.EventStorage.EventStorageException;
+import org.joda.time.DateTime;
+import org.junit.Test;
+
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.PrecisionModel;
+
+/**
+ * Integration tests the methods of {@link MongoEventStorage}.
+ */
+public class MongoEventStorageTest extends MongoITBase {
+
+    private static final String RYA_INSTANCE_NAME = "testInstance";
+    private static final GeometryFactory GF = new GeometryFactory(new 
PrecisionModel(), 4326);
+
+    @Test
+    public void create_and_get() throws Exception {
+        final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+        final TemporalInstant instant = new 
TemporalInstantRfc3339(DateTime.now());
+
+        // An Event that will be stored.
+        final Event event = Event.builder()
+                .setSubject(new RyaURI("urn:event/001"))
+                .setGeometry(geo)
+                .setTemporalInstant(instant)
+                .build();
+
+        // Create it.
+        final EventStorage storage = new 
MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+        storage.create(event);
+
+        // Get it.
+        final Optional<Event> storedEvent = storage.get(new 
RyaURI("urn:event/001"));
+
+        // Verify the correct value was returned.
+        assertEquals(event, storedEvent.get());
+    }
+
+    @Test
+    public void can_not_create_with_same_subject() throws Exception {
+        final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+        final TemporalInstant instant = new 
TemporalInstantRfc3339(DateTime.now());
+
+        // An Event that will be stored.
+        final Event event = Event.builder()
+                .setSubject(new RyaURI("urn:event/001"))
+                .setGeometry(geo)
+                .setTemporalInstant(instant)
+                .build();
+
+        // Create it.
+        final EventStorage storage = new 
MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+        storage.create(event);
+
+        // Try to create it again. This will fail.
+        boolean failed = false;
+        try {
+            storage.create(event);
+        } catch(final EventAlreadyExistsException e) {
+            failed = true;
+        }
+        assertTrue(failed);
+    }
+
+    @Test
+    public void get_noneExisting() throws Exception {
+        // Get a Type that hasn't been created.
+        final EventStorage storage = new 
MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+        final Optional<Event> storedEvent = storage.get(new 
RyaURI("urn:event/000"));
+
+        // Verify nothing was returned.
+        assertFalse(storedEvent.isPresent());
+    }
+
+    @Test
+    public void delete() throws Exception {
+        final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+        final TemporalInstant instant = new 
TemporalInstantRfc3339(DateTime.now());
+
+        // An Event that will be stored.
+        final Event event = Event.builder()
+                .setSubject(new RyaURI("urn:event/002"))
+                .setGeometry(geo)
+                .setTemporalInstant(instant)
+                .build();
+
+        // Create it.
+        final EventStorage storage = new 
MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+        storage.create(event);
+
+        // Delete it.
+        final boolean deleted = storage.delete( new RyaURI("urn:event/002") );
+
+        // Verify a document was deleted.
+        assertTrue( deleted );
+    }
+
+    @Test
+    public void delete_nonExisting() throws Exception {
+        // Delete an Event that has not been created.
+        final EventStorage storage = new 
MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+        final boolean deleted = storage.delete( new RyaURI("urn:event/003") );
+
+        // Verify no document was deleted.
+        assertFalse( deleted );
+    }
+
+    @Test
+    public void update() throws Exception {
+        final EventStorage storage = new 
MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+        final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+        TemporalInstant instant = new TemporalInstantRfc3339(DateTime.now());
+
+        // An Event that will be stored.
+        final Event event = Event.builder()
+                .setSubject(new RyaURI("urn:event/004"))
+                .setGeometry(geo)
+                .setTemporalInstant(instant)
+                .build();
+
+        storage.create(event);
+
+        // Show Alice was stored.
+        Optional<Event> latest = storage.get(new RyaURI("urn:event/004"));
+        assertEquals(event, latest.get());
+
+        instant = new TemporalInstantRfc3339(DateTime.now());
+        // Change Alice's eye color to brown.
+        final Event updated = Event.builder(event)
+                .setTemporalInstant(instant)
+                .build();
+
+        storage.update(event, updated);
+
+        // Fetch the Alice object and ensure it has the new value.
+        latest = storage.get(new RyaURI("urn:event/004"));
+
+        assertEquals(updated, latest.get());
+    }
+
+    @Test(expected = EventStorageException.class)
+    public void update_differentSubjects() throws Exception {
+        final EventStorage storage = new 
MongoEventStorage(super.getMongoClient(), RYA_INSTANCE_NAME);
+        final Geometry geo = GF.createPoint(new Coordinate(10, 10));
+        final TemporalInstant instant = new 
TemporalInstantRfc3339(DateTime.now());
+
+        // Two objects that do not have the same Subjects.
+        final Event old = Event.builder()
+                .setSubject(new RyaURI("urn:event/001"))
+                .setGeometry(geo)
+                .setTemporalInstant(instant)
+                .build();
+
+        final Event updated = Event.builder()
+                .setSubject(new RyaURI("urn:event/002"))
+                .setGeometry(geo)
+                .setTemporalInstant(instant)
+                .build();
+
+        // The update will fail.
+        storage.update(old, updated);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/646d21b4/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java
----------------------------------------------------------------------
diff --git 
a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java
 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java
new file mode 100644
index 0000000..802e8c1
--- /dev/null
+++ 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoGeoTemporalIndexerIT.java
@@ -0,0 +1,126 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.indexing.geotemporal.mongo;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.Optional;
+
+import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.resolver.RdfToRyaConversions;
+import org.apache.rya.indexing.GeoConstants;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.geotemporal.model.Event;
+import org.apache.rya.indexing.geotemporal.mongo.MongoGeoTemporalIndexer;
+import org.apache.rya.indexing.geotemporal.storage.EventStorage;
+import org.apache.rya.mongodb.MockMongoFactory;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.junit.Before;
+import org.junit.Test;
+import org.openrdf.model.Resource;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.StatementImpl;
+import org.openrdf.model.impl.ValueFactoryImpl;
+
+import com.mongodb.MongoClient;
+import com.vividsolutions.jts.geom.Geometry;
+
+/**
+ * Integration tests the methods of {@link MongoGeoTemporalIndexer}.
+ */
+public class MongoGeoTemporalIndexerIT extends MongoITBase {
+
+    private MongoGeoTemporalIndexer indexer;
+
+    @Before
+    public void makeTestIndexer() throws Exception {
+        final MongoClient client = 
MockMongoFactory.newFactory().newMongoClient();
+        indexer = new MongoGeoTemporalIndexer();
+        conf.setMongoDBName("GEO_TEMPORAL_INDEXER_TEST");
+        conf.set(MongoDBRdfConfiguration.MONGO_DB_NAME, 
"GEO_TEMPORAL_INDEXER_TEST");
+        conf.setMongoClient(client);
+        conf.set(RdfCloudTripleStoreConfiguration.CONF_TBL_PREFIX, "rya_");
+        indexer.setConf(conf);
+        indexer.init();
+    }
+
+    @Test
+    public void ensureEvent() throws Exception {
+        final RyaStatement geoStmnt = statement(point(0, 0));
+        final RyaStatement timeStmnt = statement(makeInstant(0));
+
+        final EventStorage store = indexer.getEventStorage(conf);
+
+        indexer.storeStatement(geoStmnt);
+        Optional<Event> evnt = store.get(geoStmnt.getSubject());
+        assertTrue(evnt.isPresent());
+        Event expected = Event.builder()
+            .setSubject(geoStmnt.getSubject())
+            .setGeometry(point(0, 0))
+            .build();
+        assertEquals(expected, evnt.get());
+
+        indexer.storeStatement(timeStmnt);
+        evnt = store.get(timeStmnt.getSubject());
+        assertTrue(evnt.isPresent());
+        expected = Event.builder()
+            .setSubject(geoStmnt.getSubject())
+            .setGeometry(point(0, 0))
+            .setTemporalInstant(makeInstant(0))
+            .build();
+        assertEquals(expected, evnt.get());
+
+        indexer.deleteStatement(geoStmnt);
+        evnt = store.get(timeStmnt.getSubject());
+        assertTrue(evnt.isPresent());
+        expected = Event.builder()
+            .setSubject(timeStmnt.getSubject())
+            .setTemporalInstant(makeInstant(0))
+            .build();
+        assertEquals(expected, evnt.get());
+
+        indexer.deleteStatement(timeStmnt);
+        evnt = store.get(timeStmnt.getSubject());
+        assertTrue(evnt.isPresent());
+        expected = Event.builder()
+            .setSubject(timeStmnt.getSubject())
+            .build();
+        assertEquals(expected, evnt.get());
+    }
+
+    private static RyaStatement statement(final Geometry geo) {
+        final ValueFactory vf = new ValueFactoryImpl();
+        final Resource subject = vf.createURI("uri:test");
+        final URI predicate = GeoConstants.GEO_AS_WKT;
+        final Value object = vf.createLiteral(geo.toString(), 
GeoConstants.XMLSCHEMA_OGC_WKT);
+        return RdfToRyaConversions.convertStatement(new StatementImpl(subject, 
predicate, object));
+    }
+
+    private static RyaStatement statement(final TemporalInstant instant) {
+        final ValueFactory vf = new ValueFactoryImpl();
+        final Resource subject = vf.createURI("uri:test");
+        final URI predicate = vf.createURI("Property:atTime");
+        final Value object = vf.createLiteral(instant.toString());
+        return RdfToRyaConversions.convertStatement(new StatementImpl(subject, 
predicate, object));
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/646d21b4/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java
----------------------------------------------------------------------
diff --git 
a/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java
 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java
new file mode 100644
index 0000000..bd7b5db
--- /dev/null
+++ 
b/extras/rya.geoindexing/src/test/java/org/apache/rya/indexing/geotemporal/mongo/MongoITBase.java
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.indexing.geotemporal.mongo;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.rya.indexing.geotemporal.GeoTemporalTestBase;
+import org.apache.rya.mongodb.MockMongoFactory;
+import org.apache.rya.mongodb.MongoConnectorFactory;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+
+import com.mongodb.MongoClient;
+
+/**
+ * A base class that may be used when implementing Mongo DB integration tests 
that
+ * use the JUnit framework.
+ */
+public class MongoITBase extends GeoTemporalTestBase {
+    protected final MongoDBRdfConfiguration conf = new 
MongoDBRdfConfiguration( new Configuration() );
+
+    private MongoClient mongoClient = null;
+    private Set<String> originalDbNames = null;
+
+    @Before
+    public void setupTest() throws Exception {
+        conf.setMongoDBName("testDB");
+        conf.setMongoInstance("testDB");
+        conf.setMongoPort("27017");
+
+        mongoClient = MockMongoFactory.newFactory().newMongoClient();
+        conf.setMongoClient(mongoClient);;
+        // Store the names of the DBs that are present before running the test.
+        originalDbNames = new HashSet<>();
+        for(final String name : mongoClient.listDatabaseNames()) {
+            originalDbNames.add(name);
+        }
+    }
+
+    @After
+    public void cleanupTest() {
+        // Remove any DBs that were created by the test.
+        for(final String dbName : mongoClient.listDatabaseNames()) {
+            if(!originalDbNames.contains(dbName)) {
+                mongoClient.dropDatabase(dbName);
+            }
+        }
+    }
+
+    @AfterClass
+    public static void shutdown() {
+        MongoConnectorFactory.closeMongoClient();
+    }
+
+    /**
+     * @return A {@link MongoClient} that is connected to the embedded 
instance of Mongo DB.
+     */
+    public MongoClient getMongoClient() {
+        return mongoClient;
+    }
+}
\ No newline at end of file


Reply via email to