You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@rya.apache.org by pu...@apache.org on 2017/03/27 18:09:33 UTC

[1/4] incubator-rya git commit: RYA-144: Mongo Entity Centric Indexer; Closes #124, #135

Repository: incubator-rya
Updated Branches:
  refs/heads/master 4ac4e8674 -> 529f2d595


http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexIT.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexIT.java b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexIT.java
new file mode 100644
index 0000000..4ddb2a5
--- /dev/null
+++ b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexIT.java
@@ -0,0 +1,326 @@
+/**
+ * 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.mongo;
+
+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.accumulo.ConfigUtils;
+import org.apache.rya.indexing.entity.model.Entity;
+import org.apache.rya.indexing.entity.model.Type;
+import org.apache.rya.indexing.entity.storage.EntityStorage;
+import org.apache.rya.indexing.entity.storage.TypeStorage;
+import org.apache.rya.indexing.entity.update.mongo.MongoEntityIndexer;
+import org.apache.rya.mongodb.MockMongoFactory;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.apache.rya.sail.config.RyaSailFactory;
+import org.bson.Document;
+import org.junit.Before;
+import org.junit.Test;
+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.ValueFactoryImpl;
+import org.openrdf.model.vocabulary.RDF;
+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.google.common.collect.ImmutableSet;
+import com.mongodb.Block;
+import com.mongodb.MongoClient;
+import com.mongodb.client.MongoDatabase;
+
+import de.flapdoodle.embed.mongo.distribution.Version;
+
+public class MongoEntityIndexIT {
+    private static final ValueFactory VF = ValueFactoryImpl.getInstance();
+    private MongoDBRdfConfiguration conf;
+    private SailRepositoryConnection conn;
+    private MongoEntityIndexer indexer;
+    private MongoClient mongoClient;
+
+    @Before
+    public void setUp() throws Exception{
+        mongoClient = MockMongoFactory.with(Version.Main.PRODUCTION).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.setMongoClient(mongoClient);
+        conf.setBoolean(ConfigUtils.USE_ENTITY, true);
+        final int port = mongoClient.getServerAddressList().get(0).getPort();
+        conf.set(MongoDBRdfConfiguration.MONGO_INSTANCE_PORT, Integer.toString(port));
+
+        final Sail sail = RyaSailFactory.getInstance(conf);
+        conn = new SailRepository(sail).getConnection();
+        conn.begin();
+
+        indexer = new MongoEntityIndexer();
+        indexer.setConf(conf);
+        indexer.init();
+    }
+
+    @Test
+    public void ensureInEntityStore_Test() throws Exception {
+        setupTypes();
+        addStatements();
+
+        final MongoDatabase db = mongoClient.getDatabase("test");
+        db.listCollections().forEach((Block<Document>)doc -> {
+            System.out.println(doc);
+        });
+
+
+        final EntityStorage entities = indexer.getEntityStorage(conf);
+        final RyaURI subject = new RyaURI("urn:alice");
+        final Optional<Entity> alice = entities.get(subject);
+        assertTrue(alice.isPresent());
+    }
+
+    @Test
+    public void sparqlQuery_Test() throws Exception {
+        setupTypes();
+        addStatements();
+        //conn.commit();
+
+        final String query = "SELECT * WHERE { " +
+                "<urn:strawberry> <" + RDF.TYPE + "> <urn:icecream> ."+
+                "<urn:strawberry> <urn:brand> ?brand . " +
+                "<urn:strawberry> <urn:flavor> ?flavor . " +
+            "}";
+
+        final TupleQueryResult rez = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate();
+        final Set<BindingSet> results = new HashSet<>();
+        while(rez.hasNext()) {
+            final BindingSet bs = rez.next();
+            System.out.println(bs);
+            results.add(bs);
+        }
+        final MapBindingSet expected = new MapBindingSet();
+        expected.addBinding("flavor", ValueFactoryImpl.getInstance().createLiteral("Strawberry"));
+        expected.addBinding("brand", ValueFactoryImpl.getInstance().createLiteral("Awesome Icecream"));
+
+        assertEquals(1, results.size());
+        assertEquals(expected, results.iterator().next());
+    }
+
+    @Test
+    public void partialQuery_Test() throws Exception {
+        setupTypes();
+        addStatements();
+        conn.commit();
+
+        final String query = "SELECT * WHERE { " +
+                "<urn:george> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:george> <urn:name> ?name . " +
+                "<urn:george> <urn:eye> ?eye . " +
+            "}";
+
+        final TupleQueryResult rez = conn.prepareTupleQuery(QueryLanguage.SPARQL, query).evaluate();
+        final Set<BindingSet> results = new HashSet<>();
+        while(rez.hasNext()) {
+            final BindingSet bs = rez.next();
+            System.out.println(bs);
+            results.add(bs);
+        }
+        final ValueFactory vf = ValueFactoryImpl.getInstance();
+        final MapBindingSet expected = new MapBindingSet();
+        //expected.addBinding("name", vf.createURI("http://www.w3.org/2001/SMLSchema#string", "George"));
+        expected.addBinding("name", vf.createLiteral("George"));
+        expected.addBinding("eye", vf.createLiteral("blue"));
+
+        assertEquals(1, results.size());
+        assertEquals(expected, results.iterator().next());
+    }
+
+    private void setupTypes() throws Exception {
+        final TypeStorage typeStore = indexer.getTypeStorage(conf);
+        // Add some Types to the storage.
+        final Type cat = new Type(new RyaURI("urn:cat"),
+                ImmutableSet.<RyaURI>builder()
+                    .add(new RyaURI("urn:numLegs"))
+                    .add(new RyaURI("urn:eye"))
+                    .add(new RyaURI("urn:species"))
+                    .build());
+
+        final Type dog = new Type(new RyaURI("urn:dog"),
+                ImmutableSet.<RyaURI>builder()
+                    .add(new RyaURI("urn:numLegs"))
+                    .add(new RyaURI("urn:eye"))
+                    .add(new RyaURI("urn:species"))
+                    .build());
+
+        final Type icecream = new Type(new RyaURI("urn:icecream"),
+                ImmutableSet.<RyaURI>builder()
+                    .add(new RyaURI("urn:brand"))
+                    .add(new RyaURI("urn:flavor"))
+                    .add(new RyaURI("urn:cost"))
+                    .build());
+
+        final Type person = new Type(new RyaURI("urn:person"),
+                ImmutableSet.<RyaURI>builder()
+                    .add(new RyaURI("urn:name"))
+                    .add(new RyaURI("urn:age"))
+                    .add(new RyaURI("urn:eye"))
+                    .build());
+
+        typeStore.create(cat);
+        typeStore.create(dog);
+        typeStore.create(icecream);
+        typeStore.create(person);
+    }
+
+    private void addStatements() throws Exception {
+        final List<Statement> stmnts = new ArrayList<>();
+
+        //alice
+        URI subject = VF.createURI("urn:alice");
+        URI predicate = VF.createURI("urn:name");
+        Value object = VF.createLiteral("Alice");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:eye");
+        object = VF.createLiteral("blue");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:age");
+        object = VF.createLiteral(30);
+        conn.add(VF.createStatement(subject, predicate, object));
+        conn.add(VF.createStatement(subject, RDF.TYPE, VF.createURI("urn:person")));
+
+        //bob
+        subject = VF.createURI("urn:bob");
+        predicate = VF.createURI("urn:name");
+        object = VF.createLiteral("Bob");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:eye");
+        object = VF.createLiteral("brown");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:age");
+        object = VF.createLiteral(57);
+        conn.add(VF.createStatement(subject, predicate, object));
+        conn.add(VF.createStatement(subject, RDF.TYPE, VF.createURI("urn:person")));
+
+        //charlie
+        subject = VF.createURI("urn:charlie");
+        predicate = VF.createURI("urn:name");
+        object = VF.createLiteral("Charlie");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:eye");
+        object = VF.createLiteral("hazel");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:age");
+        object = VF.createLiteral(25);
+        conn.add(VF.createStatement(subject, predicate, object));
+        conn.add(VF.createStatement(subject, RDF.TYPE, VF.createURI("urn:person")));
+
+        //david
+        subject = VF.createURI("urn:david");
+        predicate = VF.createURI("urn:name");
+        object = VF.createLiteral("David");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:eye");
+        object = VF.createLiteral("brown");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:age");
+        object = VF.createLiteral(30);
+        conn.add(VF.createStatement(subject, predicate, object));
+        conn.add(VF.createStatement(subject, RDF.TYPE, VF.createURI("urn:person")));
+
+        //eve
+        subject = VF.createURI("urn:eve");
+        predicate = VF.createURI("urn:name");
+        object = VF.createLiteral("Bob");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:age");
+        object = VF.createLiteral(25);
+        conn.add(VF.createStatement(subject, predicate, object));
+        conn.add(VF.createStatement(subject, RDF.TYPE, VF.createURI("urn:person")));
+
+        //frank
+        subject = VF.createURI("urn:frank");
+        predicate = VF.createURI("urn:name");
+        object = VF.createLiteral("Frank");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:eye");
+        object = VF.createLiteral("Hazel");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:age");
+        object = VF.createLiteral(57);
+        conn.add(VF.createStatement(subject, predicate, object));
+        conn.add(VF.createStatement(subject, RDF.TYPE, VF.createURI("urn:person")));
+
+        //george
+        subject = VF.createURI("urn:george");
+        predicate = VF.createURI("urn:name");
+        object = VF.createLiteral("George");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:eye");
+        object = VF.createLiteral("blue");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:age");
+        object = VF.createLiteral(30);
+        conn.add(VF.createStatement(subject, predicate, object));
+        conn.add(VF.createStatement(subject, RDF.TYPE, VF.createURI("urn:person")));
+
+        // Some Icecream typed objects.
+        //chocolate
+        subject = VF.createURI("urn:chocolate");
+        predicate = VF.createURI("urn:brand");
+        object = VF.createLiteral("Awesome Icecream");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:flavor");
+        object = VF.createLiteral("Chocolate");
+        conn.add(VF.createStatement(subject, predicate, object));
+        conn.add(VF.createStatement(subject, RDF.TYPE, VF.createURI("urn:icecream")));
+
+        //vanilla
+        subject = VF.createURI("urn:vanilla");
+        predicate = VF.createURI("urn:brand");
+        object = VF.createLiteral("Awesome Icecream");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:flavor");
+        object = VF.createLiteral("Vanilla");
+        conn.add(VF.createStatement(subject, predicate, object));
+        conn.add(VF.createStatement(subject, RDF.TYPE, VF.createURI("urn:icecream")));
+
+        //strawberry
+        subject = VF.createURI("urn:strawberry");
+        predicate = VF.createURI("urn:brand");
+        object = VF.createLiteral("Awesome Icecream");
+        conn.add(VF.createStatement(subject, predicate, object));
+        predicate = VF.createURI("urn:flavor");
+        object = VF.createLiteral("Strawberry");
+        conn.add(VF.createStatement(subject, predicate, object));
+        conn.add(VF.createStatement(subject, RDF.TYPE, VF.createURI("urn:icecream")));
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexTest.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexTest.java b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexTest.java
new file mode 100644
index 0000000..f4aeaa1
--- /dev/null
+++ b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexTest.java
@@ -0,0 +1,260 @@
+/**
+ * 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.mongo;
+
+import java.util.List;
+
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.entity.EntityIndexOptimizer;
+import org.apache.rya.indexing.entity.model.Entity;
+import org.apache.rya.indexing.entity.model.Property;
+import org.apache.rya.indexing.entity.model.Type;
+import org.apache.rya.indexing.entity.query.EntityQueryNode;
+import org.apache.rya.indexing.entity.storage.EntityStorage;
+import org.apache.rya.indexing.entity.storage.TypeStorage;
+import org.apache.rya.mongodb.MockMongoFactory;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openrdf.model.vocabulary.RDF;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
+import org.openrdf.query.algebra.helpers.StatementPatternCollector;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+import com.google.common.collect.ImmutableSet;
+import com.mongodb.MongoClient;
+
+public class MongoEntityIndexTest {
+    private static final Type PERSON_TYPE =
+            new Type(new RyaURI("urn:person"),
+                ImmutableSet.<RyaURI>builder()
+                    .add(new RyaURI("urn:name"))
+                    .add(new RyaURI("urn:age"))
+                    .add(new RyaURI("urn:eye"))
+                    .build());
+    private static final RyaURI RYA_PERSON_TYPE = new RyaURI("urn:person");
+
+    static MongoDBRdfConfiguration conf;
+    private static EntityIndexOptimizer optimizer;
+    private static EntityStorage entityStorage;
+
+    @BeforeClass
+    public static void beforeClass() throws Exception {
+        conf = new MongoDBRdfConfiguration();
+        conf.set(ConfigUtils.USE_MONGO, "true");
+        conf.set(MongoDBRdfConfiguration.MONGO_DB_NAME, "test");
+        conf.set(MongoDBRdfConfiguration.MONGO_COLLECTION_PREFIX, "rya_");
+        conf.setTablePrefix("another_");
+
+        final MongoClient client = MockMongoFactory.newFactory().newMongoClient();
+        conf.setMongoClient(client);
+
+        optimizer = new EntityIndexOptimizer();
+        optimizer.setConf(conf);
+
+        final TypeStorage typeStorage = optimizer.getTypeStorage();
+        typeStorage.create(PERSON_TYPE);
+
+        final Entity entity = Entity.builder()
+                .setSubject(new RyaURI("urn:SSN:111-11-1111"))
+                .setExplicitType(RYA_PERSON_TYPE)
+                .setProperty(RYA_PERSON_TYPE, new Property(new RyaURI("urn:age"), new RyaType("25")))
+                .setProperty(RYA_PERSON_TYPE, new Property(new RyaURI("urn:eye"), new RyaType("blue")))
+                .setProperty(RYA_PERSON_TYPE, new Property(new RyaURI("urn:name"), new RyaType("bob")))
+                .build();
+        entityStorage = optimizer.getEntityStorage();
+        entityStorage.create(entity);
+    }
+
+    @Test()
+    public void queryIsFullEntity() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(query), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryIsPartEntity() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(query), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryIsPartEntityandExtra() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:222-22-2222> <urn:age> ?age . " +
+                "<urn:SSN:222-22-2222> <urn:eye> ?eye . " +
+                "<urn:SSN:222-22-2222> <urn:name> ?name . " +
+            "}";
+
+        final String expectedQuery = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(expectedQuery), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryIsFullEntityWithExtra() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+                "<urn:SSN:222-22-2222> <urn:age> ?age . " +
+                "<urn:SSN:222-22-2222> <urn:eye> ?eye . " +
+                "<urn:SSN:222-22-2222> <urn:name> ?name . " +
+            "}";
+
+        final String expectedQuery = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(expectedQuery), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryIsFullEntityWithOptional() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+                "  OPTIONAL{" +
+                "    <urn:SSN:222-22-2222> <urn:age> ?age . " +
+                "    <urn:SSN:222-22-2222> <urn:eye> ?eye . " +
+                "    <urn:SSN:222-22-2222> <urn:name> ?name . " +
+                " } . " +
+            "}";
+
+        final String expectedQuery = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(expectedQuery), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryIsSplitEntityWithOptional() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "  OPTIONAL{" +
+                "    <urn:SSN:111-11-1111> <urn:name> ?name . " +
+                " } . " +
+            "}";
+
+        final String expectedQuery = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(expectedQuery), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryEntityInOptional() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "  OPTIONAL{" +
+                "    <urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "    <urn:SSN:111-11-1111> <urn:name> ?name . " +
+                " } . " +
+            "}";
+
+        final String expectedQuery = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, getSPs(expectedQuery), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    private static List<StatementPattern> getSPs(final String sparql) throws MalformedQueryException {
+        final StatementPatternCollector spCollector = new StatementPatternCollector();
+        new SPARQLParser().parseQuery(sparql, null).getTupleExpr().visit(spCollector);
+        return spCollector.getStatementPatterns();
+    }
+
+    private void assertOptimizer(final String query, final EntityQueryNode expected) throws Exception {
+        final SPARQLParser parser = new SPARQLParser();
+        final TupleExpr expr = parser.parseQuery(query, null).getTupleExpr();
+
+        optimizer.optimize(expr, null, null);
+        expr.visit(new EntityFetchingAsserterVisitor(expected));
+    }
+
+    private class EntityFetchingAsserterVisitor extends QueryModelVisitorBase<Exception> {
+        private final EntityQueryNode expected;
+        public EntityFetchingAsserterVisitor(final EntityQueryNode expected) {
+            this.expected = expected;
+        }
+        @Override
+        protected void meetNode(final QueryModelNode node) throws Exception {
+            if(node instanceof EntityQueryNode) {
+                Assert.assertEquals(expected, node);
+            } else {
+                super.meetNode(node);
+            }
+        }
+    }
+}
+


[3/4] incubator-rya git commit: RYA-144: Mongo Entity Centric Indexer; Closes #124, #135

Posted by pu...@apache.org.
RYA-144: Mongo Entity Centric Indexer; Closes #124, #135

Added optimizer for indexer as well as tests.
The mvm package structure still existed here, so that
was cleaned up.
Added tests for the new optmizer.


Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/c4d4bfe7
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/c4d4bfe7
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/c4d4bfe7

Branch: refs/heads/master
Commit: c4d4bfe741e57559cea83a0c4acda7bff5e6d59b
Parents: 07643eb
Author: isper3at <sm...@gmail.com>
Authored: Wed Nov 2 11:36:51 2016 -0400
Committer: pujav65 <pu...@gmail.com>
Committed: Mon Mar 27 13:45:12 2017 -0400

----------------------------------------------------------------------
 .../rya/mongodb/MongoConnectorFactory.java      |  18 +-
 .../rya/indexing/accumulo/ConfigUtils.java      |  37 ++-
 .../entity/EntityExternalSetMatcherFactory.java |  44 +++
 .../indexing/entity/EntityIndexOptimizer.java   | 125 +++++++
 .../indexing/entity/EntityIndexSetProvider.java | 157 +++++++++
 .../entity/EntityToSegmentConverter.java        |  51 +++
 .../rya/indexing/entity/model/Entity.java       |  33 +-
 .../rya/indexing/entity/model/Property.java     |  11 +-
 .../apache/rya/indexing/entity/model/Type.java  |  10 +-
 .../rya/indexing/entity/model/TypedEntity.java  |  29 +-
 .../indexing/entity/query/EntityQueryNode.java  | 200 ++++++++++--
 .../entity/storage/CloseableIterator.java       |  29 --
 .../indexing/entity/storage/EntityStorage.java  |  25 +-
 .../indexing/entity/storage/TypeStorage.java    |  17 +-
 .../entity/storage/mongo/ConvertingCursor.java  |   7 +-
 .../entity/storage/mongo/DocumentConverter.java |  11 +-
 .../storage/mongo/EntityDocumentConverter.java  |  14 +-
 .../storage/mongo/MongoEntityStorage.java       |  29 +-
 .../entity/storage/mongo/MongoTypeStorage.java  |  24 +-
 .../storage/mongo/RyaTypeDocumentConverter.java |  12 +-
 .../storage/mongo/TypeDocumentConverter.java    |   8 +-
 .../entity/update/BaseEntityIndexer.java        |  50 +--
 .../indexing/entity/update/EntityIndexer.java   |  22 +-
 .../indexing/entity/update/EntityUpdater.java   |  12 +-
 .../entity/update/mongo/MongoEntityIndexer.java |  48 ++-
 .../matching/AbstractExternalSetMatcher.java    |  32 +-
 .../AbstractExternalSetMatcherFactory.java      |  24 +-
 .../indexing/external/matching/BasicRater.java  |  18 +
 .../external/matching/ExternalSetConverter.java |  22 +-
 .../external/matching/ExternalSetProvider.java  |  26 +-
 .../external/matching/MatcherUtilities.java     |  20 +-
 .../external/matching/QueryNodeListRater.java   |  24 +-
 .../external/matching/QuerySegment.java         |   6 +-
 .../external/matching/QuerySegmentFactory.java  |  28 +-
 .../pcj/matching/AccumuloIndexSetProvider.java  |  66 ++--
 .../matching/PCJExternalSetMatcherFactory.java  |  22 +-
 .../pcj/matching/PCJToSegmentConverter.java     |  34 +-
 .../apache/rya/sail/config/RyaSailFactory.java  |  18 +-
 .../entity/query/EntityQueryNodeTest.java       | 144 ++++++--
 .../mongo/EntityDocumentConverterTest.java      |   6 +-
 .../storage/mongo/MongoEntityStorageIT.java     |  11 +-
 .../entity/storage/mongo/MongoITBase.java       |  19 +-
 .../storage/mongo/MongoTypeStorageIT.java       |   9 +-
 .../mongo/RyaTypeDocumentConverterTest.java     |   6 +-
 .../mongo/TypeDocumentConverterTest.java        |   4 +-
 .../update/mongo/MongoEntityIndexerIT.java      |  45 +--
 .../rya/indexing/mongo/MongoEntityIndexIT.java  | 326 +++++++++++++++++++
 .../indexing/mongo/MongoEntityIndexTest.java    | 260 +++++++++++++++
 48 files changed, 1786 insertions(+), 407 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/dao/mongodb.rya/src/main/java/org/apache/rya/mongodb/MongoConnectorFactory.java
----------------------------------------------------------------------
diff --git a/dao/mongodb.rya/src/main/java/org/apache/rya/mongodb/MongoConnectorFactory.java b/dao/mongodb.rya/src/main/java/org/apache/rya/mongodb/MongoConnectorFactory.java
index df62a87..50c3a52 100644
--- a/dao/mongodb.rya/src/main/java/org/apache/rya/mongodb/MongoConnectorFactory.java
+++ b/dao/mongodb.rya/src/main/java/org/apache/rya/mongodb/MongoConnectorFactory.java
@@ -6,9 +6,9 @@
  * 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
@@ -57,7 +57,11 @@ public class MongoConnectorFactory {
     public static synchronized MongoClient getMongoClient(final Configuration conf)
             throws ConfigurationRuntimeException, MongoException {
         if (mongoClient == null) {
-            createMongoClientForServer(conf);
+            if(conf instanceof MongoDBRdfConfiguration && ((MongoDBRdfConfiguration) conf).getMongoClient() != null) {
+                mongoClient = ((MongoDBRdfConfiguration) conf).getMongoClient();
+            } else {
+                createMongoClientForServer(conf);
+            }
         }
         return mongoClient;
     }
@@ -71,7 +75,7 @@ public class MongoConnectorFactory {
     }
 
     /**
-     * Create a MongoDB client object and assign it to this class's static mongoClient 
+     * Create a MongoDB client object and assign it to this class's static mongoClient
      * @param conf configuration containing connection parameters
      * @throws ConfigurationRuntimeException - Thrown if the configured server, port, user, or others are missing.
      * @throws MongoException  if can't connect despite conf parameters are given
@@ -81,7 +85,7 @@ public class MongoConnectorFactory {
         // Connect to a running Mongo server
         final String host = requireNonNull(conf.get(MongoDBRdfConfiguration.MONGO_INSTANCE), MSG_INTRO+"host name is required");
         final int port = requireNonNullInt(conf.get(MongoDBRdfConfiguration.MONGO_INSTANCE_PORT), MSG_INTRO+"Port number is required.");
-        ServerAddress server = new ServerAddress(host, port);
+        final ServerAddress server = new ServerAddress(host, port);
         // check for authentication credentials
         if (conf.get(MongoDBRdfConfiguration.MONGO_USER) != null) {
             final String username = conf.get(MongoDBRdfConfiguration.MONGO_USER);
@@ -101,7 +105,7 @@ public class MongoConnectorFactory {
 
     /**
      * Throw exception for un-configured required values.
-     * 
+     *
      * @param required  String to check
      * @param message  throw configuration exception with this description
      * @return unaltered required string
@@ -123,7 +127,7 @@ public class MongoConnectorFactory {
         }
         try {
             return Integer.parseInt(required);
-        } catch (NumberFormatException e) {
+        } catch (final NumberFormatException e) {
             throw new ConfigurationRuntimeException(message);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/ConfigUtils.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/ConfigUtils.java b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/ConfigUtils.java
index 88e9667..7f10629 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/ConfigUtils.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/accumulo/ConfigUtils.java
@@ -43,12 +43,6 @@ import org.apache.hadoop.conf.Configuration;
 import org.apache.hadoop.mapreduce.JobContext;
 import org.apache.hadoop.util.ReflectionUtils;
 import org.apache.log4j.Logger;
-import org.openrdf.model.URI;
-import org.openrdf.model.impl.URIImpl;
-
-import com.google.common.base.Optional;
-import com.google.common.collect.Lists;
-
 import org.apache.rya.accumulo.AccumuloRdfConfiguration;
 import org.apache.rya.api.RdfCloudTripleStoreConfiguration;
 import org.apache.rya.api.instance.RyaDetails;
@@ -59,16 +53,23 @@ import org.apache.rya.indexing.accumulo.freetext.AccumuloFreeTextIndexer;
 import org.apache.rya.indexing.accumulo.freetext.LuceneTokenizer;
 import org.apache.rya.indexing.accumulo.freetext.Tokenizer;
 import org.apache.rya.indexing.accumulo.temporal.AccumuloTemporalIndexer;
+import org.apache.rya.indexing.entity.EntityIndexOptimizer;
+import org.apache.rya.indexing.entity.update.mongo.MongoEntityIndexer;
 import org.apache.rya.indexing.external.PrecomputedJoinIndexer;
 import org.apache.rya.indexing.mongodb.freetext.MongoFreeTextIndexer;
 import org.apache.rya.indexing.pcj.matching.PCJOptimizer;
 import org.apache.rya.indexing.statement.metadata.matching.StatementMetadataOptimizer;
+import org.openrdf.model.URI;
+import org.openrdf.model.impl.URIImpl;
+
+import com.google.common.base.Optional;
+import com.google.common.collect.Lists;
 
 /**
  * A set of configuration utils to read a Hadoop {@link Configuration} object and create Cloudbase/Accumulo objects.
- * Soon will deprecate this class.  Use installer for the set methods, use {@link RyaDetails} for the get methods. 
+ * Soon will deprecate this class.  Use installer for the set methods, use {@link RyaDetails} for the get methods.
  * New code must separate parameters that are set at Rya install time from that which is specific to the client.
- * Also Accumulo index tables are pushed down to the implementation and not configured in conf.   
+ * Also Accumulo index tables are pushed down to the implementation and not configured in conf.
  */
 public class ConfigUtils {
     private static final Logger logger = Logger.getLogger(ConfigUtils.class);
@@ -343,7 +344,7 @@ public class ConfigUtils {
     public static boolean getUseOptimalPCJ(final Configuration conf) {
         return conf.getBoolean(USE_OPTIMAL_PCJ, false);
     }
-    
+
     public static boolean getUsePcjUpdaterIndex(final Configuration conf) {
         return conf.getBoolean(USE_PCJ_UPDATER_INDEX, false);
     }
@@ -354,7 +355,7 @@ public class ConfigUtils {
      *   using to incrementally update PCJs.
      */
     //TODO delete this eventually and use Details table
-    public Optional<String> getFluoAppName(Configuration conf) {
+    public Optional<String> getFluoAppName(final Configuration conf) {
         return Optional.fromNullable(conf.get(FLUO_APP_NAME));
     }
 
@@ -376,12 +377,17 @@ public class ConfigUtils {
                 indexList.add(MongoFreeTextIndexer.class.getName());
                 useFilterIndex = true;
             }
+
+            if (getUseEntity(conf)) {
+                indexList.add(MongoEntityIndexer.class.getName());
+                optimizers.add(EntityIndexOptimizer.class.getName());
+            }
         } else {
 
         	 if (getUsePCJ(conf) || getUseOptimalPCJ(conf)) {
                  conf.setPcjOptimizer(PCJOptimizer.class);
              }
-             
+
              if(getUsePcjUpdaterIndex(conf)) {
              	indexList.add(PrecomputedJoinIndexer.class.getName());
              }
@@ -397,17 +403,16 @@ public class ConfigUtils {
                 useFilterIndex = true;
             }
 
+            if (getUseEntity(conf)) {
+                indexList.add(EntityCentricIndex.class.getName());
+                optimizers.add(EntityOptimizer.class.getName());
+            }
         }
 
         if (useFilterIndex) {
             optimizers.add(FilterFunctionOptimizer.class.getName());
         }
 
-        if (getUseEntity(conf)) {
-            indexList.add(EntityCentricIndex.class.getName());
-            optimizers.add(EntityOptimizer.class.getName());
-        }
-        
         if(conf.getUseStatementMetadata()) {
             optimizers.add(StatementMetadataOptimizer.class.getName());
         }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityExternalSetMatcherFactory.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityExternalSetMatcherFactory.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityExternalSetMatcherFactory.java
new file mode 100644
index 0000000..12fd471
--- /dev/null
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityExternalSetMatcherFactory.java
@@ -0,0 +1,44 @@
+/**
+ * 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.entity;
+
+import org.apache.rya.indexing.entity.query.EntityQueryNode;
+import org.apache.rya.indexing.external.matching.AbstractExternalSetMatcherFactory;
+import org.apache.rya.indexing.external.matching.ExternalSetMatcher;
+import org.apache.rya.indexing.external.matching.JoinSegment;
+import org.apache.rya.indexing.external.matching.JoinSegmentMatcher;
+import org.apache.rya.indexing.external.matching.OptionalJoinSegment;
+import org.apache.rya.indexing.external.matching.OptionalJoinSegmentMatcher;
+
+/**
+ * Factory used to build {@link EntityQueryNodeMatcher}s for the {@link EntityIndexOptimizer}.
+ *
+ */
+public class EntityExternalSetMatcherFactory extends AbstractExternalSetMatcherFactory<EntityQueryNode> {
+
+    @Override
+    protected ExternalSetMatcher<EntityQueryNode> getJoinSegmentMatcher(final JoinSegment<EntityQueryNode> segment) {
+        return new JoinSegmentMatcher<EntityQueryNode>(segment, new EntityToSegmentConverter());
+    }
+
+    @Override
+    protected ExternalSetMatcher<EntityQueryNode> getOptionalJoinSegmentMatcher(final OptionalJoinSegment<EntityQueryNode> segment) {
+        return new OptionalJoinSegmentMatcher<EntityQueryNode>(segment, new EntityToSegmentConverter());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityIndexOptimizer.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityIndexOptimizer.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityIndexOptimizer.java
new file mode 100644
index 0000000..5a45dc8
--- /dev/null
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityIndexOptimizer.java
@@ -0,0 +1,125 @@
+/**
+ * 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.entity;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import org.apache.hadoop.conf.Configurable;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.rya.indexing.entity.model.Entity;
+import org.apache.rya.indexing.entity.query.EntityQueryNode;
+import org.apache.rya.indexing.entity.storage.EntityStorage;
+import org.apache.rya.indexing.entity.storage.TypeStorage;
+import org.apache.rya.indexing.entity.update.mongo.MongoEntityIndexer;
+import org.apache.rya.indexing.external.matching.AbstractExternalSetOptimizer;
+import org.apache.rya.indexing.external.matching.ExternalSetMatcher;
+import org.apache.rya.indexing.external.matching.ExternalSetProvider;
+import org.apache.rya.indexing.external.matching.QueryNodeListRater;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.apache.rya.indexing.external.matching.TopOfQueryFilterRelocator;
+import org.openrdf.query.BindingSet;
+import org.openrdf.query.Dataset;
+import org.openrdf.query.algebra.TupleExpr;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.base.Optional;
+
+/**
+ * Optimizes a query over {@link Entity}s.
+ */
+public class EntityIndexOptimizer extends AbstractExternalSetOptimizer<EntityQueryNode> implements Configurable {
+    private static final Logger log = Logger.getLogger(EntityIndexOptimizer.class);
+    private static final EntityExternalSetMatcherFactory MATCHER_FACTORY = new EntityExternalSetMatcherFactory();
+
+    private final MongoEntityIndexer indexer;
+    private EntityIndexSetProvider provider;
+    private Configuration conf;
+
+    private EntityStorage entityStorage;
+    private TypeStorage typeStorage;
+
+    /**
+     * Creates a new {@link EntityIndexOptimizer}.
+     */
+    public EntityIndexOptimizer() {
+        indexer = new MongoEntityIndexer();
+
+        //There is no rater for entity query nodes.
+        useOptimal = false;
+    }
+
+    @Override
+    public void setConf(final Configuration conf) {
+        this.conf = conf;
+        indexer.setConf(conf);
+
+        typeStorage = indexer.getTypeStorage(conf);
+        entityStorage = indexer.getEntityStorage(conf);
+
+        provider = new EntityIndexSetProvider(typeStorage, entityStorage);
+    }
+
+    @Override
+    public Configuration getConf() {
+        return conf;
+    }
+
+    @Override
+    public void optimize(TupleExpr tupleExpr, final Dataset dataset, final BindingSet bindings) {
+        checkNotNull(tupleExpr);
+        checkNotNull(indexer);
+
+        // first standardize query by pulling all filters to top of query if
+        // they exist using TopOfQueryFilterRelocator
+        tupleExpr = TopOfQueryFilterRelocator.moveFiltersToTop(tupleExpr);
+        super.optimize(tupleExpr, null, null);
+    }
+
+    @VisibleForTesting
+    public EntityStorage getEntityStorage() {
+        return entityStorage;
+    }
+
+    @VisibleForTesting
+    public TypeStorage getTypeStorage() {
+        return typeStorage;
+    }
+
+    /**
+     * Visits a node of the query tree.  Checks to see if the node belongs
+     * or is of an {@link Entity}.  If it is, prepares it, so after the query
+     * is checked, the nodes can be replaced with {@link EntityQueryNode}s.
+     */
+
+    @Override
+    protected ExternalSetMatcher<EntityQueryNode> getMatcher(final QuerySegment<EntityQueryNode> segment) {
+        return MATCHER_FACTORY.getMatcher(segment);
+    }
+
+    @Override
+    protected ExternalSetProvider<EntityQueryNode> getProvider() {
+        return provider;
+    }
+
+    @Override
+    protected Optional<QueryNodeListRater> getNodeListRater(final QuerySegment<EntityQueryNode> segment) {
+        return Optional.absent();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityIndexSetProvider.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityIndexSetProvider.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityIndexSetProvider.java
new file mode 100644
index 0000000..1052b38
--- /dev/null
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityIndexSetProvider.java
@@ -0,0 +1,157 @@
+/**
+ * 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.entity;
+
+import static java.util.Objects.requireNonNull;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.entity.model.Entity;
+import org.apache.rya.indexing.entity.model.Type;
+import org.apache.rya.indexing.entity.query.EntityQueryNode;
+import org.apache.rya.indexing.entity.storage.EntityStorage;
+import org.apache.rya.indexing.entity.storage.TypeStorage;
+import org.apache.rya.indexing.entity.storage.TypeStorage.TypeStorageException;
+import org.apache.rya.indexing.external.matching.ExternalSetProvider;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.openrdf.model.impl.URIImpl;
+import org.openrdf.model.vocabulary.RDF;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.Var;
+
+import com.google.common.collect.HashMultimap;
+import com.google.common.collect.Multimap;
+
+/**
+ * Provides {@link EntityQueryNodes}s.
+ */
+public class EntityIndexSetProvider implements ExternalSetProvider<EntityQueryNode> {
+    private Multimap<Type, StatementPattern> typeMap;
+    private Map<String, Type> subjectTypeMap;
+    private final TypeStorage typeStorage;
+    private final EntityStorage entityStorage;
+
+    /**
+     * Creates a new {@link EntityIndexSetProvider}.
+     * @param typeStorage - The mechanism for access the various {@link Type}s. (not null)
+     * @param entityStorage - The mechanism for access to the various {@link Entity}s. (not null)
+     */
+    public EntityIndexSetProvider(final TypeStorage typeStorage, final EntityStorage entityStorage) {
+        this.typeStorage = requireNonNull(typeStorage);
+        this.entityStorage = requireNonNull(entityStorage);
+    }
+
+    private Var getTypeSubject(final Type type) {
+        //we just need the first pattern since all the patterns in this type map are the same subject
+        final StatementPattern pattern = typeMap.get(type).iterator().next();
+        return pattern.getSubjectVar();
+    }
+
+    private RyaURI getPredURI(final StatementPattern pattern) {
+        final Var pred = pattern.getPredicateVar();
+        return new RyaURI(pred.getValue().stringValue());
+    }
+
+    @Override
+    public List<EntityQueryNode> getExternalSets(final QuerySegment<EntityQueryNode> node) {
+        typeMap = HashMultimap.create();
+        subjectTypeMap = new HashMap<>();
+
+        //discover entities
+        final List<StatementPattern> unused = new ArrayList<>();
+        for (final QueryModelNode pattern : node.getOrderedNodes()) {
+            if(pattern instanceof StatementPattern) {
+                discoverEntities((StatementPattern) pattern, unused);
+            }
+        }
+
+        final List<EntityQueryNode> nodes = new ArrayList<>();
+        for(final Type type : typeMap.keySet()) {
+            //replace all nodes in the tupleExpr of the collection of statement patterns with this node.
+            final EntityQueryNode entity = new EntityQueryNode(type, typeMap.get(type), entityStorage);
+            nodes.add(entity);
+        }
+        return nodes;
+    }
+
+    private void discoverEntities(final StatementPattern pattern, final List<StatementPattern> unmatched) {
+        final Var subj = pattern.getSubjectVar();
+        final String subjStr = subj.getName();
+        final RyaURI predURI = getPredURI(pattern);
+        //check to see if current node is type
+        if(new URIImpl(predURI.getData()).equals(RDF.TYPE)) {
+            final Var obj = pattern.getObjectVar();
+            final RyaURI objURI = new RyaURI(obj.getValue().stringValue());
+            try {
+                final Optional<Type> optType = typeStorage.get(objURI);
+                //if is type, fetch type add to subject -> type map
+                if(optType.isPresent()) {
+                    final Type type = optType.get();
+                    typeMap.put(type, pattern);
+                    subjectTypeMap.put(subjStr, type);
+                    //check unmatched properties, add matches
+                    for(final StatementPattern propertyPattern : unmatched) {
+                        //store sps into the type -> property map
+                        final RyaURI property = getPredURI(propertyPattern);
+                        final Var typeSubVar = getTypeSubject(type);
+                        final Var patternSubVar = propertyPattern.getSubjectVar();
+                        if (type.getPropertyNames().contains(property) && typeSubVar.equals(patternSubVar)) {
+                            typeMap.put(type, propertyPattern);
+                        }
+                    }
+                }
+            } catch (final TypeStorageException e) {
+                e.printStackTrace();
+            }
+        } else {
+            //if not type, check to see if subject is in type map
+            if(subjectTypeMap.containsKey(subjStr)) {
+                //if is, check to see if pred is a property of type
+                final Type type = subjectTypeMap.get(subjStr);
+                if(type.getPropertyNames().contains(predURI)) {
+                    //if is, add sp to type -> sp map
+                    if(!typeMap.containsKey(type)) {
+                        //each variable can only contain 1 type for now @see:Rya-235?
+                        typeMap.put(type, pattern);
+                    }
+                } else {
+                    //if not, add to unmatched type
+                    unmatched.add(pattern);
+                }
+            } else {
+                //if not, add to unmatched
+                unmatched.add(pattern);
+            }
+        }
+    }
+
+    @Override
+    public Iterator<List<EntityQueryNode>> getExternalSetCombos(final QuerySegment<EntityQueryNode> segment) {
+        final List<List<EntityQueryNode>> comboList = new ArrayList<>();
+        comboList.add(getExternalSets(segment));
+        return comboList.iterator();
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityToSegmentConverter.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityToSegmentConverter.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityToSegmentConverter.java
new file mode 100644
index 0000000..c76a3ab
--- /dev/null
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/EntityToSegmentConverter.java
@@ -0,0 +1,51 @@
+/**
+ * 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.entity;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.rya.indexing.entity.query.EntityQueryNode;
+import org.apache.rya.indexing.external.matching.ExternalSetConverter;
+import org.apache.rya.indexing.external.matching.JoinSegment;
+import org.apache.rya.indexing.external.matching.QuerySegment;
+import org.openrdf.query.algebra.Filter;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.ValueExpr;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * Implementation of {@link ExternalSetConverter} to convert {@link EntityQueryNode}s
+ * to {@link QuerySegment}s.
+ *
+ */
+public class EntityToSegmentConverter implements ExternalSetConverter<EntityQueryNode> {
+
+    @Override
+    public QuerySegment<EntityQueryNode> setToSegment(final EntityQueryNode set) {
+        Preconditions.checkNotNull(set);
+        final Set<QueryModelNode> matched = new HashSet<>(set.getPatterns());
+        final List<QueryModelNode> unmatched = new ArrayList<>(set.getPatterns());
+        return new JoinSegment<EntityQueryNode>(matched, unmatched, new HashMap<ValueExpr, Filter>());
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Entity.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Entity.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Entity.java
index c37eed3..3eb4c39 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Entity.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Entity.java
@@ -18,6 +18,8 @@
  */
 package org.apache.rya.indexing.entity.model;
 
+import static java.util.Objects.requireNonNull;
+
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -26,6 +28,7 @@ import java.util.Map.Entry;
 import java.util.Objects;
 import java.util.Optional;
 
+import org.apache.http.annotation.Immutable;
 import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.storage.EntityStorage;
 
@@ -33,6 +36,10 @@ import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Maps;
 
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
+import edu.umd.cs.findbugs.annotations.Nullable;
+
 /**
  * An {@link Entity} is a named concept that has at least one defined structure
  * and a bunch of values that fit within each of those structures. A structure is
@@ -64,7 +71,7 @@ import com.google.common.collect.Maps;
  * Once something has done so, it is an explicitly typed Entity.
  */
 @Immutable
-
+@DefaultAnnotation(NonNull.class)
 public class Entity {
 
     private final RyaURI subject;
@@ -84,11 +91,11 @@ public class Entity {
             final RyaURI subject,
             final ImmutableList<RyaURI> explicitTypeIds,
             final ImmutableMap<RyaURI, ImmutableMap<RyaURI, Property>> typeProperties,
-            int version) {
-        subject = requireNonNull(subject);
-        explicitTypeIds = requireNonNull(explicitTypeIds);
+            final int version) {
+        this.subject = requireNonNull(subject);
+        this.explicitTypeIds = requireNonNull(explicitTypeIds);
         properties = requireNonNull(typeProperties);
-        version = version;
+        this.version = version;
     }
 
     /**
@@ -126,7 +133,7 @@ public class Entity {
     }
 
     @Override
-    public boolean equals(Object o) {
+    public boolean equals(final Object o) {
         if(this == o) {
             return true;
         }
@@ -147,7 +154,7 @@ public class Entity {
      * @return A TypedEntity using this object's values if any properties for the Type
      *    are present or if the Type was explicitly set. Otherwise an empty {@link Optional}.
      */
-    public Optional<TypedEntity> makeTypedEntity(RyaURI typeId) {
+    public Optional<TypedEntity> makeTypedEntity(final RyaURI typeId) {
         requireNonNull(typeId);
 
         final boolean explicitlyHasType = explicitTypeIds.contains(typeId);
@@ -186,14 +193,14 @@ public class Entity {
      * @param entity - The Entity the builder will be based on. (not null)
      * @return A {@link Builder} loaded with {@code entity}'s values.
      */
-    public static Builder builder(Entity entity) {
+    public static Builder builder(final Entity entity) {
         return new Builder(entity);
     }
 
     /**
      * Builds instances of {@link Entity}.
      */
-    @ParametersAreNonnullByDefault
+    @DefaultAnnotation(NonNull.class)
     public static class Builder {
 
         private RyaURI subject = null;
@@ -212,7 +219,7 @@ public class Entity {
          *
          * @param entity - The Entity the builder will be based on. (not null)
          */
-        public Builder(Entity entity) {
+        public Builder(final Entity entity) {
             requireNonNull(entity);
 
             subject = entity.getSubject();
@@ -230,7 +237,7 @@ public class Entity {
          * @return This {@link Builder} so that method invocations may be chained.
          */
         public Builder setSubject(@Nullable final RyaURI subject) {
-            subject = subject;
+            this.subject = subject;
             return this;
         }
 
@@ -300,8 +307,8 @@ public class Entity {
          * {@link EntityStorage} to prevent stale updates.
          * @return This {@link Builder} so that method invocations may be chained.
          */
-        public Builder setVersion(int version) {
-            version = version;
+        public Builder setVersion(final int version) {
+            this.version = version;
             return this;
         }
 

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Property.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Property.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Property.java
index 4388024..53b141e 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Property.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Property.java
@@ -22,17 +22,18 @@ import static java.util.Objects.requireNonNull;
 
 import java.util.Objects;
 
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
+import org.apache.http.annotation.Immutable;
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
 
-import mvm.rya.api.domain.RyaType;
-import mvm.rya.api.domain.RyaURI;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * A value that has been set for an {@link TypedEntity}.
  */
 @Immutable
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public class Property {
 
     private final RyaURI name;

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Type.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Type.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Type.java
index 7d8e0ee..f539e7c 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Type.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/Type.java
@@ -22,14 +22,14 @@ import static java.util.Objects.requireNonNull;
 
 import java.util.Objects;
 
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
-
+import org.apache.http.annotation.Immutable;
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.storage.TypeStorage;
 
 import com.google.common.collect.ImmutableSet;
 
-import mvm.rya.api.domain.RyaURI;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * Defines the structure of an {@link TypedEntity}.
@@ -45,7 +45,7 @@ import mvm.rya.api.domain.RyaURI;
  * </pre>
  */
 @Immutable
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public class Type {
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/TypedEntity.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/TypedEntity.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/TypedEntity.java
index a49c8d2..0d019c2 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/TypedEntity.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/model/TypedEntity.java
@@ -23,24 +23,25 @@ import static java.util.Objects.requireNonNull;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 
-import javax.annotation.Nullable;
-import javax.annotation.ParametersAreNonnullByDefault;
-import javax.annotation.concurrent.Immutable;
+import org.apache.http.annotation.Immutable;
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
 
-import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableMap;
 
-import mvm.rya.api.domain.RyaType;
-import mvm.rya.api.domain.RyaURI;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
+import edu.umd.cs.findbugs.annotations.Nullable;
 
 /**
  * A {@link TypedEntity} is a view of an {@link Entity} that has had a specific
  * {@link Type} applied to it.
  */
 @Immutable
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public class TypedEntity {
 
     /**
@@ -79,10 +80,10 @@ public class TypedEntity {
      */
     private TypedEntity(final RyaURI subject,
             final RyaURI dataTypeId,
-            boolean explicitlyTyped,
+            final boolean explicitlyTyped,
             final ImmutableMap<RyaURI, Property> optionalFields) {
         this.subject = requireNonNull(subject);
-        this.typeId = requireNonNull(dataTypeId);
+        typeId = requireNonNull(dataTypeId);
         this.optionalFields = requireNonNull(optionalFields);
         this.explicitlyTyped = explicitlyTyped;
     }
@@ -129,7 +130,7 @@ public class TypedEntity {
 
         final Property field = optionalFields.get(propertyName);
         return field == null ?
-                Optional.absent() :
+                Optional.empty() :
                 Optional.of( field.getValue() );
     }
 
@@ -139,7 +140,7 @@ public class TypedEntity {
     }
 
     @Override
-    public boolean equals(Object o) {
+    public boolean equals(final Object o) {
         if(this == o) {
             return true;
         }
@@ -165,7 +166,7 @@ public class TypedEntity {
      * @param entity - The initial values of the builder. (not null)
      * @return An instance of {@link Builder} loaded with {@code entity}'s values.
      */
-    public static Builder builder(TypedEntity entity) {
+    public static Builder builder(final TypedEntity entity) {
         requireNonNull(entity);
 
         final Builder builder = builder()
@@ -180,7 +181,7 @@ public class TypedEntity {
     /**
      * Builds instances of {@link TypedEntity}.
      */
-    @ParametersAreNonnullByDefault
+    @DefaultAnnotation(NonNull.class)
     public static class Builder {
 
         private RyaURI subject;
@@ -212,7 +213,7 @@ public class TypedEntity {
          * only exists because it has properties that happen to match that type's properties).
          * @return This {@link Builder} so that method invocations may be chained.
          */
-        public Builder setExplicitelyTyped(boolean explicitlyTyped) {
+        public Builder setExplicitelyTyped(final boolean explicitlyTyped) {
             this.explicitlyTyped = explicitlyTyped;
             return this;
         }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/query/EntityQueryNode.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/query/EntityQueryNode.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/query/EntityQueryNode.java
index bb14922..1174b21 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/query/EntityQueryNode.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/query/EntityQueryNode.java
@@ -20,31 +20,53 @@ package org.apache.rya.indexing.entity.query;
 
 import static java.util.Objects.requireNonNull;
 
+import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
 import java.util.Optional;
-
-import javax.annotation.ParametersAreNonnullByDefault;
-
+import java.util.Set;
+import java.util.function.Consumer;
+
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.api.resolver.RdfToRyaConversions;
+import org.apache.rya.indexing.entity.model.Entity;
+import org.apache.rya.indexing.entity.model.Property;
 import org.apache.rya.indexing.entity.model.Type;
+import org.apache.rya.indexing.entity.model.TypedEntity;
 import org.apache.rya.indexing.entity.storage.EntityStorage;
+import org.apache.rya.indexing.entity.storage.EntityStorage.EntityStorageException;
+import org.apache.rya.indexing.entity.storage.mongo.ConvertingCursor;
+import org.apache.rya.indexing.entity.update.EntityIndexer;
+import org.apache.rya.rdftriplestore.evaluation.ExternalBatchingIterator;
+import org.openrdf.model.impl.ValueFactoryImpl;
 import org.openrdf.model.vocabulary.RDF;
+import org.openrdf.query.Binding;
 import org.openrdf.query.BindingSet;
 import org.openrdf.query.QueryEvaluationException;
 import org.openrdf.query.algebra.StatementPattern;
 import org.openrdf.query.algebra.Var;
 import org.openrdf.query.algebra.evaluation.impl.ExternalSet;
+import org.openrdf.query.algebra.evaluation.iterator.CollectionIteration;
+import org.openrdf.query.impl.MapBindingSet;
 
+import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableMap.Builder;
 
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 import info.aduna.iteration.CloseableIteration;
-import mvm.rya.api.domain.RyaURI;
-import mvm.rya.rdftriplestore.evaluation.ExternalBatchingIterator;
+import jline.internal.Log;
 
 /**
- * TODO impl, test, doc
+ * Indexing Node for {@link Entity} expressions to be inserted into execution plan
+ * to delegate entity portion of query to {@link EntityIndexer}.
  */
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public class EntityQueryNode extends ExternalSet implements ExternalBatchingIterator {
 
     /**
@@ -62,11 +84,14 @@ public class EntityQueryNode extends ExternalSet implements ExternalBatchingIter
     private final Optional<String> subjectConstant;
     private final Optional<String> subjectVar;
 
+    //since and EntityQueryNode exists in a single segment, all binding names are garunteed to be assured.
+    private final Set<String> bindingNames;
+
     // Information about the objects of the patterns.
+    private final ImmutableMap<RyaURI, Var> objectVariables;
 
-    // XXX what does this map? property name -> binding variable?
-    // for any property of the entity that has a variable, have to fill it in?
-    private final ImmutableMap<RyaURI, String> objectVariables;
+    // Properties of the Type found in the query
+    private final Set<Property> properties;
 
 
     /**
@@ -83,6 +108,8 @@ public class EntityQueryNode extends ExternalSet implements ExternalBatchingIter
         this.patterns = requireNonNull(patterns);
         this.entities = requireNonNull(entities);
 
+        bindingNames = new HashSet<>();
+        properties = new HashSet<>();
         // Subject based preconditions.
         verifySameSubjects(patterns);
 
@@ -102,11 +129,30 @@ public class EntityQueryNode extends ExternalSet implements ExternalBatchingIter
             subjectVar = Optional.of( subject.getName() );
         }
 
-        // TODO Also, map each variable that is in an Object spot each variable can be mapped to a property name as well
-        // Processing note:
         // Any constant that appears in the Object portion of the SP will be used to make sure they match.
+        final Builder<RyaURI, Var> builder = ImmutableMap.<RyaURI, Var>builder();
+        for(final StatementPattern sp : patterns) {
+            final Var object = sp.getObjectVar();
+            final Var pred = sp.getPredicateVar();
+            final RyaURI predURI = new RyaURI(pred.getValue().stringValue());
+            bindingNames.addAll(sp.getBindingNames());
+            if(object.isConstant() && !pred.getValue().equals(RDF.TYPE)) {
+                final RyaType propertyType = RdfToRyaConversions.convertValue(object.getValue());
+                properties.add(new Property(predURI, propertyType));
+            }
+            builder.put(predURI, object);
+        }
+        objectVariables = builder.build();
+    }
 
-        objectVariables = null;
+    @Override
+    public Set<String> getBindingNames() {
+        return bindingNames;
+    }
+
+    @Override
+    public Set<String> getAssuredBindingNames() {
+        return bindingNames;
     }
 
     /**
@@ -115,7 +161,7 @@ public class EntityQueryNode extends ExternalSet implements ExternalBatchingIter
      * @param patterns - The patterns to check.
      * @throws IllegalStateException If all of the Subjects are not the same.
      */
-    private static void verifySameSubjects(Collection<StatementPattern> patterns) throws IllegalStateException {
+    private static void verifySameSubjects(final Collection<StatementPattern> patterns) throws IllegalStateException {
         requireNonNull(patterns);
 
         final Iterator<StatementPattern> it = patterns.iterator();
@@ -136,7 +182,7 @@ public class EntityQueryNode extends ExternalSet implements ExternalBatchingIter
      * @param patterns - The patterns to check. (not null)
      * @throws IllegalStateException A pattern has a variable predicate.
      */
-    private static void verifyAllPredicatesAreConstants(Collection<StatementPattern> patterns) throws IllegalStateException {
+    private static void verifyAllPredicatesAreConstants(final Collection<StatementPattern> patterns) throws IllegalStateException {
         requireNonNull(patterns);
 
         for(final StatementPattern pattern : patterns) {
@@ -153,7 +199,7 @@ public class EntityQueryNode extends ExternalSet implements ExternalBatchingIter
      * @param patterns - The patterns to check. (not null)
      * @throws IllegalStateException No Type or the wrong Type is specified by the patterns.
      */
-    private static void verifyHasCorrectTypePattern(Type type, Collection<StatementPattern> patterns) throws IllegalStateException {
+    private static void verifyHasCorrectTypePattern(final Type type, final Collection<StatementPattern> patterns) throws IllegalStateException {
         requireNonNull(type);
         requireNonNull(patterns);
 
@@ -186,7 +232,7 @@ public class EntityQueryNode extends ExternalSet implements ExternalBatchingIter
      * @throws IllegalStateException If any of the non-type defining Statement Patterns
      *   contain a predicate that does not match one of the Type's property names.
      */
-    private static void verifyAllPredicatesPartOfType(Type type, Collection<StatementPattern> patterns) throws IllegalStateException {
+    private static void verifyAllPredicatesPartOfType(final Type type, final Collection<StatementPattern> patterns) throws IllegalStateException {
         requireNonNull(type);
         requireNonNull(patterns);
 
@@ -204,35 +250,117 @@ public class EntityQueryNode extends ExternalSet implements ExternalBatchingIter
         }
     }
 
-
-
-
-
-
     @Override
-    public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(Collection<BindingSet> bindingSets) throws QueryEvaluationException {
-        // TODO Auto-generated method stub
-        return null;
+    public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(final Collection<BindingSet> bindingSets) throws QueryEvaluationException {
+        requireNonNull(bindingSets);
+        final List<BindingSet> list = new ArrayList<>();
+        bindingSets.forEach(bindingSet -> {
+            try {
+                list.addAll(findBindings(bindingSet));
+            } catch (final Exception e) {
+                Log.error("Unable to evaluate bindingset.", e);
+            }
+        });
+
+        return new CollectionIteration<>(list);
     }
 
     @Override
-    public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(BindingSet bindingSet) throws QueryEvaluationException {
+    public CloseableIteration<BindingSet, QueryEvaluationException> evaluate(final BindingSet bindingSet) throws QueryEvaluationException {
         requireNonNull(bindingSet);
+        return new CollectionIteration<>(findBindings(bindingSet));
+    }
 
-        // ... ok, so if the subject needs to be filled in, then we need to see if the subject variable is in the binding set.
-        // if it is, fetch that value and then fetch the entity for the subject.
-
-        // if it isn't, fetch the entity for the constant?
+    private List<BindingSet> findBindings(final BindingSet bindingSet) throws QueryEvaluationException {
+        final MapBindingSet resultSet = new MapBindingSet();
+        try {
+            final ConvertingCursor<TypedEntity> entitiesCursor;
+            final String subj;
+            // If the subject needs to be filled in, check if the subject variable is in the binding set.
+            if(subjectIsConstant) {
+                // if it is, fetch that value and then fetch the entity for the subject.
+                subj = subjectConstant.get();
+                entitiesCursor = entities.search(Optional.of(new RyaURI(subj)), type, properties);
+            } else {
+                entitiesCursor = entities.search(Optional.empty(), type, properties);
+            }
 
+            while(entitiesCursor.hasNext()) {
+                final TypedEntity typedEntity = entitiesCursor.next();
+                final ImmutableCollection<Property> properties = typedEntity.getProperties();
+                //ensure properties match and only add properties that are in the statement patterns to the binding set
+                for(final RyaURI key : objectVariables.keySet()) {
+                    final Optional<RyaType> prop = typedEntity.getPropertyValue(new RyaURI(key.getData()));
+                    if(prop.isPresent()) {
+                        final RyaType type = prop.get();
+                        final String bindingName = objectVariables.get(key).getName();
+                        resultSet.addBinding(bindingName, ValueFactoryImpl.getInstance().createLiteral(type.getData()));
+                    }
+                }
+            }
+        } catch (final EntityStorageException e) {
+            throw new QueryEvaluationException("Failed to evaluate the binding set", e);
+        }
+        bindingSet.forEach(new Consumer<Binding>() {
+            @Override
+            public void accept(final Binding binding) {
+                resultSet.addBinding(binding);
+            }
+        });
+        final List<BindingSet> list = new ArrayList<>();
+        list.add(resultSet);
+        return list;
+    }
 
-        // RETURN AN EMPTY ITERATION IF IT CAN NOT FILL IT IN!
+    /**
+     * @return - The {@link StatementPattern}s that make up this {@link EntityQueryNode}
+     */
+    public Collection<StatementPattern> getPatterns() {
+        return patterns;
+    }
 
-        // for all variables in the OBJECT portion of the SPs, fill 'em in using the entity that is stored in the index.
+    @Override
+    public int hashCode() {
+        return Objects.hash(subjectIsConstant,
+                type,
+                subjectVar,
+                subjectConstant,
+                getPatterns());
+    }
 
-        // x = alice's SSN
-        // y = blue  <-- how do i know this is for urn:eye property? FROM THE STATEMENT PATTERN. look for the ?y in the SP, and that has the property name in it.
+    @Override
+    public boolean equals(final Object other) {
+        if(other instanceof EntityQueryNode) {
+            final EntityQueryNode otherNode = (EntityQueryNode)other;
+
+            final boolean samePatterns = getPatterns().size() == otherNode.getPatterns().size();
+            boolean match = true;
+            if(samePatterns) {
+                for(final StatementPattern sp : getPatterns()) {
+                    if(!otherNode.getPatterns().contains(sp)) {
+                        match = false;
+                        break;
+                    }
+                }
+            }
+            return  Objects.equals(subjectIsConstant, otherNode.subjectIsConstant) &&
+                    Objects.equals(subjectVar, otherNode.subjectVar) &&
+                    Objects.equals(type, otherNode.type) &&
+                    Objects.equals(subjectConstant, otherNode.subjectConstant)
+                    && samePatterns && match;
+        }
+        return false;
+    }
 
-        // TODO Auto-generated method stub
-        return null;
+    @Override
+    public String toString() {
+        final StringBuilder sb = new StringBuilder();
+        sb.append("Type: " + type.toString());
+        sb.append("Statement Patterns:");
+        sb.append("-------------------");
+        for(final StatementPattern sp : getPatterns()) {
+            sb.append(sp.toString());
+        }
+        return sb.toString();
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/CloseableIterator.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/CloseableIterator.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/CloseableIterator.java
deleted file mode 100644
index 3b2e10f..0000000
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/CloseableIterator.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/**
- * 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.entity.storage;
-
-import java.io.Closeable;
-import java.util.Iterator;
-
-/**
- * An {@link Iterator} that is also {@link Closeable}.
- *
- * @param <T> - The type of object that will be iterated over.
- */
-public interface CloseableIterator<T> extends Iterator<T>, Closeable { }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/EntityStorage.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/EntityStorage.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/EntityStorage.java
index 44db8e2..34dbf15 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/EntityStorage.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/EntityStorage.java
@@ -21,20 +21,22 @@ package org.apache.rya.indexing.entity.storage;
 import java.util.Optional;
 import java.util.Set;
 
-import javax.annotation.ParametersAreNonnullByDefault;
-
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.EntityIndexException;
 import org.apache.rya.indexing.entity.model.Entity;
 import org.apache.rya.indexing.entity.model.Property;
 import org.apache.rya.indexing.entity.model.Type;
 import org.apache.rya.indexing.entity.model.TypedEntity;
+import org.apache.rya.indexing.entity.storage.mongo.ConvertingCursor;
+import org.calrissian.mango.collect.CloseableIterator;
 
-import mvm.rya.api.domain.RyaURI;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * Stores and provides access to {@link Entity}s.
  */
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public interface EntityStorage {
 
     /**
@@ -69,12 +71,13 @@ public interface EntityStorage {
      * Search the stored {@link Entity}s that have a specific {@link Type} as
      * well as the provided {@link Property} values.
      *
+     * @param subject - The {@link RyaURI} subject of the Entity. (Optional)
      * @param type - The {@link Type} of the Entities. (not null)
      * @param properties - The {@link Property} values that must be set on the Entity. (not null)
      * @return A {@link CloseableIterator} over the {@link TypedEntity}s that match the search parameters.
      * @throws EntityStorageException A problem occurred while searching the storage.
      */
-    public CloseableIterator<TypedEntity> search(Type type, Set<Property> properties) throws EntityStorageException;
+    public ConvertingCursor<TypedEntity> search(final Optional<RyaURI> subject, Type type, Set<Property> properties) throws EntityStorageException;
 
     /**
      * Deletes an {@link Entity} from the storage.
@@ -99,7 +102,7 @@ public interface EntityStorage {
          * @param   message   the detail message. The detail message is saved for
          *          later retrieval by the {@link #getMessage()} method.
          */
-        public EntityStorageException(String message) {
+        public EntityStorageException(final String message) {
             super(message);
         }
 
@@ -116,7 +119,7 @@ public interface EntityStorage {
          *         permitted, and indicates that the cause is nonexistent or
          *         unknown.)
          */
-        public EntityStorageException(String message, Throwable cause) {
+        public EntityStorageException(final String message, final Throwable cause) {
             super(message, cause);
         }
     }
@@ -127,11 +130,11 @@ public interface EntityStorage {
     public static class EntityAlreadyExistsException extends EntityStorageException {
         private static final long serialVersionUID = 1L;
 
-        public EntityAlreadyExistsException(String message) {
+        public EntityAlreadyExistsException(final String message) {
             super(message);
         }
 
-        public EntityAlreadyExistsException(String message, Throwable cause) {
+        public EntityAlreadyExistsException(final String message, final Throwable cause) {
             super(message, cause);
         }
     }
@@ -143,11 +146,11 @@ public interface EntityStorage {
     public static class StaleUpdateException extends EntityStorageException {
         private static final long serialVersionUID = 1L;
 
-        public StaleUpdateException(String message) {
+        public StaleUpdateException(final String message) {
             super(message);
         }
 
-        public StaleUpdateException(String message, Throwable cause) {
+        public StaleUpdateException(final String message, final Throwable cause) {
             super(message, cause);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/TypeStorage.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/TypeStorage.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/TypeStorage.java
index 2d4622f..31b1790 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/TypeStorage.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/TypeStorage.java
@@ -18,19 +18,20 @@
  */
 package org.apache.rya.indexing.entity.storage;
 
-import javax.annotation.ParametersAreNonnullByDefault;
+import java.util.Optional;
 
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.EntityIndexException;
 import org.apache.rya.indexing.entity.model.Type;
+import org.apache.rya.indexing.entity.storage.mongo.ConvertingCursor;
 
-import com.google.common.base.Optional;
-
-import mvm.rya.api.domain.RyaURI;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * Stores and provides access to {@link Type}s.
  */
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public interface TypeStorage {
 
     /**
@@ -58,7 +59,7 @@ public interface TypeStorage {
      * @throws TypeStorageException A problem occurred while searching for the Types
      *   that have the Property name.
      */
-    public CloseableIterator<Type> search(RyaURI propertyName) throws TypeStorageException;
+    public ConvertingCursor<Type> search(RyaURI propertyName) throws TypeStorageException;
 
     /**
      * Deletes a {@link Type} from the storage.
@@ -83,7 +84,7 @@ public interface TypeStorage {
          * @param   message   the detail message. The detail message is saved for
          *          later retrieval by the {@link #getMessage()} method.
          */
-        public TypeStorageException(String message) {
+        public TypeStorageException(final String message) {
             super(message);
         }
 
@@ -100,7 +101,7 @@ public interface TypeStorage {
          *         permitted, and indicates that the cause is nonexistent or
          *         unknown.)
          */
-        public TypeStorageException(String message, Throwable cause) {
+        public TypeStorageException(final String message, final Throwable cause) {
             super(message, cause);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/ConvertingCursor.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/ConvertingCursor.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/ConvertingCursor.java
index 31a9308..df5c3a4 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/ConvertingCursor.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/ConvertingCursor.java
@@ -20,10 +20,11 @@ package org.apache.rya.indexing.entity.storage.mongo;
 
 import static java.util.Objects.requireNonNull;
 
+import java.io.Closeable;
 import java.io.IOException;
+import java.util.Iterator;
 import java.util.function.Function;
 
-import org.apache.rya.indexing.entity.storage.CloseableIterator;
 import org.bson.Document;
 
 import com.mongodb.client.MongoCursor;
@@ -34,7 +35,7 @@ import com.mongodb.client.MongoCursor;
  *
  * @param <T> - The type of object the Documents are converted into.
  */
-public class ConvertingCursor<T> implements CloseableIterator<T> {
+public class ConvertingCursor<T> implements Iterator<T>, Closeable {
 
     private final Converter<T> converter;
     private final MongoCursor<Document> cursor;
@@ -45,7 +46,7 @@ public class ConvertingCursor<T> implements CloseableIterator<T> {
      * @param converter - Converts the {@link Document}s returned by {@code cursor}. (not null)
      * @param cursor - Retrieves the {@link Document}s from a Mongo DB instance. (not null)
      */
-    public ConvertingCursor(Converter<T> converter, MongoCursor<Document> cursor) {
+    public ConvertingCursor(final Converter<T> converter, final MongoCursor<Document> cursor) {
         this.converter = requireNonNull(converter);
         this.cursor = requireNonNull(cursor);
     }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/DocumentConverter.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/DocumentConverter.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/DocumentConverter.java
index da3e8b6..63d437d 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/DocumentConverter.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/DocumentConverter.java
@@ -18,16 +18,17 @@
  */
 package org.apache.rya.indexing.entity.storage.mongo;
 
-import javax.annotation.ParametersAreNonnullByDefault;
-
 import org.bson.Document;
 
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
+
 /**
  * Converts an object to/from a {@link Document}.
  *
  * @param <T> - The type of object that is converted to/from a {@link Document}.
  */
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public interface DocumentConverter<T> {
 
     /**
@@ -54,11 +55,11 @@ public interface DocumentConverter<T> {
     public static class DocumentConverterException extends Exception {
         private static final long serialVersionUID = 1L;
 
-        public DocumentConverterException(String message) {
+        public DocumentConverterException(final String message) {
             super(message);
         }
 
-        public DocumentConverterException(String message, Throwable cause) {
+        public DocumentConverterException(final String message, final Throwable cause) {
             super(message, cause);
         }
     }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/EntityDocumentConverter.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/EntityDocumentConverter.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/EntityDocumentConverter.java
index 6a2fb74..a46fd5a 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/EntityDocumentConverter.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/EntityDocumentConverter.java
@@ -23,19 +23,19 @@ import static java.util.Objects.requireNonNull;
 import java.util.List;
 import java.util.stream.Collectors;
 
-import javax.annotation.ParametersAreNonnullByDefault;
-
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.model.Entity;
 import org.apache.rya.indexing.entity.model.Property;
 import org.bson.Document;
 
-import mvm.rya.api.domain.RyaType;
-import mvm.rya.api.domain.RyaURI;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * Converts between {@link Entity} and {@link Document}.
  */
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public class EntityDocumentConverter implements DocumentConverter<Entity> {
 
     public static final String SUBJECT = "_id";
@@ -46,7 +46,7 @@ public class EntityDocumentConverter implements DocumentConverter<Entity> {
     private final RyaTypeDocumentConverter ryaTypeConverter = new RyaTypeDocumentConverter();
 
     @Override
-    public Document toDocument(Entity entity) {
+    public Document toDocument(final Entity entity) {
         requireNonNull(entity);
 
         final Document doc = new Document();
@@ -75,7 +75,7 @@ public class EntityDocumentConverter implements DocumentConverter<Entity> {
     }
 
     @Override
-    public Entity fromDocument(Document document) throws DocumentConverterException {
+    public Entity fromDocument(final Document document) throws DocumentConverterException {
         requireNonNull(document);
 
         // Preconditions.

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/MongoEntityStorage.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/MongoEntityStorage.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/MongoEntityStorage.java
index 8a5f6da..3fc817b 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/MongoEntityStorage.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/MongoEntityStorage.java
@@ -26,13 +26,11 @@ import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
-import javax.annotation.ParametersAreNonnullByDefault;
-
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.model.Entity;
 import org.apache.rya.indexing.entity.model.Property;
 import org.apache.rya.indexing.entity.model.Type;
 import org.apache.rya.indexing.entity.model.TypedEntity;
-import org.apache.rya.indexing.entity.storage.CloseableIterator;
 import org.apache.rya.indexing.entity.storage.EntityStorage;
 import org.apache.rya.indexing.entity.storage.mongo.ConvertingCursor.Converter;
 import org.apache.rya.indexing.entity.storage.mongo.DocumentConverter.DocumentConverterException;
@@ -47,12 +45,13 @@ import com.mongodb.client.MongoCollection;
 import com.mongodb.client.MongoCursor;
 import com.mongodb.client.model.Filters;
 
-import mvm.rya.api.domain.RyaURI;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * A Mongo DB implementation of {@link EntityStorage}.
  */
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public class MongoEntityStorage implements EntityStorage {
 
     private static final String COLLECTION_NAME = "entity-entities";
@@ -75,13 +74,13 @@ public class MongoEntityStorage implements EntityStorage {
      * @param mongo - A client connected to the Mongo instance that hosts the Rya instance. (not null)
      * @param ryaInstanceName - The name of the Rya instance the {@link TypedEntity}s are for. (not null)
      */
-    public MongoEntityStorage(MongoClient mongo, String ryaInstanceName) {
+    public MongoEntityStorage(final MongoClient mongo, final String ryaInstanceName) {
         this.mongo = requireNonNull(mongo);
         this.ryaInstanceName = requireNonNull(ryaInstanceName);
     }
 
     @Override
-    public void create(Entity entity) throws EntityStorageException {
+    public void create(final Entity entity) throws EntityStorageException {
         requireNonNull(entity);
 
         try {
@@ -99,7 +98,7 @@ public class MongoEntityStorage implements EntityStorage {
     }
 
     @Override
-    public void update(Entity old, Entity updated) throws StaleUpdateException, EntityStorageException {
+    public void update(final Entity old, final Entity updated) throws StaleUpdateException, EntityStorageException {
         requireNonNull(old);
         requireNonNull(updated);
 
@@ -134,7 +133,7 @@ public class MongoEntityStorage implements EntityStorage {
     }
 
     @Override
-    public Optional<Entity> get(RyaURI subject) throws EntityStorageException {
+    public Optional<Entity> get(final RyaURI subject) throws EntityStorageException {
         requireNonNull(subject);
 
         try {
@@ -153,7 +152,7 @@ public class MongoEntityStorage implements EntityStorage {
     }
 
     @Override
-    public CloseableIterator<TypedEntity> search(final Type type, final Set<Property> properties) throws EntityStorageException {
+    public ConvertingCursor<TypedEntity> search(final Optional<RyaURI> subject, final Type type, final Set<Property> properties) throws EntityStorageException {
         requireNonNull(type);
         requireNonNull(properties);
 
@@ -197,7 +196,7 @@ public class MongoEntityStorage implements EntityStorage {
     }
 
     @Override
-    public boolean delete(RyaURI subject) throws EntityStorageException {
+    public boolean delete(final RyaURI subject) throws EntityStorageException {
         requireNonNull(subject);
 
         try {
@@ -212,19 +211,19 @@ public class MongoEntityStorage implements EntityStorage {
         }
     }
 
-    private static Bson makeSubjectFilter(RyaURI subject) {
+    private static Bson makeSubjectFilter(final RyaURI subject) {
         return Filters.eq(EntityDocumentConverter.SUBJECT, subject.getData());
     }
 
-    private static Bson makeVersionFilter(int version) {
+    private static Bson makeVersionFilter(final int version) {
         return Filters.eq(EntityDocumentConverter.VERSION, version);
     }
 
-    private static Bson makeExplicitTypeFilter(RyaURI typeId) {
+    private static Bson makeExplicitTypeFilter(final RyaURI typeId) {
         return Filters.eq(EntityDocumentConverter.EXPLICIT_TYPE_IDS, typeId.getData());
     }
 
-    private static Stream<Bson> makePropertyFilters(RyaURI typeId, Property property) {
+    private static Stream<Bson> makePropertyFilters(final RyaURI typeId, final Property property) {
         final String propertyName = property.getName().getData();
 
         // Must match the property's data type.

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/MongoTypeStorage.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/MongoTypeStorage.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/MongoTypeStorage.java
index 88a0aa1..0083671 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/MongoTypeStorage.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/MongoTypeStorage.java
@@ -20,27 +20,27 @@ package org.apache.rya.indexing.entity.storage.mongo;
 
 import static java.util.Objects.requireNonNull;
 
-import javax.annotation.ParametersAreNonnullByDefault;
+import java.util.Optional;
 
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.model.Type;
-import org.apache.rya.indexing.entity.storage.CloseableIterator;
 import org.apache.rya.indexing.entity.storage.TypeStorage;
 import org.apache.rya.indexing.entity.storage.mongo.DocumentConverter.DocumentConverterException;
 import org.bson.Document;
 import org.bson.conversions.Bson;
 
-import com.google.common.base.Optional;
 import com.mongodb.MongoClient;
 import com.mongodb.MongoException;
 import com.mongodb.client.MongoCursor;
 import com.mongodb.client.model.Filters;
 
-import mvm.rya.api.domain.RyaURI;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * A Mongo DB implementation of {@link TypeStorage}.
  */
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public class MongoTypeStorage implements TypeStorage {
 
     private static final String COLLECTION_NAME = "entity-types";
@@ -63,13 +63,13 @@ public class MongoTypeStorage implements TypeStorage {
      * @param mongo - A client connected to the Mongo instance that hosts the Rya instance. (not null)
      * @param ryaInstanceName - The name of the Rya instance the {@link Type}s are for. (not null)
      */
-    public MongoTypeStorage(MongoClient mongo, String ryaInstanceName) {
+    public MongoTypeStorage(final MongoClient mongo, final String ryaInstanceName) {
         this.mongo = requireNonNull(mongo);
         this.ryaInstanceName = requireNonNull(ryaInstanceName);
     }
 
     @Override
-    public void create(Type type) throws TypeStorageException {
+    public void create(final Type type) throws TypeStorageException {
         requireNonNull(type);
 
         try {
@@ -83,7 +83,7 @@ public class MongoTypeStorage implements TypeStorage {
     }
 
     @Override
-    public Optional<Type> get(RyaURI typeId) throws TypeStorageException {
+    public Optional<Type> get(final RyaURI typeId) throws TypeStorageException {
         requireNonNull(typeId);
 
         try {
@@ -93,7 +93,7 @@ public class MongoTypeStorage implements TypeStorage {
                 .first();
 
             return document == null ?
-                    Optional.absent() :
+                    Optional.empty() :
                     Optional.of( TYPE_CONVERTER.fromDocument(document) );
 
         } catch(final MongoException | DocumentConverterException e) {
@@ -102,7 +102,7 @@ public class MongoTypeStorage implements TypeStorage {
     }
 
     @Override
-    public CloseableIterator<Type> search(RyaURI propertyName) throws TypeStorageException {
+    public ConvertingCursor<Type> search(final RyaURI propertyName) throws TypeStorageException {
         requireNonNull(propertyName);
 
         try {
@@ -128,7 +128,7 @@ public class MongoTypeStorage implements TypeStorage {
     }
 
     @Override
-    public boolean delete(RyaURI typeId) throws TypeStorageException {
+    public boolean delete(final RyaURI typeId) throws TypeStorageException {
         requireNonNull(typeId);
 
         try {
@@ -143,7 +143,7 @@ public class MongoTypeStorage implements TypeStorage {
         }
     }
 
-    private static Bson makeIdFilter(RyaURI typeId) {
+    private static Bson makeIdFilter(final RyaURI typeId) {
         return Filters.eq(TypeDocumentConverter.ID, typeId.getData());
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/RyaTypeDocumentConverter.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/RyaTypeDocumentConverter.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/RyaTypeDocumentConverter.java
index f7fd4ac..c0afd73 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/RyaTypeDocumentConverter.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/RyaTypeDocumentConverter.java
@@ -20,18 +20,18 @@ package org.apache.rya.indexing.entity.storage.mongo;
 
 import static java.util.Objects.requireNonNull;
 
-import javax.annotation.ParametersAreNonnullByDefault;
-
+import org.apache.rya.api.domain.RyaType;
 import org.bson.Document;
 import org.openrdf.model.ValueFactory;
 import org.openrdf.model.impl.ValueFactoryImpl;
 
-import mvm.rya.api.domain.RyaType;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * Converts between {@link RyaType} and {@link Document}.
  */
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public class RyaTypeDocumentConverter implements DocumentConverter<RyaType> {
 
     private static final ValueFactory VF = new ValueFactoryImpl();
@@ -40,7 +40,7 @@ public class RyaTypeDocumentConverter implements DocumentConverter<RyaType> {
     public static final String VALUE = "value";
 
     @Override
-    public Document toDocument(RyaType ryaType) {
+    public Document toDocument(final RyaType ryaType) {
         requireNonNull(ryaType);
 
         return new Document()
@@ -49,7 +49,7 @@ public class RyaTypeDocumentConverter implements DocumentConverter<RyaType> {
     }
 
     @Override
-    public RyaType fromDocument(Document document) throws DocumentConverterException {
+    public RyaType fromDocument(final Document document) throws DocumentConverterException {
         requireNonNull(document);
 
         if(!document.containsKey(DATA_TYPE)) {

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/TypeDocumentConverter.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/TypeDocumentConverter.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/TypeDocumentConverter.java
index 104fbad..37c65bb 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/TypeDocumentConverter.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/storage/mongo/TypeDocumentConverter.java
@@ -23,19 +23,19 @@ import static java.util.Objects.requireNonNull;
 import java.util.ArrayList;
 import java.util.List;
 
-import javax.annotation.ParametersAreNonnullByDefault;
-
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.model.Type;
 import org.bson.Document;
 
 import com.google.common.collect.ImmutableSet;
 
-import mvm.rya.api.domain.RyaURI;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * Converts between {@link Type} and {@link Document}.
  */
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public class TypeDocumentConverter implements DocumentConverter<Type> {
 
     public static final String ID = "_id";


[4/4] incubator-rya git commit: Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-rya

Posted by pu...@apache.org.
Merge branch 'master' of https://git-wip-us.apache.org/repos/asf/incubator-rya


Project: http://git-wip-us.apache.org/repos/asf/incubator-rya/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-rya/commit/529f2d59
Tree: http://git-wip-us.apache.org/repos/asf/incubator-rya/tree/529f2d59
Diff: http://git-wip-us.apache.org/repos/asf/incubator-rya/diff/529f2d59

Branch: refs/heads/master
Commit: 529f2d5957b1f6a16a55a6cbea2d550e1d874e7f
Parents: c4d4bfe 4ac4e86
Author: pujav65 <pu...@gmail.com>
Authored: Mon Mar 27 14:09:14 2017 -0400
Committer: pujav65 <pu...@gmail.com>
Committed: Mon Mar 27 14:09:14 2017 -0400

----------------------------------------------------------------------

----------------------------------------------------------------------



[2/4] incubator-rya git commit: RYA-144: Mongo Entity Centric Indexer; Closes #124, #135

Posted by pu...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/BaseEntityIndexer.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/BaseEntityIndexer.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/BaseEntityIndexer.java
index 0bd9261..7da9918 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/BaseEntityIndexer.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/BaseEntityIndexer.java
@@ -32,34 +32,34 @@ import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.atomic.AtomicReference;
 
-import javax.annotation.Nullable;
-import javax.annotation.ParametersAreNonnullByDefault;
-
 import org.apache.hadoop.conf.Configuration;
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.model.Entity;
 import org.apache.rya.indexing.entity.model.Property;
 import org.apache.rya.indexing.entity.model.Type;
-import org.apache.rya.indexing.entity.storage.CloseableIterator;
 import org.apache.rya.indexing.entity.storage.EntityStorage;
-import org.apache.rya.indexing.entity.storage.TypeStorage;
 import org.apache.rya.indexing.entity.storage.EntityStorage.EntityStorageException;
+import org.apache.rya.indexing.entity.storage.TypeStorage;
 import org.apache.rya.indexing.entity.storage.TypeStorage.TypeStorageException;
+import org.apache.rya.indexing.entity.storage.mongo.ConvertingCursor;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.apache.rya.mongodb.MongoSecondaryIndex;
 import org.openrdf.model.URI;
 import org.openrdf.model.vocabulary.RDF;
 
 import com.google.common.base.Objects;
 
-import mvm.rya.api.domain.RyaStatement;
-import mvm.rya.api.domain.RyaType;
-import mvm.rya.api.domain.RyaURI;
-import mvm.rya.mongodb.MongoDBRdfConfiguration;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * A base class that may be used to update an {@link EntityStorage} as new
  * {@link RyaStatement}s are added to/removed from the Rya instance.
  */
-@ParametersAreNonnullByDefault
-public abstract class BaseEntityIndexer implements EntityIndexer {
+@DefaultAnnotation(NonNull.class)
+public abstract class BaseEntityIndexer implements EntityIndexer, MongoSecondaryIndex {
 
     /**
      * When this URI is the Predicate of a Statement, it indicates a {@link Type} for an {@link Entity}.
@@ -70,24 +70,8 @@ public abstract class BaseEntityIndexer implements EntityIndexer {
     private final AtomicReference<EntityStorage> entities = new AtomicReference<>();
     private final AtomicReference<TypeStorage> types = new AtomicReference<>();
 
-    /**
-     * Creates the {@link EntityStorage} that will be used by the indexer.
-     *
-     * @param conf - Indicates how the {@link EntityStorage} is initialized. (not null)
-     * @return The {@link EntityStorage} that will be used by this indexer.
-     */
-    public abstract @Nullable EntityStorage getEntityStorage(Configuration conf);
-
-    /**
-     * Creates the {@link TypeStorage} that will be used by the indexer.
-     *
-     * @param conf - Indicates how the {@link TypeStorage} is initialized. (not null)
-     * @return The {@link TypeStorage} that will be used by this indexer.
-     */
-    public abstract @Nullable TypeStorage getTypeStorage(Configuration conf);
-
     @Override
-    public void setConf(Configuration conf) {
+    public void setConf(final Configuration conf) {
         requireNonNull(conf);
         entities.set( getEntityStorage(conf) );
         types.set( getTypeStorage(conf) );
@@ -99,13 +83,13 @@ public abstract class BaseEntityIndexer implements EntityIndexer {
     }
 
     @Override
-    public void storeStatement(RyaStatement statement) throws IOException {
+    public void storeStatement(final RyaStatement statement) throws IOException {
         requireNonNull(statement);
         storeStatements( singleton(statement) );
     }
 
     @Override
-    public void storeStatements(Collection<RyaStatement> statements) throws IOException {
+    public void storeStatements(final Collection<RyaStatement> statements) throws IOException {
         requireNonNull(statements);
 
         final Map<RyaURI,List<RyaStatement>> groupedBySubject = statements.stream()
@@ -162,7 +146,7 @@ public abstract class BaseEntityIndexer implements EntityIndexer {
                     final RyaURI propertyName = statement.getPredicate();
                     final RyaType propertyValue = statement.getObject();
 
-                    try(final CloseableIterator<Type> typesIt = types.search(propertyName)) {
+                    try(final ConvertingCursor<Type> typesIt = types.search(propertyName)) {
                         // Set the Property for each type that includes the Statement's predicate.
                         while(typesIt.hasNext()) {
                             final RyaURI typeId = typesIt.next().getId();
@@ -180,7 +164,7 @@ public abstract class BaseEntityIndexer implements EntityIndexer {
     }
 
     @Override
-    public void deleteStatement(RyaStatement statement) throws IOException {
+    public void deleteStatement(final RyaStatement statement) throws IOException {
         requireNonNull(statement);
 
         final EntityStorage entities = this.entities.get();
@@ -254,7 +238,7 @@ public abstract class BaseEntityIndexer implements EntityIndexer {
     }
 
     @Override
-    public void dropGraph(RyaURI... graphs) {
+    public void dropGraph(final RyaURI... graphs) {
         // We do not support graphs when performing entity centric indexing.
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/EntityIndexer.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/EntityIndexer.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/EntityIndexer.java
index 9ef5dfd..48cb0b1 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/EntityIndexer.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/EntityIndexer.java
@@ -18,10 +18,13 @@
  */
 package org.apache.rya.indexing.entity.update;
 
+import org.apache.hadoop.conf.Configuration;
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.persist.index.RyaSecondaryIndexer;
 import org.apache.rya.indexing.entity.storage.EntityStorage;
+import org.apache.rya.indexing.entity.storage.TypeStorage;
 
-import mvm.rya.api.domain.RyaStatement;
-import mvm.rya.api.persist.index.RyaSecondaryIndexer;
+import edu.umd.cs.findbugs.annotations.Nullable;
 
 /**
  * Updates the {@link Entity}s that are in a {@link EntityStorage} when new
@@ -29,4 +32,19 @@ import mvm.rya.api.persist.index.RyaSecondaryIndexer;
  */
 public interface EntityIndexer extends RyaSecondaryIndexer {
 
+    /**
+     * Creates the {@link EntityStorage} that will be used by the indexer.
+     *
+     * @param conf - Indicates how the {@link EntityStorage} is initialized. (not null)
+     * @return The {@link EntityStorage} that will be used by this indexer.
+     */
+    public @Nullable EntityStorage getEntityStorage(Configuration conf);
+
+    /**
+     * Creates the {@link TypeStorage} that will be used by the indexer.
+     *
+     * @param conf - Indicates how the {@link TypeStorage} is initialized. (not null)
+     * @return The {@link TypeStorage} that will be used by this indexer.
+     */
+    public @Nullable TypeStorage getTypeStorage(Configuration conf);
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/EntityUpdater.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/EntityUpdater.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/EntityUpdater.java
index 4bb003f..fb5e957 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/EntityUpdater.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/EntityUpdater.java
@@ -23,20 +23,20 @@ import static java.util.Objects.requireNonNull;
 import java.util.Optional;
 import java.util.function.Function;
 
-import javax.annotation.ParametersAreNonnullByDefault;
-
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.model.Entity;
 import org.apache.rya.indexing.entity.storage.EntityStorage;
 import org.apache.rya.indexing.entity.storage.EntityStorage.EntityAlreadyExistsException;
 import org.apache.rya.indexing.entity.storage.EntityStorage.EntityStorageException;
 import org.apache.rya.indexing.entity.storage.EntityStorage.StaleUpdateException;
 
-import mvm.rya.api.domain.RyaURI;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * Performs update operations over an {@link EntityStorage}.
  */
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public class EntityUpdater {
 
     private final EntityStorage storage;
@@ -46,7 +46,7 @@ public class EntityUpdater {
      *
      * @param storage - The storage this updater operates over. (not null)
      */
-    public EntityUpdater(EntityStorage storage) {
+    public EntityUpdater(final EntityStorage storage) {
         this.storage = requireNonNull(storage);
     }
 
@@ -59,7 +59,7 @@ public class EntityUpdater {
      *   the new state of the Entity. (not null)
      * @throws EntityStorageException A non-recoverable error has caused the update to fail.
      */
-    public void update(RyaURI subject, EntityMutator mutator) throws EntityStorageException {
+    public void update(final RyaURI subject, final EntityMutator mutator) throws EntityStorageException {
         requireNonNull(subject);
         requireNonNull(mutator);
 

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/mongo/MongoEntityIndexer.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/mongo/MongoEntityIndexer.java b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/mongo/MongoEntityIndexer.java
index 71b5198..84eebaa 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/mongo/MongoEntityIndexer.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/entity/update/mongo/MongoEntityIndexer.java
@@ -18,8 +18,6 @@
  */
 package org.apache.rya.indexing.entity.update.mongo;
 
-import javax.annotation.ParametersAreNonnullByDefault;
-
 import org.apache.hadoop.conf.Configuration;
 import org.apache.rya.indexing.entity.storage.EntityStorage;
 import org.apache.rya.indexing.entity.storage.TypeStorage;
@@ -27,29 +25,57 @@ import org.apache.rya.indexing.entity.storage.mongo.MongoEntityStorage;
 import org.apache.rya.indexing.entity.storage.mongo.MongoTypeStorage;
 import org.apache.rya.indexing.entity.update.BaseEntityIndexer;
 import org.apache.rya.indexing.entity.update.EntityIndexer;
+import org.apache.rya.mongodb.MongoConnectorFactory;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
 
 import com.mongodb.MongoClient;
 
-import mvm.rya.mongodb.MongoConnectorFactory;
-import mvm.rya.mongodb.MongoDBRdfConfiguration;
+import edu.umd.cs.findbugs.annotations.DefaultAnnotation;
+import edu.umd.cs.findbugs.annotations.NonNull;
 
 /**
  * A Mongo DB implementation of {@link EntityIndexer}.
  */
-@ParametersAreNonnullByDefault
+@DefaultAnnotation(NonNull.class)
 public class MongoEntityIndexer extends BaseEntityIndexer {
+    private MongoClient client;
 
     @Override
-    public EntityStorage getEntityStorage(Configuration conf) {
-        final MongoClient mongoClient = MongoConnectorFactory.getMongoClient(conf);
+    public EntityStorage getEntityStorage(final Configuration conf) {
+        final MongoDBRdfConfiguration mongoConf = (MongoDBRdfConfiguration) conf;
+        if (client == null) {
+            if(mongoConf.getMongoClient() != null) {
+                client = mongoConf.getMongoClient();
+            } else {
+                client = MongoConnectorFactory.getMongoClient(conf);
+            }
+        }
         final String ryaInstanceName = new MongoDBRdfConfiguration(conf).getMongoDBName();
-        return new MongoEntityStorage(mongoClient, ryaInstanceName);
+        return new MongoEntityStorage(client, ryaInstanceName);
     }
 
     @Override
-    public TypeStorage getTypeStorage(Configuration conf) {
-        final MongoClient mongoClient = MongoConnectorFactory.getMongoClient(conf);
+    public TypeStorage getTypeStorage(final Configuration conf) {
+        final MongoDBRdfConfiguration mongoConf = (MongoDBRdfConfiguration) conf;
+        if (client == null) {
+            if(mongoConf.getMongoClient() != null) {
+                client = mongoConf.getMongoClient();
+            } else {
+                client = MongoConnectorFactory.getMongoClient(conf);
+            }
+        }
         final String ryaInstanceName = new MongoDBRdfConfiguration(conf).getMongoDBName();
-        return new MongoTypeStorage(mongoClient, ryaInstanceName);
+        return new MongoTypeStorage(client, ryaInstanceName);
+    }
+
+
+    @Override
+    public void init() {
+        //nothing to init.
+    }
+
+    @Override
+    public void setClient(final MongoClient client) {
+        this.client = client;
     }
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/AbstractExternalSetMatcher.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/AbstractExternalSetMatcher.java b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/AbstractExternalSetMatcher.java
index 65c1c9d..0f34030 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/AbstractExternalSetMatcher.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/AbstractExternalSetMatcher.java
@@ -1,3 +1,21 @@
+/**
+ * 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.external.matching;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -64,7 +82,7 @@ public abstract class AbstractExternalSetMatcher<T extends ExternalSet> implemen
     protected TupleExpr tuple;
     protected Set<TupleExpr> unmatched;
     protected Set<Filter> filters;
-    private QuerySegmentFactory<T> factory = new QuerySegmentFactory<T>();
+    private final QuerySegmentFactory<T> factory = new QuerySegmentFactory<T>();
 
     /**
      * Matches {@link QuerySegment} with underlying QuerySegment. If match
@@ -85,7 +103,7 @@ public abstract class AbstractExternalSetMatcher<T extends ExternalSet> implemen
     /**
      * In following method, order is determined by the order in which the node
      * appear in the query.
-     * 
+     *
      * @return - an ordered view of the QueryModelNodes appearing tuple
      *
      */
@@ -110,14 +128,14 @@ public abstract class AbstractExternalSetMatcher<T extends ExternalSet> implemen
     }
 
     @Override
-    public QuerySegment<T> nodeToQuerySegment(QueryModelNode node) {
+    public QuerySegment<T> nodeToQuerySegment(final QueryModelNode node) {
         return factory.getQuerySegment(node);
     }
 
     @Override
     public List<QueryModelNode> getAllUnmatchedNodes() {
-        List<QueryModelNode> unmatched = new ArrayList<>();
-        for (QueryModelNode node : segmentNodeList) {
+        final List<QueryModelNode> unmatched = new ArrayList<>();
+        for (final QueryModelNode node : segmentNodeList) {
             if (!(node instanceof ExternalSet)) {
                 unmatched.add(node);
             }
@@ -136,8 +154,8 @@ public abstract class AbstractExternalSetMatcher<T extends ExternalSet> implemen
             if (q instanceof UnaryTupleOperator || q instanceof BinaryTupleOperator) {
                 unmatched.add((TupleExpr) q);
             } else if (q instanceof FlattenedOptional) {
-                FlattenedOptional opt = (FlattenedOptional) q;
-                TupleExpr rightArg = opt.getRightArg();
+                final FlattenedOptional opt = (FlattenedOptional) q;
+                final TupleExpr rightArg = opt.getRightArg();
                 if (rightArg instanceof UnaryTupleOperator || rightArg instanceof BinaryTupleOperator) {
                     unmatched.add(rightArg);
                 }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/AbstractExternalSetMatcherFactory.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/AbstractExternalSetMatcherFactory.java b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/AbstractExternalSetMatcherFactory.java
index d4cd2e5..ca7ede4 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/AbstractExternalSetMatcherFactory.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/AbstractExternalSetMatcherFactory.java
@@ -1,3 +1,21 @@
+/**
+ * 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.external.matching;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -28,7 +46,7 @@ import org.openrdf.query.algebra.evaluation.impl.ExternalSet;
  * given query.
  */
 public abstract class AbstractExternalSetMatcherFactory<T extends ExternalSet> {
-    
+
     public ExternalSetMatcher<T> getMatcher(final QuerySegment<T> segment) {
         if(segment instanceof JoinSegment<?>) {
             return getJoinSegmentMatcher((JoinSegment<T>) segment);
@@ -38,9 +56,9 @@ public abstract class AbstractExternalSetMatcherFactory<T extends ExternalSet> {
             throw new IllegalArgumentException("Invalid Segment.");
         }
     }
-    
+
     protected abstract ExternalSetMatcher<T> getJoinSegmentMatcher(JoinSegment<T> segment);
-    
+
     protected abstract ExternalSetMatcher<T> getOptionalJoinSegmentMatcher(OptionalJoinSegment<T> segment);
 
 }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/BasicRater.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/BasicRater.java b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/BasicRater.java
index a26c872..6166d8a 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/BasicRater.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/BasicRater.java
@@ -1,3 +1,21 @@
+/**
+ * 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.external.matching;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/ExternalSetConverter.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/ExternalSetConverter.java b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/ExternalSetConverter.java
index 2e973e9..900e6a8 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/ExternalSetConverter.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/ExternalSetConverter.java
@@ -1,3 +1,21 @@
+/**
+ * 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.external.matching;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -21,10 +39,10 @@ package org.apache.rya.indexing.external.matching;
 import org.openrdf.query.algebra.evaluation.impl.ExternalSet;
 
 public interface ExternalSetConverter<T extends ExternalSet> {
-    
+
     /**
      * Converts the {@link ExternalSet} to a {@link QuerySegment}
-     * 
+     *
      * @param set - ExternalSet to be converted
      * @return QuerySegment derived from ExternalSet
      */

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/ExternalSetProvider.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/ExternalSetProvider.java b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/ExternalSetProvider.java
index 801bb87..e2d6b34 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/ExternalSetProvider.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/ExternalSetProvider.java
@@ -1,3 +1,21 @@
+/**
+ * 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.external.matching;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -32,19 +50,19 @@ public interface ExternalSetProvider<T extends ExternalSet> {
 
     /**
      * Extract all {@link ExternalSet}s from specified QuerySegment.
-     * 
+     *
      * @param segment
      * @return - List of ExternalSets
      */
     public List<T> getExternalSets(QuerySegment<T> segment);
-    
+
     /**
      * Extract an Iterator over Lists of ExternalSets. This allows an ExtenalSetProvider to pass back
      * different combinations of ExternalSets for the purposes of query optimization.
-     * 
+     *
      * @param segment
      * @return - Iterator over different combinations of ExternalSets
      */
     public Iterator<List<T>> getExternalSetCombos(QuerySegment<T> segment);
-    
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/MatcherUtilities.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/MatcherUtilities.java b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/MatcherUtilities.java
index b4a48eb..1f8e287 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/MatcherUtilities.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/MatcherUtilities.java
@@ -1,3 +1,21 @@
+/**
+ * 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.external.matching;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -41,5 +59,5 @@ public class MatcherUtilities {
             return false;
         }
     }
-    
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QueryNodeListRater.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QueryNodeListRater.java b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QueryNodeListRater.java
index 115a12b..e8b1553 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QueryNodeListRater.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QueryNodeListRater.java
@@ -1,3 +1,21 @@
+/**
+ * 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.external.matching;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -24,7 +42,7 @@ import org.openrdf.query.algebra.QueryModelNode;
 
 /**
  * Class used for determining an optimal query plan.  It assigns a score
- * between 0 and 1 to a list of QueryModelNodes.  A lower score indicates 
+ * between 0 and 1 to a list of QueryModelNodes.  A lower score indicates
  * that the List represents a better collection of nodes for building a query
  * plan.  Usually, the specified List is compared to a base List (original query),
  * and the specified List (mutated query) is compared to the original to determine
@@ -33,7 +51,7 @@ import org.openrdf.query.algebra.QueryModelNode;
  *
  */
 public interface QueryNodeListRater {
-    
+
     public double rateQuerySegment(List<QueryModelNode> eNodes);
-    
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QuerySegment.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QuerySegment.java b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QuerySegment.java
index 8603a68..a8f687e 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QuerySegment.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QuerySegment.java
@@ -28,11 +28,12 @@ import org.openrdf.query.algebra.QueryModelNode;
 import org.openrdf.query.algebra.evaluation.impl.ExternalSet;
 
 /**
- * A QuerySegment represents a subset of a query to be compared to PCJs for
+ * A QuerySegment represents a subset of a query to be compared to ExternalSets for
  * query matching. The QuerySegment is represented as a List, where the order of
  * the nodes in the list is determined by a Visitor as it traverses the Segment
  * from top down, visiting right children before left.
  *
+ * @param <T> - The type of ExternalSet that will replace a subset of nodes in this segment.
  */
 public interface QuerySegment<T extends ExternalSet> extends Cloneable{
 
@@ -62,14 +63,13 @@ public interface QuerySegment<T extends ExternalSet> extends Cloneable{
     /**
      * Sets List of {@link QueryModelNode}s representing this QuerySegment to
      * specified list
-     * 
+     *
      * @param nodes
      *            - nodes to set
      */
     public void setNodes(List<QueryModelNode> nodes);
 
     /**
-     *
      * @param nodeToReplace
      *            - QuerySegment representation of ExternalSet T to match with
      *            subset of this QuerySegment

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QuerySegmentFactory.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QuerySegmentFactory.java b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QuerySegmentFactory.java
index 4bf1faf..0c1eb7e 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QuerySegmentFactory.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/external/matching/QuerySegmentFactory.java
@@ -1,3 +1,21 @@
+/**
+ * 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.external.matching;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -33,17 +51,17 @@ import com.google.common.base.Preconditions;
  */
 public class QuerySegmentFactory<T extends ExternalSet> {
 
-    public QuerySegment<T> getQuerySegment(QueryModelNode node) {
+    public QuerySegment<T> getQuerySegment(final QueryModelNode node) {
         Preconditions.checkNotNull(node);
         if(node instanceof Filter) {
-            Filter filter = (Filter)node;
+            final Filter filter = (Filter)node;
             if(MatcherUtilities.segmentContainsLeftJoins(filter)) {
                 return new OptionalJoinSegment<T>(filter);
             } else {
                 return new JoinSegment<T>(filter);
             }
         } else if(node instanceof Join) {
-            Join join = (Join) node;
+            final Join join = (Join) node;
             if(MatcherUtilities.segmentContainsLeftJoins(join)) {
                 return new OptionalJoinSegment<T>(join);
             } else {
@@ -54,7 +72,7 @@ public class QuerySegmentFactory<T extends ExternalSet> {
         } else {
             throw new IllegalArgumentException("Node must be a Join, Filter, or LeftJoin");
         }
-        
+
     }
-    
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/AccumuloIndexSetProvider.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/AccumuloIndexSetProvider.java b/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/AccumuloIndexSetProvider.java
index 641830b..828ee4b 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/AccumuloIndexSetProvider.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/AccumuloIndexSetProvider.java
@@ -1,3 +1,21 @@
+/**
+ * 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.pcj.matching;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -62,7 +80,7 @@ import jline.internal.Preconditions;
  * This provider uses either user specified Accumulo configuration information or user a specified
  * List of ExternalTupleSets to populate an internal cache of ExternalTupleSets.  If Accumulo configuration
  * is provided, the provider connects to an instance of RyaDetails and populates the cache with
- * PCJs registered in RyaDetails.  
+ * PCJs registered in RyaDetails.
  *
  */
 public class AccumuloIndexSetProvider implements ExternalSetProvider<ExternalTupleSet> {
@@ -70,25 +88,25 @@ public class AccumuloIndexSetProvider implements ExternalSetProvider<ExternalTup
     private static final Logger log = Logger.getLogger(ExternalSetProvider.class);
     private static final PCJToSegmentConverter converter = new PCJToSegmentConverter();
     private List<ExternalTupleSet> indexCache;
-    private Configuration conf;
+    private final Configuration conf;
     private boolean init = false;
 
-    public AccumuloIndexSetProvider(Configuration conf) {
+    public AccumuloIndexSetProvider(final Configuration conf) {
         Preconditions.checkNotNull(conf);
         this.conf = conf;
     }
-    
-    public AccumuloIndexSetProvider(Configuration conf, List<ExternalTupleSet> indices) {
+
+    public AccumuloIndexSetProvider(final Configuration conf, final List<ExternalTupleSet> indices) {
         Preconditions.checkNotNull(conf);
         this.conf = conf;
-        this.indexCache = indices;
+        indexCache = indices;
         init = true;
     }
-    
+
     /**
-     * 
+     *
      * @return - size of underlying PCJ cache
-     * @throws Exception 
+     * @throws Exception
      */
     public int size() throws Exception {
         if(!init) {
@@ -103,37 +121,37 @@ public class AccumuloIndexSetProvider implements ExternalSetProvider<ExternalTup
      * @return List of PCJs for matching
      */
     @Override
-    public List<ExternalTupleSet> getExternalSets(QuerySegment<ExternalTupleSet> segment) {
+    public List<ExternalTupleSet> getExternalSets(final QuerySegment<ExternalTupleSet> segment) {
         try {
             if(!init) {
                 indexCache = PCJOptimizerUtilities.getValidPCJs(getAccIndices());
                 init = true;
             }
-            TupleExpr query = segment.getQuery().getTupleExpr();
-            IndexedExecutionPlanGenerator iep = new IndexedExecutionPlanGenerator(query, indexCache);
-            List<ExternalTupleSet> pcjs = iep.getNormalizedIndices();
-            List<ExternalTupleSet> tuples = new ArrayList<>();
-            for (ExternalTupleSet tuple: pcjs) {
-                QuerySegment<ExternalTupleSet> pcj = converter.setToSegment(tuple);
+            final TupleExpr query = segment.getQuery().getTupleExpr();
+            final IndexedExecutionPlanGenerator iep = new IndexedExecutionPlanGenerator(query, indexCache);
+            final List<ExternalTupleSet> pcjs = iep.getNormalizedIndices();
+            final List<ExternalTupleSet> tuples = new ArrayList<>();
+            for (final ExternalTupleSet tuple: pcjs) {
+                final QuerySegment<ExternalTupleSet> pcj = converter.setToSegment(tuple);
                 if (segment.containsQuerySegment(pcj)) {
                     tuples.add(tuple);
                 }
             }
             return tuples;
 
-        } catch (Exception e) {
+        } catch (final Exception e) {
             throw new RuntimeException(e);
         }
     }
-    
+
     /**
-     * @param segment - QuerySegment used to get relevant queries form index cache for matching 
-     * 
+     * @param segment - QuerySegment used to get relevant queries form index cache for matching
+     *
      * @return Iterator of Lists (combos) of PCJs used to build an optimal query plan
      */
     @Override
-    public Iterator<List<ExternalTupleSet>> getExternalSetCombos(QuerySegment<ExternalTupleSet> segment) {
-        ValidIndexCombinationGenerator comboGen = new ValidIndexCombinationGenerator(segment.getOrderedNodes());
+    public Iterator<List<ExternalTupleSet>> getExternalSetCombos(final QuerySegment<ExternalTupleSet> segment) {
+        final ValidIndexCombinationGenerator comboGen = new ValidIndexCombinationGenerator(segment.getOrderedNodes());
         return comboGen.getValidIndexCombos(getExternalSets(segment));
     }
 
@@ -204,8 +222,8 @@ public class AccumuloIndexSetProvider implements ExternalSetProvider<ExternalTup
                 index.add(new AccumuloIndexSet(indexSparqlString, conf, table));
             }
         }
-        
-        
+
+
         return index;
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/PCJExternalSetMatcherFactory.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/PCJExternalSetMatcherFactory.java b/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/PCJExternalSetMatcherFactory.java
index e9bfbbe..c7449f5 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/PCJExternalSetMatcherFactory.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/PCJExternalSetMatcherFactory.java
@@ -1,3 +1,21 @@
+/**
+ * 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.pcj.matching;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -33,12 +51,12 @@ import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet;
 public class PCJExternalSetMatcherFactory extends AbstractExternalSetMatcherFactory<ExternalTupleSet> {
 
     @Override
-    protected ExternalSetMatcher<ExternalTupleSet> getJoinSegmentMatcher(JoinSegment<ExternalTupleSet> segment) {
+    protected ExternalSetMatcher<ExternalTupleSet> getJoinSegmentMatcher(final JoinSegment<ExternalTupleSet> segment) {
         return new JoinSegmentMatcher<ExternalTupleSet>(segment, new PCJToSegmentConverter());
     }
 
     @Override
-    protected ExternalSetMatcher<ExternalTupleSet> getOptionalJoinSegmentMatcher(OptionalJoinSegment<ExternalTupleSet> segment) {
+    protected ExternalSetMatcher<ExternalTupleSet> getOptionalJoinSegmentMatcher(final OptionalJoinSegment<ExternalTupleSet> segment) {
         return new OptionalJoinSegmentMatcher<ExternalTupleSet>(segment, new PCJToSegmentConverter());
     }
 

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/PCJToSegmentConverter.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/PCJToSegmentConverter.java b/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/PCJToSegmentConverter.java
index 61d6204..5744f41 100644
--- a/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/PCJToSegmentConverter.java
+++ b/extras/indexing/src/main/java/org/apache/rya/indexing/pcj/matching/PCJToSegmentConverter.java
@@ -1,3 +1,21 @@
+/**
+ * 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.pcj.matching;
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -33,17 +51,17 @@ import com.google.common.base.Preconditions;
 
 /**
  * Implementation of {@link ExternalSetConverter} to convert {@link ExternalTupleSet}s
- * to {@link QuerySegment}s. 
+ * to {@link QuerySegment}s.
  *
  */
 public class PCJToSegmentConverter implements ExternalSetConverter<ExternalTupleSet> {
 
     private static final PCJToOptionalJoinSegment optional = new PCJToOptionalJoinSegment();
     private static final PCJToJoinSegment join = new PCJToJoinSegment();
-    
-    
+
+
     @Override
-    public QuerySegment<ExternalTupleSet> setToSegment(ExternalTupleSet set) {
+    public QuerySegment<ExternalTupleSet> setToSegment(final ExternalTupleSet set) {
         Preconditions.checkNotNull(set);
         if (PCJOptimizerUtilities.tupleContainsLeftJoins(set.getTupleExpr())) {
             return optional.getSegment(set);
@@ -60,10 +78,10 @@ public class PCJToSegmentConverter implements ExternalSetConverter<ExternalTuple
     static class PCJToJoinSegment extends QueryModelVisitorBase<RuntimeException> {
 
         private JoinSegment<ExternalTupleSet> segment;
-        
+
         private PCJToJoinSegment(){};
 
-        public QuerySegment<ExternalTupleSet> getSegment(ExternalTupleSet pcj) {
+        public QuerySegment<ExternalTupleSet> getSegment(final ExternalTupleSet pcj) {
             segment = null;
             pcj.getTupleExpr().visit(this);
             return segment;
@@ -88,10 +106,10 @@ public class PCJToSegmentConverter implements ExternalSetConverter<ExternalTuple
     static class PCJToOptionalJoinSegment extends QueryModelVisitorBase<RuntimeException> {
 
         private OptionalJoinSegment<ExternalTupleSet> segment;
-        
+
         private PCJToOptionalJoinSegment(){};
 
-        public QuerySegment<ExternalTupleSet> getSegment(ExternalTupleSet pcj) {
+        public QuerySegment<ExternalTupleSet> getSegment(final ExternalTupleSet pcj) {
             segment = null;
             pcj.getTupleExpr().visit(this);
             return segment;

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/main/java/org/apache/rya/sail/config/RyaSailFactory.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/main/java/org/apache/rya/sail/config/RyaSailFactory.java b/extras/indexing/src/main/java/org/apache/rya/sail/config/RyaSailFactory.java
index 8b1ee15..68f1394 100644
--- a/extras/indexing/src/main/java/org/apache/rya/sail/config/RyaSailFactory.java
+++ b/extras/indexing/src/main/java/org/apache/rya/sail/config/RyaSailFactory.java
@@ -29,13 +29,6 @@ import org.apache.accumulo.core.client.Connector;
 import org.apache.accumulo.core.client.Instance;
 import org.apache.accumulo.core.client.security.tokens.PasswordToken;
 import org.apache.hadoop.conf.Configuration;
-import org.openrdf.sail.Sail;
-import org.openrdf.sail.SailException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.mongodb.MongoClient;
-
 import org.apache.rya.accumulo.AccumuloRdfConfiguration;
 import org.apache.rya.accumulo.AccumuloRyaDAO;
 import org.apache.rya.accumulo.instance.AccumuloRyaInstanceDetailsRepository;
@@ -53,6 +46,12 @@ import org.apache.rya.mongodb.instance.MongoRyaInstanceDetailsRepository;
 import org.apache.rya.rdftriplestore.RdfCloudTripleStore;
 import org.apache.rya.rdftriplestore.inference.InferenceEngine;
 import org.apache.rya.rdftriplestore.inference.InferenceEngineException;
+import org.openrdf.sail.Sail;
+import org.openrdf.sail.SailException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.mongodb.MongoClient;
 
 public class RyaSailFactory {
     private static final Logger LOG = LoggerFactory.getLogger(RyaSailFactory.class);
@@ -90,7 +89,8 @@ public class RyaSailFactory {
                 RyaDetailsToConfiguration.addRyaDetailsToConfiguration(ryaDetailsRepo.getRyaInstanceDetails(), mongoConfig);
             } catch (final RyaDetailsRepositoryException e) {
                LOG.info("Instance does not have a rya details collection, skipping.");
-           }            dao = getMongoDAO((MongoDBRdfConfiguration)rdfConfig, client);
+           }
+            dao = getMongoDAO((MongoDBRdfConfiguration)rdfConfig, client);
         } else {
             rdfConfig = new AccumuloRdfConfiguration(config);
             user = rdfConfig.get(ConfigUtils.CLOUDBASE_USER);
@@ -139,7 +139,7 @@ public class RyaSailFactory {
         dao.setConnector(connector);
 
         ConfigUtils.setIndexers(config);
-        
+
         dao.setConf(config);
         dao.init();
         return dao;

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/test/java/org/apache/rya/indexing/entity/query/EntityQueryNodeTest.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/query/EntityQueryNodeTest.java b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/query/EntityQueryNodeTest.java
index 9446d85..d2d9a54 100644
--- a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/query/EntityQueryNodeTest.java
+++ b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/query/EntityQueryNodeTest.java
@@ -18,23 +18,37 @@
  */
 package org.apache.rya.indexing.entity.query;
 
+import static org.junit.Assert.assertEquals;
+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.api.resolver.RdfToRyaConversions;
+import org.apache.rya.indexing.entity.model.Entity;
+import org.apache.rya.indexing.entity.model.Property;
 import org.apache.rya.indexing.entity.model.Type;
-import org.apache.rya.indexing.entity.query.EntityQueryNode;
 import org.apache.rya.indexing.entity.storage.EntityStorage;
+import org.apache.rya.indexing.entity.storage.mongo.MongoEntityStorage;
+import org.apache.rya.mongodb.MockMongoFactory;
 import org.junit.Test;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.ValueFactoryImpl;
 import org.openrdf.model.vocabulary.RDF;
+import org.openrdf.query.BindingSet;
 import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.QueryEvaluationException;
 import org.openrdf.query.algebra.StatementPattern;
 import org.openrdf.query.algebra.helpers.StatementPatternCollector;
+import org.openrdf.query.impl.MapBindingSet;
 import org.openrdf.query.parser.sparql.SPARQLParser;
 
 import com.google.common.collect.ImmutableSet;
+import com.mongodb.MongoClient;
 
-import mvm.rya.api.domain.RyaURI;
+import info.aduna.iteration.CloseableIteration;
 
 /**
  * Unit tests the methods of {@link EntityQueryNode}.
@@ -136,16 +150,21 @@ public class EntityQueryNodeTest {
         new EntityQueryNode(EMPLOYEE_TYPE, patterns, mock(EntityStorage.class));
     }
 
-    // Happy path test.
-
-    // TODO test for all of the types of preconditions
-    //      test when a binding set can join
-    //      test when a binding set does not join
-    //      test when there are constants that are part of the query
-    //      test when there are variables that are part of the query.
-
     @Test
     public void evaluate_constantSubject() throws Exception {
+        final MongoClient client = MockMongoFactory.newFactory().newMongoClient();
+        final EntityStorage storage = new MongoEntityStorage(client, "testDB");
+        final ValueFactory vf = ValueFactoryImpl.getInstance();
+        final RyaURI subject = new RyaURI("urn:SSN:111-11-1111");
+        final Entity entity = Entity.builder()
+            .setSubject(subject)
+            .setExplicitType(PERSON_TYPE.getId())
+            .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:age"), RdfToRyaConversions.convertLiteral(vf.createLiteral(20))))
+            .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:eye"), RdfToRyaConversions.convertLiteral(vf.createLiteral("blue"))))
+            .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:name"), RdfToRyaConversions.convertLiteral(vf.createLiteral("Bob"))))
+            .build();
+
+        storage.create(entity);
         // A set of patterns that match a sepecific Entity subject.
         final List<StatementPattern> patterns = getSPs(
                 "SELECT * WHERE { " +
@@ -155,30 +174,107 @@ public class EntityQueryNodeTest {
                     "<urn:SSN:111-11-1111> <urn:name> ?name . " +
                 "}");
 
-        new EntityQueryNode(PERSON_TYPE, patterns, mock(EntityStorage.class));
-
-
-        // TODO implement
+        final EntityQueryNode node = new EntityQueryNode(PERSON_TYPE, patterns, storage);
+        final CloseableIteration<BindingSet, QueryEvaluationException> rez = node.evaluate(new MapBindingSet());
+        final MapBindingSet expected = new MapBindingSet();
+        expected.addBinding("age", vf.createLiteral("20"));
+        expected.addBinding("eye", vf.createLiteral("blue"));
+        expected.addBinding("name", vf.createLiteral("Bob"));
+        while(rez.hasNext()) {
+            assertEquals(expected, rez.next());
+            break;
+        }
     }
 
     @Test
     public void evaluate_variableSubject() throws Exception {
-        // A set of patterns that matches a variable Entity subject.
+        final MongoClient client = MockMongoFactory.newFactory().newMongoClient();
+        final EntityStorage storage = new MongoEntityStorage(client, "testDB");
+        final ValueFactory vf = ValueFactoryImpl.getInstance();
+        RyaURI subject = new RyaURI("urn:SSN:111-11-1111");
+        final Entity bob = Entity.builder()
+                .setSubject(subject)
+                .setExplicitType(PERSON_TYPE.getId())
+                .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:age"), RdfToRyaConversions.convertLiteral(vf.createLiteral(20))))
+                .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:eye"), RdfToRyaConversions.convertLiteral(vf.createLiteral("blue"))))
+                .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:name"), RdfToRyaConversions.convertLiteral(vf.createLiteral("Bob"))))
+                .build();
+
+        subject = new RyaURI("urn:SSN:222-22-2222");
+        final Entity fred = Entity.builder()
+                .setSubject(subject)
+                .setExplicitType(PERSON_TYPE.getId())
+                .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:age"), RdfToRyaConversions.convertLiteral(vf.createLiteral(25))))
+                .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:eye"), RdfToRyaConversions.convertLiteral(vf.createLiteral("brown"))))
+                .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:name"), RdfToRyaConversions.convertLiteral(vf.createLiteral("Fred"))))
+                .build();
+
+        storage.create(bob);
+        storage.create(fred);
+        // A set of patterns that match a sepecific Entity subject.
         final List<StatementPattern> patterns = getSPs(
                 "SELECT * WHERE { " +
-                    "?subject <" + RDF.TYPE + "> <urn:person> ."+
-                    "?subject <urn:age> ?age . " +
-                    "?subject <urn:eye> ?eye . " +
-                    "?subject <urn:name> ?name . " +
+                    "?ssn <" + RDF.TYPE + "> <urn:person> ."+
+                    "?ssn <urn:age> ?age . " +
+                    "?ssn <urn:eye> ?eye . " +
+                    "?ssn <urn:name> ?name . " +
                 "}");
 
-        new EntityQueryNode(PERSON_TYPE, patterns, mock(EntityStorage.class));
-
-
-        // TODO implement
+        final EntityQueryNode node = new EntityQueryNode(PERSON_TYPE, patterns, storage);
+        final CloseableIteration<BindingSet, QueryEvaluationException> rez = node.evaluate(new MapBindingSet());
+        final List<BindingSet> expectedBindings = new ArrayList<>();
+        final MapBindingSet expectedBob = new MapBindingSet();
+        expectedBob.addBinding("age", vf.createLiteral("20"));
+        expectedBob.addBinding("eye", vf.createLiteral("blue"));
+        expectedBob.addBinding("name", vf.createLiteral("Bob"));
+
+        final MapBindingSet expectedFred = new MapBindingSet();
+        expectedFred.addBinding("age", vf.createLiteral("25"));
+        expectedFred.addBinding("eye", vf.createLiteral("brown"));
+        expectedFred.addBinding("name", vf.createLiteral("Fred"));
+        expectedBindings.add(expectedBob);
+        expectedBindings.add(expectedFred);
+        while(rez.hasNext()) {
+            final BindingSet bs = rez.next();
+            assertTrue(expectedBindings.contains(bs));
+        }
     }
 
+    @Test
+    public void evaluate_constantObject() throws Exception {
+        final MongoClient client = MockMongoFactory.newFactory().newMongoClient();
+        final EntityStorage storage = new MongoEntityStorage(client, "testDB");
+        final ValueFactory vf = ValueFactoryImpl.getInstance();
+        final RyaURI subject = new RyaURI("urn:SSN:111-11-1111");
+        final Entity entity = Entity.builder()
+            .setSubject(subject)
+            .setExplicitType(PERSON_TYPE.getId())
+            .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:age"), RdfToRyaConversions.convertLiteral(vf.createLiteral(20))))
+            .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:eye"), RdfToRyaConversions.convertLiteral(vf.createLiteral("blue"))))
+            .setProperty(PERSON_TYPE.getId(), new Property(new RyaURI("urn:name"), RdfToRyaConversions.convertLiteral(vf.createLiteral("Bob"))))
+            .build();
+
+        storage.create(entity);
+        // A set of patterns that match a sepecific Entity subject.
+        final List<StatementPattern> patterns = getSPs(
+                "SELECT * WHERE { " +
+                    "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                    "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                    "<urn:SSN:111-11-1111> <urn:eye> \"blue\" . " +
+                    "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+                "}");
 
+        final EntityQueryNode node = new EntityQueryNode(PERSON_TYPE, patterns, storage);
+        final CloseableIteration<BindingSet, QueryEvaluationException> rez = node.evaluate(new MapBindingSet());
+        final MapBindingSet expected = new MapBindingSet();
+        expected.addBinding("age", vf.createLiteral("20"));
+        expected.addBinding("-const-blue", vf.createLiteral("blue"));
+        expected.addBinding("name", vf.createLiteral("Bob"));
+        while(rez.hasNext()) {
+            assertEquals(expected, rez.next());
+            break;
+        }
+    }
 
     /**
      * TODO doc
@@ -187,7 +283,7 @@ public class EntityQueryNodeTest {
      * @return
      * @throws MalformedQueryException
      */
-    private static List<StatementPattern> getSPs(String sparql) throws MalformedQueryException {
+    private static List<StatementPattern> getSPs(final String sparql) throws MalformedQueryException {
         final StatementPatternCollector spCollector = new StatementPatternCollector();
         new SPARQLParser().parseQuery(sparql, null).getTupleExpr().visit(spCollector);
         return spCollector.getStatementPatterns();

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/EntityDocumentConverterTest.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/EntityDocumentConverterTest.java b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/EntityDocumentConverterTest.java
index 9b8cb66..79ea998 100644
--- a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/EntityDocumentConverterTest.java
+++ b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/EntityDocumentConverterTest.java
@@ -20,17 +20,15 @@ package org.apache.rya.indexing.entity.storage.mongo;
 
 import static org.junit.Assert.assertEquals;
 
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.model.Entity;
 import org.apache.rya.indexing.entity.model.Property;
-import org.apache.rya.indexing.entity.storage.mongo.EntityDocumentConverter;
 import org.apache.rya.indexing.entity.storage.mongo.DocumentConverter.DocumentConverterException;
 import org.bson.Document;
 import org.junit.Test;
 import org.openrdf.model.vocabulary.XMLSchema;
 
-import mvm.rya.api.domain.RyaType;
-import mvm.rya.api.domain.RyaURI;
-
 /**
  * Tests the methods of {@link EntityDocumentConverter}.
  */

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoEntityStorageIT.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoEntityStorageIT.java b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoEntityStorageIT.java
index 1269d20..d271ba0 100644
--- a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoEntityStorageIT.java
+++ b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoEntityStorageIT.java
@@ -26,25 +26,22 @@ import java.util.HashSet;
 import java.util.Optional;
 import java.util.Set;
 
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.model.Entity;
 import org.apache.rya.indexing.entity.model.Property;
 import org.apache.rya.indexing.entity.model.Type;
 import org.apache.rya.indexing.entity.model.TypedEntity;
-import org.apache.rya.indexing.entity.storage.CloseableIterator;
 import org.apache.rya.indexing.entity.storage.EntityStorage;
 import org.apache.rya.indexing.entity.storage.EntityStorage.EntityAlreadyExistsException;
 import org.apache.rya.indexing.entity.storage.EntityStorage.EntityStorageException;
 import org.apache.rya.indexing.entity.storage.EntityStorage.StaleUpdateException;
-import org.apache.rya.indexing.entity.storage.mongo.MongoEntityStorage;
 import org.junit.Test;
 import org.openrdf.model.vocabulary.XMLSchema;
 
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 
-import mvm.rya.api.domain.RyaType;
-import mvm.rya.api.domain.RyaURI;
-
 /**
  * Integration tests the methods of {@link MongoEntityStorage}.
  */
@@ -198,7 +195,7 @@ public class MongoEntityStorageIT extends MongoITBase {
 
         // Search for all icecreams.
         final Set<TypedEntity> objects = new HashSet<>();
-        try(final CloseableIterator<TypedEntity> it = storage.search(icecreamType, new HashSet<>())) {
+        try(final ConvertingCursor<TypedEntity> it = storage.search(Optional.empty(), icecreamType, new HashSet<>())) {
             while(it.hasNext()) {
                 objects.add(it.next());
             }
@@ -295,7 +292,7 @@ public class MongoEntityStorageIT extends MongoITBase {
                 new Property(new RyaURI("urn:eye"), new RyaType(XMLSchema.STRING, "blue")),
                 new Property(new RyaURI("urn:age"), new RyaType(XMLSchema.INT, "30")));
 
-        try(final CloseableIterator<TypedEntity> it = storage.search(personType, searchValues)) {
+        try(final ConvertingCursor<TypedEntity> it = storage.search(Optional.empty(), personType, searchValues)) {
             while(it.hasNext()) {
                 objects.add(it.next());
             }

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoITBase.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoITBase.java b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoITBase.java
index 9894ee5..692d1aa 100644
--- a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoITBase.java
+++ b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoITBase.java
@@ -18,20 +18,18 @@
  */
 package org.apache.rya.indexing.entity.storage.mongo;
 
-import java.net.UnknownHostException;
 import java.util.HashSet;
 import java.util.Set;
 
 import org.apache.hadoop.conf.Configuration;
+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;
-import com.mongodb.MongoException;
-
-import mvm.rya.mongodb.MongoConnectorFactory;
-import mvm.rya.mongodb.MongoDBRdfConfiguration;
 
 /**
  * A base class that may be used when implementing Mongo DB integration tests that
@@ -41,14 +39,15 @@ public class MongoITBase {
 
     private MongoClient mongoClient = null;
     private Set<String> originalDbNames = null;
+    protected MongoDBRdfConfiguration conf;
 
     @Before
-    public void setupTest() throws UnknownHostException, MongoException {
-        final MongoDBRdfConfiguration conf = new MongoDBRdfConfiguration( new Configuration() );
-        conf.setUseTestMongo(true);
+    public void setupTest() throws Exception {
+        conf = new MongoDBRdfConfiguration( new Configuration() );
         conf.setMongoDBName("testDB");
+        mongoClient = MockMongoFactory.newFactory().newMongoClient();
+        conf.setMongoClient(mongoClient);
 
-        mongoClient = MongoConnectorFactory.getMongoClient(conf);
 
         // Store the names of the DBs that are present before running the test.
         originalDbNames = new HashSet<>();
@@ -69,7 +68,7 @@ public class MongoITBase {
 
     @AfterClass
     public static void shutdown() {
-        MongoConnectorFactory.shutdown();
+        MongoConnectorFactory.closeMongoClient();
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoTypeStorageIT.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoTypeStorageIT.java b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoTypeStorageIT.java
index 2b4c849..56c10c0 100644
--- a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoTypeStorageIT.java
+++ b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/MongoTypeStorageIT.java
@@ -23,21 +23,18 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import java.util.HashSet;
+import java.util.Optional;
 import java.util.Set;
 
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.model.Type;
-import org.apache.rya.indexing.entity.storage.CloseableIterator;
 import org.apache.rya.indexing.entity.storage.TypeStorage;
 import org.apache.rya.indexing.entity.storage.TypeStorage.TypeStorageException;
-import org.apache.rya.indexing.entity.storage.mongo.MongoTypeStorage;
 import org.junit.Test;
 
-import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 
-import mvm.rya.api.domain.RyaURI;
-
 /**
  * Integration tests the methods of {@link MongoTypeStorage}.
  */
@@ -161,7 +158,7 @@ public class MongoTypeStorageIT extends MongoITBase {
         storage.create(icecream);
 
         // Search for all Types that have the 'urn:eye' property.
-        final CloseableIterator<Type> typeIt = storage.search(new RyaURI("urn:eye"));
+        final ConvertingCursor<Type> typeIt = storage.search(new RyaURI("urn:eye"));
 
         final Set<Type> types = new HashSet<>();
         while(typeIt.hasNext()) {

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/RyaTypeDocumentConverterTest.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/RyaTypeDocumentConverterTest.java b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/RyaTypeDocumentConverterTest.java
index 35c7968..3196793 100644
--- a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/RyaTypeDocumentConverterTest.java
+++ b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/RyaTypeDocumentConverterTest.java
@@ -20,16 +20,14 @@ package org.apache.rya.indexing.entity.storage.mongo;
 
 import static org.junit.Assert.assertEquals;
 
-import org.apache.rya.indexing.entity.storage.mongo.RyaTypeDocumentConverter;
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.resolver.RdfToRyaConversions;
 import org.apache.rya.indexing.entity.storage.mongo.DocumentConverter.DocumentConverterException;
 import org.bson.Document;
 import org.junit.Test;
 import org.openrdf.model.impl.ValueFactoryImpl;
 import org.openrdf.model.vocabulary.XMLSchema;
 
-import mvm.rya.api.domain.RyaType;
-import mvm.rya.api.resolver.RdfToRyaConversions;
-
 /**
  * Tests the methods of {@link RyaTypeDocumentConverter}.
  */

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/TypeDocumentConverterTest.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/TypeDocumentConverterTest.java b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/TypeDocumentConverterTest.java
index 9d854cf..4c795c2 100644
--- a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/TypeDocumentConverterTest.java
+++ b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/storage/mongo/TypeDocumentConverterTest.java
@@ -20,8 +20,8 @@ package org.apache.rya.indexing.entity.storage.mongo;
 
 import static org.junit.Assert.assertEquals;
 
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.model.Type;
-import org.apache.rya.indexing.entity.storage.mongo.TypeDocumentConverter;
 import org.apache.rya.indexing.entity.storage.mongo.DocumentConverter.DocumentConverterException;
 import org.bson.Document;
 import org.junit.Test;
@@ -29,8 +29,6 @@ import org.junit.Test;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
 
-import mvm.rya.api.domain.RyaURI;
-
 /**
  * Tests the methods of {@link TypeDocumentConverter}.
  */

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/c4d4bfe7/extras/indexing/src/test/java/org/apache/rya/indexing/entity/update/mongo/MongoEntityIndexerIT.java
----------------------------------------------------------------------
diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/update/mongo/MongoEntityIndexerIT.java b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/update/mongo/MongoEntityIndexerIT.java
index 1fc3f72..a33ddd4 100644
--- a/extras/indexing/src/test/java/org/apache/rya/indexing/entity/update/mongo/MongoEntityIndexerIT.java
+++ b/extras/indexing/src/test/java/org/apache/rya/indexing/entity/update/mongo/MongoEntityIndexerIT.java
@@ -22,7 +22,9 @@ import static org.junit.Assert.assertEquals;
 
 import java.util.Set;
 
-import org.apache.hadoop.conf.Configuration;
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
 import org.apache.rya.indexing.entity.model.Entity;
 import org.apache.rya.indexing.entity.model.Property;
 import org.apache.rya.indexing.entity.model.Type;
@@ -31,8 +33,7 @@ import org.apache.rya.indexing.entity.storage.TypeStorage;
 import org.apache.rya.indexing.entity.storage.mongo.MongoEntityStorage;
 import org.apache.rya.indexing.entity.storage.mongo.MongoITBase;
 import org.apache.rya.indexing.entity.storage.mongo.MongoTypeStorage;
-import org.apache.rya.indexing.entity.update.EntityIndexer;
-import org.apache.rya.indexing.entity.update.mongo.MongoEntityIndexer;
+import org.junit.Before;
 import org.junit.Test;
 import org.openrdf.model.vocabulary.RDF;
 import org.openrdf.model.vocabulary.XMLSchema;
@@ -40,17 +41,12 @@ import org.openrdf.model.vocabulary.XMLSchema;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Sets;
 
-import mvm.rya.api.domain.RyaStatement;
-import mvm.rya.api.domain.RyaType;
-import mvm.rya.api.domain.RyaURI;
-import mvm.rya.mongodb.MongoDBRdfConfiguration;
-
 /**
  * Integration tests the methods of {@link MongoEntityIndexer}.
  */
 public class MongoEntityIndexerIT extends MongoITBase {
 
-    private static final String RYA_INSTANCE_NAME = "testInstance";
+    private static final String RYA_INSTANCE_NAME = "testDB";
 
     private static final Type PERSON_TYPE =
             new Type(new RyaURI("urn:person"),
@@ -67,6 +63,16 @@ public class MongoEntityIndexerIT extends MongoITBase {
                     .add(new RyaURI("urn:hoursPerWeek"))
                     .build());
 
+    private MongoEntityIndexer indexer;
+
+    @Before
+    public void setup() {
+        indexer = new MongoEntityIndexer();
+        indexer.setClient(getMongoClient());
+        indexer.setConf(conf);
+        indexer.init();
+    }
+
     @Test
     public void addStatement_setsType() throws Exception {
         // Load a type into the TypeStorage.
@@ -74,7 +80,6 @@ public class MongoEntityIndexerIT extends MongoITBase {
         types.create(PERSON_TYPE);
 
         // Index a RyaStatement that will create an Entity with an explicit type.
-        final EntityIndexer indexer = makeTestIndexer();
         final RyaStatement statement = new RyaStatement(new RyaURI("urn:SSN/111-11-1111"), new RyaURI( RDF.TYPE.toString() ), new RyaType(XMLSchema.ANYURI, "urn:person"));
         indexer.storeStatement(statement);
 
@@ -98,7 +103,6 @@ public class MongoEntityIndexerIT extends MongoITBase {
         types.create(EMPLOYEE_TYPE);
 
         // Index a RyaStatement that will create an Entity with two implicit types.
-        final EntityIndexer indexer = makeTestIndexer();
         final RyaStatement statement = new RyaStatement(new RyaURI("urn:SSN/111-11-1111"), new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "Alice"));
         indexer.storeStatement(statement);
 
@@ -123,8 +127,6 @@ public class MongoEntityIndexerIT extends MongoITBase {
         types.create(EMPLOYEE_TYPE);
 
         // Index a bunch of RyaStatements.
-        final EntityIndexer indexer = makeTestIndexer();
-
         final RyaURI aliceSSN = new RyaURI("urn:SSN/111-11-1111");
         indexer.storeStatement(new RyaStatement(aliceSSN, new RyaURI( RDF.TYPE.toString() ), new RyaType(XMLSchema.ANYURI, "urn:person")));
         indexer.storeStatement(new RyaStatement(aliceSSN, new RyaURI("urn:name"), new RyaType(XMLSchema.STRING, "Alice")));
@@ -156,8 +158,6 @@ public class MongoEntityIndexerIT extends MongoITBase {
         types.create(EMPLOYEE_TYPE);
 
         // Index a bunch of RyaStatements.
-        final EntityIndexer indexer = makeTestIndexer();
-
         final RyaURI aliceSSN = new RyaURI("urn:SSN/111-11-1111");
         final RyaURI bobSSN = new RyaURI("urn:SSN/222-22-2222");
 
@@ -208,8 +208,6 @@ public class MongoEntityIndexerIT extends MongoITBase {
         types.create(EMPLOYEE_TYPE);
 
         // Index a bunch of RyaStatements.
-        final EntityIndexer indexer = makeTestIndexer();
-
         final RyaURI aliceSSN = new RyaURI("urn:SSN/111-11-1111");
 
         indexer.storeStatements(Sets.newHashSet(
@@ -245,8 +243,6 @@ public class MongoEntityIndexerIT extends MongoITBase {
         types.create(EMPLOYEE_TYPE);
 
         // Index a bunch of RyaStatements.
-        final EntityIndexer indexer = makeTestIndexer();
-
         final RyaURI aliceSSN = new RyaURI("urn:SSN/111-11-1111");
 
         indexer.storeStatements(Sets.newHashSet(
@@ -272,15 +268,4 @@ public class MongoEntityIndexerIT extends MongoITBase {
 
         assertEquals(expected, entity);
     }
-
-    private static EntityIndexer makeTestIndexer() {
-        final EntityIndexer indexer = new MongoEntityIndexer();
-
-        final MongoDBRdfConfiguration conf = new MongoDBRdfConfiguration( new Configuration() );
-        conf.setUseTestMongo(true);
-        conf.setMongoDBName(RYA_INSTANCE_NAME);
-
-        indexer.setConf(conf);
-        return indexer;
-    }
 }
\ No newline at end of file