http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/PCJNodeConsolidatorTest.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/PCJNodeConsolidatorTest.java b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/PCJNodeConsolidatorTest.java index 2fcb8ce..607e072 100644 --- a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/PCJNodeConsolidatorTest.java +++ b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/PCJNodeConsolidatorTest.java @@ -20,6 +20,12 @@ package org.apache.rya.indexing.pcj.matching; import java.util.ArrayList; import java.util.List; +import org.apache.rya.indexing.external.matching.OptionalJoinSegment; +import org.apache.rya.indexing.external.matching.QueryNodeConsolidator; +import org.apache.rya.indexing.external.matching.QuerySegment; +import org.apache.rya.indexing.external.matching.QuerySegmentFactory; +import org.apache.rya.indexing.external.matching.TopOfQueryFilterRelocator; +import org.apache.rya.indexing.external.tupleSet.ExternalTupleSet; import org.junit.Assert; import org.junit.Test; import org.openrdf.query.algebra.Filter; @@ -33,6 +39,7 @@ import org.openrdf.query.parser.sparql.SPARQLParser; public class PCJNodeConsolidatorTest { + private final QuerySegmentFactory<ExternalTupleSet> qFactory = new QuerySegmentFactory<ExternalTupleSet>(); @Test public void testBasicOptionalWithFilter() throws Exception { @@ -66,10 +73,10 @@ public class PCJNodeConsolidatorTest { Filter filter1 = (Filter) ((Projection) te1).getArg(); Filter filter2 = (Filter) ((Projection) te2).getArg(); - OptionalJoinSegment seg1 = new OptionalJoinSegment(filter1); - OptionalJoinSegment seg2 = new OptionalJoinSegment(filter2); - - PCJNodeConsolidator consolidator = new PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); + QuerySegment<ExternalTupleSet> seg1 = qFactory.getQuerySegment(filter1); + QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(filter2); + + QueryNodeConsolidator consolidator = new QueryNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); List<QueryModelNode> queryNodes = new ArrayList<>(seg1.getOrderedNodes()); QueryModelNode node = queryNodes.remove(0); @@ -114,10 +121,10 @@ public class PCJNodeConsolidatorTest { Join join1 = (Join) ((Projection) te1).getArg(); Join join2 = (Join) ((Projection) te2).getArg(); - OptionalJoinSegment seg1 = new OptionalJoinSegment(join1); - OptionalJoinSegment seg2 = new OptionalJoinSegment(join2); - - PCJNodeConsolidator consolidator = new PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); + QuerySegment<ExternalTupleSet> seg1 = qFactory.getQuerySegment(join1); + QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(join2); + + QueryNodeConsolidator consolidator = new QueryNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); List<QueryModelNode> queryNodes = new ArrayList<>(seg1.getOrderedNodes()); QueryModelNode node = queryNodes.remove(0); @@ -163,10 +170,10 @@ public class PCJNodeConsolidatorTest { LeftJoin join1 = (LeftJoin) ((Projection) te1).getArg(); Join join2 = (Join) ((Projection) te2).getArg(); - OptionalJoinSegment seg1 = new OptionalJoinSegment(join1); - OptionalJoinSegment seg2 = new OptionalJoinSegment(join2); + QuerySegment<ExternalTupleSet> seg1 = qFactory.getQuerySegment(join1); + QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(join2); - PCJNodeConsolidator consolidator = new PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); + QueryNodeConsolidator consolidator = new QueryNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); List<QueryModelNode> queryNodes = new ArrayList<>(seg1.getOrderedNodes()); Assert.assertTrue(consolidator.consolidateNodes()); @@ -205,10 +212,10 @@ public class PCJNodeConsolidatorTest { Join join1 = (Join) ((Projection) te1).getArg(); LeftJoin join2 = (LeftJoin) ((Projection) te2).getArg(); - OptionalJoinSegment seg1 = new OptionalJoinSegment(join1); - OptionalJoinSegment seg2 = new OptionalJoinSegment(join2); + QuerySegment<ExternalTupleSet> seg1 = qFactory.getQuerySegment(join1); + QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(join2); - PCJNodeConsolidator consolidator = new PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); + QueryNodeConsolidator consolidator = new QueryNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); Assert.assertTrue(!consolidator.consolidateNodes()); } @@ -243,10 +250,10 @@ public class PCJNodeConsolidatorTest { Join join1 = (Join) ((Projection) te1).getArg(); Join join2 = (Join) ((Projection) te2).getArg(); - OptionalJoinSegment seg1 = new OptionalJoinSegment(join1); - OptionalJoinSegment seg2 = new OptionalJoinSegment(join2); + QuerySegment<ExternalTupleSet> seg1 = qFactory.getQuerySegment(join1); + QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(join2); - PCJNodeConsolidator consolidator = new PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); + QueryNodeConsolidator consolidator = new QueryNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); Assert.assertTrue(!consolidator.consolidateNodes()); } @@ -281,10 +288,10 @@ public class PCJNodeConsolidatorTest { Join join1 = (Join) ((Projection) te1).getArg(); Join join2 = (Join) ((Projection) te2).getArg(); - OptionalJoinSegment seg1 = new OptionalJoinSegment(join1); - OptionalJoinSegment seg2 = new OptionalJoinSegment(join2); + QuerySegment<ExternalTupleSet> seg1 = qFactory.getQuerySegment(join1); + QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(join2); - PCJNodeConsolidator consolidator = new PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); + QueryNodeConsolidator consolidator = new QueryNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); List<QueryModelNode> queryNodes = new ArrayList<>(seg1.getOrderedNodes()); QueryModelNode node = queryNodes.remove(5); @@ -325,10 +332,10 @@ public class PCJNodeConsolidatorTest { LeftJoin join1 = (LeftJoin) ((Projection) te1).getArg(); LeftJoin join2 = (LeftJoin) ((Projection) te2).getArg(); - OptionalJoinSegment seg1 = new OptionalJoinSegment(join1); - OptionalJoinSegment seg2 = new OptionalJoinSegment(join2); + QuerySegment<ExternalTupleSet> seg1 = qFactory.getQuerySegment(join1); + QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(join2); - PCJNodeConsolidator consolidator = new PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); + QueryNodeConsolidator consolidator = new QueryNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); List<QueryModelNode> queryNodes = new ArrayList<>(seg2.getOrderedNodes()); Assert.assertTrue(consolidator.consolidateNodes()); @@ -373,10 +380,10 @@ public class PCJNodeConsolidatorTest { LeftJoin join1 = (LeftJoin) ((Projection) te1).getArg(); LeftJoin join2 = (LeftJoin) ((Projection) te2).getArg(); - OptionalJoinSegment seg1 = new OptionalJoinSegment(join1); - OptionalJoinSegment seg2 = new OptionalJoinSegment(join2); + QuerySegment<ExternalTupleSet> seg1 = qFactory.getQuerySegment(join1); + QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(join2); - PCJNodeConsolidator consolidator = new PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); + QueryNodeConsolidator consolidator = new QueryNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); List<QueryModelNode> queryNodes = new ArrayList<>(seg2.getOrderedNodes()); Assert.assertTrue(consolidator.consolidateNodes()); @@ -411,10 +418,10 @@ public class PCJNodeConsolidatorTest { Join join1 = (Join) ((Projection) te1).getArg(); Join join2 = (Join) ((Projection) te2).getArg(); - OptionalJoinSegment seg1 = new OptionalJoinSegment(join1); - OptionalJoinSegment seg2 = new OptionalJoinSegment(join2); + QuerySegment<ExternalTupleSet> seg1 = qFactory.getQuerySegment(join1); + QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(join2); - PCJNodeConsolidator consolidator = new PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); + QueryNodeConsolidator consolidator = new QueryNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); List<QueryModelNode> queryNodes = new ArrayList<>(seg2.getOrderedNodes()); Assert.assertTrue(consolidator.consolidateNodes()); @@ -454,10 +461,10 @@ public class PCJNodeConsolidatorTest { Join join1 = (Join) ((Projection) te1).getArg(); Join join2 = (Join) ((Projection) te2).getArg(); - OptionalJoinSegment seg1 = new OptionalJoinSegment(join1); - OptionalJoinSegment seg2 = new OptionalJoinSegment(join2); + QuerySegment<ExternalTupleSet> seg1 = qFactory.getQuerySegment(join1); + QuerySegment<ExternalTupleSet> seg2 = qFactory.getQuerySegment(join2); - PCJNodeConsolidator consolidator = new PCJNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); + QueryNodeConsolidator consolidator = new QueryNodeConsolidator(seg1.getOrderedNodes(), seg2.getOrderedNodes()); List<QueryModelNode> queryNodes = new ArrayList<>(seg2.getOrderedNodes()); Assert.assertTrue(consolidator.consolidateNodes());
http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/PCJOptimizerTest.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/PCJOptimizerTest.java b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/PCJOptimizerTest.java index 261b680..31f4e7b 100644 --- a/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/PCJOptimizerTest.java +++ b/extras/indexing/src/test/java/org/apache/rya/indexing/pcj/matching/PCJOptimizerTest.java @@ -43,7 +43,7 @@ import com.google.common.collect.Sets; public class PCJOptimizerTest { @Test - public void testBasicSegment() throws MalformedQueryException { + public void testBasicSegment() throws Exception { String query1 = ""// + "SELECT ?e ?c ?l" // @@ -84,7 +84,7 @@ public class PCJOptimizerTest { } @Test - public void testSegmentWithUnion() throws MalformedQueryException { + public void testSegmentWithUnion() throws Exception { String query1 = ""// + "SELECT ?e ?c ?l" // @@ -287,7 +287,7 @@ public class PCJOptimizerTest { } @Test - public void testSegmentWithLargeUnion() throws MalformedQueryException { + public void testSegmentWithLargeUnion() throws Exception { String query1 = ""// + "SELECT ?e ?c ?l" // @@ -350,7 +350,7 @@ public class PCJOptimizerTest { } @Test - public void testSegmentWithUnionAndFilters() throws MalformedQueryException { + public void testSegmentWithUnionAndFilters() throws Exception { String query1 = ""// + "SELECT ?e ?c ?l" // @@ -407,7 +407,7 @@ public class PCJOptimizerTest { } @Test - public void testSegmentWithLeftJoinsAndFilters() throws MalformedQueryException { + public void testSegmentWithLeftJoinsAndFilters() throws Exception { String query1 = ""// + "SELECT ?e ?c ?l" // @@ -457,7 +457,7 @@ public class PCJOptimizerTest { } @Test - public void testJoinMatcherRejectsLeftJoinPcj() throws MalformedQueryException { + public void testJoinMatcherRejectsLeftJoinPcj() throws Exception { String query1 = ""// + "SELECT ?e ?c ?l" // http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/AccumuloStatementMetadataNodeTest.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/AccumuloStatementMetadataNodeTest.java b/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/AccumuloStatementMetadataNodeTest.java new file mode 100644 index 0000000..fc6bdb2 --- /dev/null +++ b/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/AccumuloStatementMetadataNodeTest.java @@ -0,0 +1,379 @@ +package org.apache.rya.indexing.statement.metadata; + +/* + * 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. + */ +import java.util.ArrayList; +import java.util.List; + +import org.apache.accumulo.core.client.Connector; +import org.apache.rya.accumulo.AccumuloRdfConfiguration; +import org.apache.rya.accumulo.AccumuloRyaDAO; +import org.apache.rya.api.RdfCloudTripleStoreConfiguration; +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.api.domain.StatementMetadata; +import org.apache.rya.api.persist.RyaDAOException; +import org.apache.rya.indexing.accumulo.ConfigUtils; +import org.apache.rya.indexing.statement.metadata.matching.StatementMetadataNode; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openrdf.model.impl.LiteralImpl; +import org.openrdf.model.impl.URIImpl; +import org.openrdf.model.vocabulary.XMLSchema; +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.evaluation.QueryBindingSet; +import org.openrdf.query.algebra.helpers.StatementPatternCollector; +import org.openrdf.query.parser.ParsedQuery; +import org.openrdf.query.parser.sparql.SPARQLParser; + +import info.aduna.iteration.CloseableIteration; + +public class AccumuloStatementMetadataNodeTest { + + private AccumuloRyaDAO dao; + private AccumuloRdfConfiguration conf; + private final String query = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode rdf:type rdf:Statement; rdf:subject <http://Joe>; " + + "rdf:predicate <http://worksAt>; rdf:object ?x; <http://createdBy> ?y; <http://createdOn> \'2017-01-04\'^^xsd:date }"; + private final String query2 = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode rdf:type rdf:Statement; rdf:subject ?x; " + + "rdf:predicate <http://worksAt>; rdf:object ?y; <http://createdBy> ?x; <http://createdOn> \'2017-01-04\'^^xsd:date }"; + + @Before + public void init() throws Exception { + conf = getConf(); + Connector conn = ConfigUtils.getConnector(conf); + dao = new AccumuloRyaDAO(); + dao.setConnector(conn); + dao.init(); + } + + @After + public void close() throws RyaDAOException { + dao.destroy(); + } + + @Test + public void simpleQueryWithoutBindingSet() + throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + dao.add(statement); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + // RyaQueryEngine<RdfCloudTripleStoreConfiguration> engine = + // (RyaQueryEngine<>) dao.getQueryEngine(); + + StatementMetadataNode<?> node = new StatementMetadataNode<>(spList, conf); + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(new QueryBindingSet()); + + QueryBindingSet bs = new QueryBindingSet(); + bs.addBinding("x", new LiteralImpl("CoffeeShop")); + bs.addBinding("y", new LiteralImpl("Joe")); + + List<BindingSet> bsList = new ArrayList<>(); + while (iteration.hasNext()) { + bsList.add(iteration.next()); + } + + Assert.assertEquals(1, bsList.size()); + Assert.assertEquals(bs, bsList.get(0)); + dao.delete(statement, conf); + } + + /** + * Tests if results are filtered correctly using the metadata properties. In + * this case, the date for the ingested RyaStatement differs from the date + * specified in the query. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithoutBindingSetInvalidProperty() + throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Doug")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-02-15")); + + RyaStatement statement = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + dao.add(statement); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + StatementMetadataNode<AccumuloRdfConfiguration> node = new StatementMetadataNode<>(spList, conf); + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(new QueryBindingSet()); + + List<BindingSet> bsList = new ArrayList<>(); + while (iteration.hasNext()) { + bsList.add(iteration.next()); + } + Assert.assertEquals(0, bsList.size()); + dao.delete(statement, conf); + } + + @Test + public void simpleQueryWithBindingSet() throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + RyaStatement statement2 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("HardwareStore"), new RyaURI("http://context"), "", metadata); + dao.add(statement1); + dao.add(statement2); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + StatementMetadataNode<AccumuloRdfConfiguration> node = new StatementMetadataNode<>(spList, conf); + + QueryBindingSet bsConstraint = new QueryBindingSet(); + bsConstraint.addBinding("x", new LiteralImpl("CoffeeShop")); + bsConstraint.addBinding("z", new LiteralImpl("Virginia")); + + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(bsConstraint); + + QueryBindingSet expected = new QueryBindingSet(); + expected.addBinding("x", new LiteralImpl("CoffeeShop")); + expected.addBinding("y", new LiteralImpl("Joe")); + expected.addBinding("z", new LiteralImpl("Virginia")); + + List<BindingSet> bsList = new ArrayList<>(); + while (iteration.hasNext()) { + bsList.add(iteration.next()); + } + + Assert.assertEquals(1, bsList.size()); + Assert.assertEquals(expected, bsList.get(0)); + + dao.delete(statement1, conf); + dao.delete(statement2, conf); + } + + /** + * Tests to see if correct result is passed back when a metadata statement + * is joined with a StatementPattern statement (i.e. a common variable + * appears in a StatementPattern statement and a metadata statement). + * StatementPattern statements have either rdf:subject, rdf:predicate, or + * rdf:object as the predicate while a metadata statement is any statement + * in the reified query whose predicate is not rdf:type and not a + * StatementPattern predicate. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithBindingSetJoinPropertyToSubject() + throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaURI("http://Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + RyaStatement statement2 = new RyaStatement(new RyaURI("http://Bob"), new RyaURI("http://worksAt"), + new RyaType("HardwareStore"), new RyaURI("http://context"), "", metadata); + dao.add(statement1); + dao.add(statement2); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query2, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + StatementMetadataNode<AccumuloRdfConfiguration> node = new StatementMetadataNode<>(spList, conf); + + List<BindingSet> bsCollection = new ArrayList<>(); + QueryBindingSet bsConstraint1 = new QueryBindingSet(); + bsConstraint1.addBinding("y", new LiteralImpl("CoffeeShop")); + bsConstraint1.addBinding("z", new LiteralImpl("Virginia")); + + QueryBindingSet bsConstraint2 = new QueryBindingSet(); + bsConstraint2.addBinding("y", new LiteralImpl("HardwareStore")); + bsConstraint2.addBinding("z", new LiteralImpl("Maryland")); + bsCollection.add(bsConstraint1); + bsCollection.add(bsConstraint2); + + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(bsCollection); + + QueryBindingSet expected = new QueryBindingSet(); + expected.addBinding("y", new LiteralImpl("CoffeeShop")); + expected.addBinding("x", new URIImpl("http://Joe")); + expected.addBinding("z", new LiteralImpl("Virginia")); + + List<BindingSet> bsList = new ArrayList<>(); + while (iteration.hasNext()) { + bsList.add(iteration.next()); + } + + Assert.assertEquals(1, bsList.size()); + Assert.assertEquals(expected, bsList.get(0)); + + dao.delete(statement1, conf); + dao.delete(statement2, conf); + } + + /** + * Tests if the StatementMetadataNode joins BindingSet correctly for + * variables appearing in metadata statements. In this case, the metadata + * statements are (_:blankNode <http://createdOn 2017-01-04 ) and + * (_:blankNode <http://createdBy> ?y). The variable ?y appears as the + * object in the above metadata statement and its values are joined to the + * constraint BindingSets in the example below. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithBindingSetJoinOnProperty() + throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + dao.add(statement1); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + StatementMetadataNode<AccumuloRdfConfiguration> node = new StatementMetadataNode<>(spList, conf); + + QueryBindingSet bsConstraint = new QueryBindingSet(); + bsConstraint.addBinding("x", new LiteralImpl("CoffeeShop")); + bsConstraint.addBinding("y", new LiteralImpl("Doug")); + + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(bsConstraint); + + List<BindingSet> bsList = new ArrayList<>(); + while (iteration.hasNext()) { + bsList.add(iteration.next()); + } + + Assert.assertEquals(0, bsList.size()); + dao.delete(statement1, conf); + } + + /** + * Tests if StatementMetadataNode joins BindingSet values correctly for + * variables appearing as the object in one of the StatementPattern + * statements (in the case ?x appears as the Object in the statement + * _:blankNode rdf:object ?x). StatementPattern statements have either + * rdf:subject, rdf:predicate, or rdf:object as the predicate. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithBindingSetCollection() + throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + RyaStatement statement2 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("HardwareStore"), new RyaURI("http://context"), "", metadata); + dao.add(statement1); + dao.add(statement2); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + StatementMetadataNode<AccumuloRdfConfiguration> node = new StatementMetadataNode<>(spList, conf); + + List<BindingSet> bsCollection = new ArrayList<>(); + QueryBindingSet bsConstraint1 = new QueryBindingSet(); + bsConstraint1.addBinding("x", new LiteralImpl("CoffeeShop")); + bsConstraint1.addBinding("z", new LiteralImpl("Virginia")); + + QueryBindingSet bsConstraint2 = new QueryBindingSet(); + bsConstraint2.addBinding("x", new LiteralImpl("HardwareStore")); + bsConstraint2.addBinding("z", new LiteralImpl("Maryland")); + + QueryBindingSet bsConstraint3 = new QueryBindingSet(); + bsConstraint3.addBinding("x", new LiteralImpl("BurgerShack")); + bsConstraint3.addBinding("z", new LiteralImpl("Delaware")); + bsCollection.add(bsConstraint1); + bsCollection.add(bsConstraint2); + bsCollection.add(bsConstraint3); + + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(bsCollection); + + QueryBindingSet expected1 = new QueryBindingSet(); + expected1.addBinding("x", new LiteralImpl("CoffeeShop")); + expected1.addBinding("y", new LiteralImpl("Joe")); + expected1.addBinding("z", new LiteralImpl("Virginia")); + + QueryBindingSet expected2 = new QueryBindingSet(); + expected2.addBinding("x", new LiteralImpl("HardwareStore")); + expected2.addBinding("y", new LiteralImpl("Joe")); + expected2.addBinding("z", new LiteralImpl("Maryland")); + + List<BindingSet> bsList = new ArrayList<>(); + while (iteration.hasNext()) { + bsList.add(iteration.next()); + } + + Assert.assertEquals(2, bsList.size()); + Assert.assertEquals(expected1, bsList.get(1)); + Assert.assertEquals(expected2, bsList.get(0)); + + dao.delete(statement1, conf); + dao.delete(statement2, conf); + } + + private static AccumuloRdfConfiguration getConf() { + + final AccumuloRdfConfiguration conf = new AccumuloRdfConfiguration(); + + conf.setBoolean(ConfigUtils.USE_MOCK_INSTANCE, true); + conf.set(RdfCloudTripleStoreConfiguration.CONF_TBL_PREFIX, "rya_"); + conf.set(ConfigUtils.CLOUDBASE_USER, "root"); + conf.set(ConfigUtils.CLOUDBASE_PASSWORD, ""); + conf.set(ConfigUtils.CLOUDBASE_INSTANCE, "instance"); + conf.set(ConfigUtils.CLOUDBASE_AUTHS, ""); + + return conf; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/AccumuloStatementMetadataOptimizerIT.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/AccumuloStatementMetadataOptimizerIT.java b/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/AccumuloStatementMetadataOptimizerIT.java new file mode 100644 index 0000000..2353f51 --- /dev/null +++ b/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/AccumuloStatementMetadataOptimizerIT.java @@ -0,0 +1,284 @@ +package org.apache.rya.indexing.statement.metadata; +/* + * 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. + */ +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.accumulo.core.client.Connector; +import org.apache.rya.accumulo.AccumuloRdfConfiguration; +import org.apache.rya.accumulo.AccumuloRyaDAO; +import org.apache.rya.api.RdfCloudTripleStoreConfiguration; +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.api.domain.StatementMetadata; +import org.apache.rya.api.persist.RyaDAOException; +import org.apache.rya.indexing.accumulo.ConfigUtils; +import org.apache.rya.sail.config.RyaSailFactory; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openrdf.model.impl.LiteralImpl; +import org.openrdf.model.impl.URIImpl; +import org.openrdf.model.vocabulary.XMLSchema; +import org.openrdf.query.BindingSet; +import org.openrdf.query.MalformedQueryException; +import org.openrdf.query.QueryEvaluationException; +import org.openrdf.query.QueryLanguage; +import org.openrdf.query.TupleQueryResult; +import org.openrdf.query.algebra.evaluation.QueryBindingSet; +import org.openrdf.repository.sail.SailRepository; +import org.openrdf.repository.sail.SailRepositoryConnection; +import org.openrdf.sail.Sail; + +public class AccumuloStatementMetadataOptimizerIT { + + private RdfCloudTripleStoreConfiguration conf; + private Sail sail; + private SailRepository repo; + private SailRepositoryConnection conn; + private AccumuloRyaDAO dao; + private final String query1 = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode rdf:type rdf:Statement; rdf:subject <http://Joe>; " + + "rdf:predicate <http://worksAt>; rdf:object ?x; <http://createdBy> ?y; <http://createdOn> \'2017-01-04\'^^xsd:date }"; + private final String query2 = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?a ?b ?c where {_:blankNode1 rdf:type rdf:Statement; rdf:subject ?a; " + + "rdf:predicate <http://worksAt>; rdf:object <http://BurgerShack>; <http://createdBy> ?c; <http://createdOn> \'2017-01-04\'^^xsd:date. " + + "_:blankNode2 rdf:type rdf:Statement; rdf:subject ?a; " + + "rdf:predicate <http://talksTo>; rdf:object ?b; <http://createdBy> ?c; <http://createdOn> \'2017-01-04\'^^xsd:date }"; + + @Before + public void init() throws Exception { + conf = getConf(); + sail = RyaSailFactory.getInstance(conf); + repo = new SailRepository(sail); + conn = repo.getConnection(); + + Connector conn = ConfigUtils.getConnector(conf); + dao = new AccumuloRyaDAO(); + dao.setConnector(conn); + dao.init(); + } + + @After + public void close() throws Exception { + conn.close(); + repo.shutDown(); + sail.shutDown(); + sail.shutDown(); + dao.destroy(); + } + + @Test + public void simpleQueryWithoutBindingSet() throws Exception { + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + dao.add(statement); + + TupleQueryResult result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query1).evaluate(); + + QueryBindingSet bs = new QueryBindingSet(); + bs.addBinding("x", new LiteralImpl("CoffeeShop")); + bs.addBinding("y", new LiteralImpl("Joe")); + + List<BindingSet> bsList = new ArrayList<>(); + while (result.hasNext()) { + bsList.add(result.next()); + } + + System.out.println(bsList); + Assert.assertEquals(1, bsList.size()); + Assert.assertEquals(bs, bsList.get(0)); + dao.delete(statement, (AccumuloRdfConfiguration) conf); + } + + /** + * Tests if results are filtered correctly using the metadata properties. In + * this case, the date for the ingested RyaStatement differs from the date + * specified in the query. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithoutBindingSetInvalidProperty() throws Exception { + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Doug")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-02-15")); + + RyaStatement statement = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + dao.add(statement); + + TupleQueryResult result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query1).evaluate(); + + List<BindingSet> bsList = new ArrayList<>(); + while (result.hasNext()) { + bsList.add(result.next()); + } + Assert.assertEquals(0, bsList.size()); + dao.delete(statement, (AccumuloRdfConfiguration) conf); + } + +// @Test +// public void simpleDataTypeTest() throws Exception { +// StatementMetadata metadata = new StatementMetadata(); +// metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Doug")); +// metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-02-15")); +// +// RyaStatement statement = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), +// new RyaType("http://BurgerShack"), new RyaURI("http://context"), "", metadata); +// dao.add(statement); +// RyaStatement statement2 = new RyaStatement(new RyaURI("http://Bob"), new RyaURI("http://worksAt"), +// new RyaURI("http://BurgerShack"), new RyaURI("http://context"), "", metadata); +// dao.add(statement2); +// +// String temp = "select ?x where { ?x <http://worksAt> 'http://BurgerShack' . }"; +// TupleQueryResult result = conn.prepareTupleQuery(QueryLanguage.SPARQL, temp).evaluate(); +// +// List<BindingSet> bsList = new ArrayList<>(); +// while (result.hasNext()) { +// bsList.add(result.next()); +// } +// System.out.println("Bindings are: " + bsList); +// dao.delete(statement, (AccumuloRdfConfiguration) conf); +// dao.delete(statement2, (AccumuloRdfConfiguration) conf); +// } + + + @Test + public void simpleQueryWithBindingSet() throws Exception { + + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + RyaStatement statement2 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("HardwareStore"), new RyaURI("http://context"), "", metadata); + dao.add(statement1); + dao.add(statement2); + + TupleQueryResult result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query1).evaluate(); + + Set<BindingSet> expected = new HashSet<>(); + QueryBindingSet expected1 = new QueryBindingSet(); + expected1.addBinding("x", new LiteralImpl("CoffeeShop")); + expected1.addBinding("y", new LiteralImpl("Joe")); + QueryBindingSet expected2 = new QueryBindingSet(); + expected2.addBinding("x", new LiteralImpl("HardwareStore")); + expected2.addBinding("y", new LiteralImpl("Joe")); + expected.add(expected1); + expected.add(expected2); + + Set<BindingSet> bsSet = new HashSet<>(); + while (result.hasNext()) { + bsSet.add(result.next()); + } + + Assert.assertEquals(expected, bsSet); + + dao.delete(statement1, (AccumuloRdfConfiguration) conf); + dao.delete(statement2, (AccumuloRdfConfiguration) conf); + } + + /** + * Tests to see if correct result is passed back when a metadata statement + * is joined with a StatementPattern statement (i.e. a common variable + * appears in a StatementPattern statement and a metadata statement). + * StatementPattern statements have either rdf:subject, rdf:predicate, or + * rdf:object as the predicate while a metadata statement is any statement + * in the reified query whose predicate is not rdf:type and not a + * StatementPattern predicate. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithBindingSetJoinPropertyToSubject() throws Exception { + + StatementMetadata metadata1 = new StatementMetadata(); + metadata1.addMetadata(new RyaURI("http://createdBy"), new RyaURI("http://Doug")); + metadata1.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + StatementMetadata metadata2 = new StatementMetadata(); + metadata2.addMetadata(new RyaURI("http://createdBy"), new RyaURI("http://Bob")); + metadata2.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-02-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaURI("http://BurgerShack"), new RyaURI("http://context"), "", metadata1); + RyaStatement statement2 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://talksTo"), + new RyaURI("http://Betty"), new RyaURI("http://context"), "", metadata1); + RyaStatement statement3 = new RyaStatement(new RyaURI("http://Fred"), new RyaURI("http://talksTo"), + new RyaType("http://Amanda"), new RyaURI("http://context"), "", metadata1); + RyaStatement statement4 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://talksTo"), + new RyaType("http://Wanda"), new RyaURI("http://context"), "", metadata2); + dao.add(statement1); + dao.add(statement2); + dao.add(statement3); + dao.add(statement4); + + TupleQueryResult result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query2).evaluate(); + + Set<BindingSet> expected = new HashSet<>(); + QueryBindingSet expected1 = new QueryBindingSet(); + expected1.addBinding("b", new URIImpl("http://Betty")); + expected1.addBinding("a", new URIImpl("http://Joe")); + expected1.addBinding("c", new URIImpl("http://Doug")); + expected.add(expected1); + + Set<BindingSet> bsSet = new HashSet<>(); + while (result.hasNext()) { + bsSet.add(result.next()); + } + + Assert.assertEquals(expected, bsSet); + + dao.delete(statement1, (AccumuloRdfConfiguration) conf); + dao.delete(statement2, (AccumuloRdfConfiguration) conf); + dao.delete(statement3, (AccumuloRdfConfiguration) conf); + dao.delete(statement4, (AccumuloRdfConfiguration) conf); + } + + private static RdfCloudTripleStoreConfiguration getConf() { + + RdfCloudTripleStoreConfiguration conf; + Set<RyaURI> propertySet = new HashSet<RyaURI>( + Arrays.asList(new RyaURI("http://createdBy"), new RyaURI("http://createdOn"))); + conf = new AccumuloRdfConfiguration(); + conf.setBoolean(ConfigUtils.USE_MOCK_INSTANCE, true); + conf.set(RdfCloudTripleStoreConfiguration.CONF_TBL_PREFIX, "rya_"); + conf.set(ConfigUtils.CLOUDBASE_USER, "root"); + conf.set(ConfigUtils.CLOUDBASE_PASSWORD, ""); + conf.set(ConfigUtils.CLOUDBASE_INSTANCE, "instance"); + conf.set(ConfigUtils.CLOUDBASE_AUTHS, ""); + conf.setUseStatementMetadata(true); + conf.setStatementMetadataProperties(propertySet); + return conf; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/MongoStatementMetadataIT.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/MongoStatementMetadataIT.java b/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/MongoStatementMetadataIT.java new file mode 100644 index 0000000..8b8d1df --- /dev/null +++ b/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/MongoStatementMetadataIT.java @@ -0,0 +1,275 @@ +package org.apache.rya.indexing.statement.metadata; +/* + * 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. + */ +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +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.api.domain.StatementMetadata; +import org.apache.rya.api.persist.RyaDAOException; +import org.apache.rya.indexing.accumulo.ConfigUtils; +import org.apache.rya.mongodb.MockMongoFactory; +import org.apache.rya.mongodb.MongoConnectorFactory; +import org.apache.rya.mongodb.MongoDBRdfConfiguration; +import org.apache.rya.mongodb.MongoDBRyaDAO; +import org.apache.rya.sail.config.RyaSailFactory; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openrdf.model.impl.LiteralImpl; +import org.openrdf.model.impl.URIImpl; +import org.openrdf.model.vocabulary.XMLSchema; +import org.openrdf.query.BindingSet; +import org.openrdf.query.MalformedQueryException; +import org.openrdf.query.QueryEvaluationException; +import org.openrdf.query.QueryLanguage; +import org.openrdf.query.TupleQueryResult; +import org.openrdf.query.algebra.evaluation.QueryBindingSet; +import org.openrdf.repository.sail.SailRepository; +import org.openrdf.repository.sail.SailRepositoryConnection; +import org.openrdf.sail.Sail; + +import com.mongodb.MongoClient; + +import de.flapdoodle.embed.mongo.distribution.Version; + +public class MongoStatementMetadataIT { + + protected MockMongoFactory testsFactory; + protected MongoClient mongoClient; + private MongoDBRdfConfiguration conf; + private Sail sail; + private SailRepository repo; + private SailRepositoryConnection conn; + private MongoDBRyaDAO dao; + private final String query1 = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode rdf:type rdf:Statement; rdf:subject <http://Joe>; " + + "rdf:predicate <http://worksAt>; rdf:object ?x; <http://createdBy> ?y; <http://createdOn> \'2017-01-04\'^^xsd:date }"; + private final String query2 = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?a ?b ?c where {_:blankNode1 rdf:type rdf:Statement; rdf:subject ?a; " + + "rdf:predicate <http://worksAt>; rdf:object <http://BurgerShack>; <http://createdBy> ?c; <http://createdOn> \'2017-01-04\'^^xsd:date. " + + "_:blankNode2 rdf:type rdf:Statement; rdf:subject ?a; " + + "rdf:predicate <http://talksTo>; rdf:object ?b; <http://createdBy> ?c; <http://createdOn> \'2017-01-04\'^^xsd:date }"; + + @Before + public void init() throws Exception { + testsFactory = MockMongoFactory.with(Version.Main.PRODUCTION); + mongoClient = testsFactory.newMongoClient(); + conf = getConf(); + sail = RyaSailFactory.getInstance(conf); + repo = new SailRepository(sail); + conn = repo.getConnection(); + + dao = new MongoDBRyaDAO(conf, mongoClient); + dao.init(); + } + + @After + public void close() throws Exception { + conn.close(); + repo.shutDown(); + sail.shutDown(); + sail.shutDown(); + dao.destroy(); + + if (mongoClient != null) { + mongoClient.close(); + } + if (testsFactory != null) { + testsFactory.shutdown(); + } + MongoConnectorFactory.closeMongoClient(); + } + + + @Test + public void simpleQueryWithoutBindingSet() throws Exception { + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + dao.add(statement); + + TupleQueryResult result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query1).evaluate(); + + QueryBindingSet bs = new QueryBindingSet(); + bs.addBinding("x", new LiteralImpl("CoffeeShop")); + bs.addBinding("y", new LiteralImpl("Joe")); + + List<BindingSet> bsList = new ArrayList<>(); + while (result.hasNext()) { + bsList.add(result.next()); + } + + System.out.println(bsList); + Assert.assertEquals(1, bsList.size()); + Assert.assertEquals(bs, bsList.get(0)); + dao.delete(statement, conf); + } + + /** + * Tests if results are filtered correctly using the metadata properties. In + * this case, the date for the ingested RyaStatement differs from the date + * specified in the query. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithoutBindingSetInvalidProperty() throws Exception { + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Doug")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-02-15")); + + RyaStatement statement = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + dao.add(statement); + + TupleQueryResult result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query1).evaluate(); + + List<BindingSet> bsList = new ArrayList<>(); + while (result.hasNext()) { + bsList.add(result.next()); + } + Assert.assertEquals(0, bsList.size()); + dao.delete(statement, conf); + } + + @Test + public void simpleQueryWithBindingSet() throws Exception { + + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + RyaStatement statement2 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("HardwareStore"), new RyaURI("http://context"), "", metadata); + dao.add(statement1); + dao.add(statement2); + + TupleQueryResult result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query1).evaluate(); + + Set<BindingSet> expected = new HashSet<>(); + QueryBindingSet expected1 = new QueryBindingSet(); + expected1.addBinding("x", new LiteralImpl("CoffeeShop")); + expected1.addBinding("y", new LiteralImpl("Joe")); + QueryBindingSet expected2 = new QueryBindingSet(); + expected2.addBinding("x", new LiteralImpl("HardwareStore")); + expected2.addBinding("y", new LiteralImpl("Joe")); + expected.add(expected1); + expected.add(expected2); + + Set<BindingSet> bsSet = new HashSet<>(); + while (result.hasNext()) { + bsSet.add(result.next()); + } + + Assert.assertEquals(expected, bsSet); + + dao.delete(statement1, conf); + dao.delete(statement2, conf); + } + + /** + * Tests to see if correct result is passed back when a metadata statement + * is joined with a StatementPattern statement (i.e. a common variable + * appears in a StatementPattern statement and a metadata statement). + * StatementPattern statements have either rdf:subject, rdf:predicate, or + * rdf:object as the predicate while a metadata statement is any statement + * in the reified query whose predicate is not rdf:type and not a + * StatementPattern predicate. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithBindingSetJoinPropertyToSubject() throws Exception { + + StatementMetadata metadata1 = new StatementMetadata(); + metadata1.addMetadata(new RyaURI("http://createdBy"), new RyaURI("http://Doug")); + metadata1.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + StatementMetadata metadata2 = new StatementMetadata(); + metadata2.addMetadata(new RyaURI("http://createdBy"), new RyaURI("http://Bob")); + metadata2.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-02-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaURI("http://BurgerShack"), new RyaURI("http://context"), "", metadata1); + RyaStatement statement2 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://talksTo"), + new RyaURI("http://Betty"), new RyaURI("http://context"), "", metadata1); + RyaStatement statement3 = new RyaStatement(new RyaURI("http://Fred"), new RyaURI("http://talksTo"), + new RyaURI("http://Amanda"), new RyaURI("http://context"), "", metadata1); + RyaStatement statement4 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://talksTo"), + new RyaURI("http://Wanda"), new RyaURI("http://context"), "", metadata2); + dao.add(statement1); + dao.add(statement2); + dao.add(statement3); + dao.add(statement4); + + TupleQueryResult result = conn.prepareTupleQuery(QueryLanguage.SPARQL, query2).evaluate(); + + Set<BindingSet> expected = new HashSet<>(); + QueryBindingSet expected1 = new QueryBindingSet(); + expected1.addBinding("b", new URIImpl("http://Betty")); + expected1.addBinding("a", new URIImpl("http://Joe")); + expected1.addBinding("c", new URIImpl("http://Doug")); + expected.add(expected1); + + Set<BindingSet> bsSet = new HashSet<>(); + while (result.hasNext()) { + bsSet.add(result.next()); + } + + Assert.assertEquals(expected, bsSet); + + dao.delete(statement1, conf); + dao.delete(statement2, conf); + dao.delete(statement3, conf); + dao.delete(statement4, conf); + } + + private MongoDBRdfConfiguration getConf() throws IOException { + + String host = mongoClient.getServerAddressList().get(0).getHost(); + int port = mongoClient.getServerAddressList().get(0).getPort(); + Set<RyaURI> propertySet = new HashSet<RyaURI>( + Arrays.asList(new RyaURI("http://createdBy"), new RyaURI("http://createdOn"))); + MongoDBRdfConfiguration conf = new MongoDBRdfConfiguration(); + conf.set(ConfigUtils.USE_MONGO, "true"); + conf.setMongoInstance(host); + conf.setMongoPort(Integer.toString(port)); + conf.setMongoDBName("local"); + conf.setCollectionName("rya"); + conf.setTablePrefix("rya_"); + conf.setUseStatementMetadata(true); + conf.setStatementMetadataProperties(propertySet); + return conf; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/MongoStatementMetadataNodeTest.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/MongoStatementMetadataNodeTest.java b/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/MongoStatementMetadataNodeTest.java new file mode 100644 index 0000000..0a3ada0 --- /dev/null +++ b/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/MongoStatementMetadataNodeTest.java @@ -0,0 +1,399 @@ +package org.apache.rya.indexing.statement.metadata; +/* + * 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. + */ +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +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.api.domain.StatementMetadata; +import org.apache.rya.api.persist.RyaDAOException; +import org.apache.rya.indexing.accumulo.ConfigUtils; +import org.apache.rya.indexing.statement.metadata.matching.StatementMetadataNode; +import org.apache.rya.mongodb.MockMongoFactory; +import org.apache.rya.mongodb.MongoConnectorFactory; +import org.apache.rya.mongodb.MongoDBRdfConfiguration; +import org.apache.rya.mongodb.MongoDBRyaDAO; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; +import org.openrdf.model.impl.LiteralImpl; +import org.openrdf.model.impl.URIImpl; +import org.openrdf.model.vocabulary.XMLSchema; +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.evaluation.QueryBindingSet; +import org.openrdf.query.algebra.helpers.StatementPatternCollector; +import org.openrdf.query.parser.ParsedQuery; +import org.openrdf.query.parser.sparql.SPARQLParser; + +import com.mongodb.MongoClient; + +import de.flapdoodle.embed.mongo.distribution.Version; +import info.aduna.iteration.CloseableIteration; + +public class MongoStatementMetadataNodeTest { + + protected MockMongoFactory testsFactory; + protected MongoClient mongoClient; + private MongoDBRdfConfiguration conf; + private MongoDBRyaDAO dao; + private final String query = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode rdf:type rdf:Statement; rdf:subject <http://Joe>; " + + "rdf:predicate <http://worksAt>; rdf:object ?x; <http://createdBy> ?y; <http://createdOn> \'2017-01-04\'^^xsd:date }"; + private final String query2 = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode rdf:type rdf:Statement; rdf:subject ?x; " + + "rdf:predicate <http://worksAt>; rdf:object ?y; <http://createdBy> ?x; <http://createdOn> \'2017-01-04\'^^xsd:date }"; + + + @Before + public void init() throws Exception { + testsFactory = MockMongoFactory.with(Version.Main.PRODUCTION); + mongoClient = testsFactory.newMongoClient(); + conf = getConf(); + + dao = new MongoDBRyaDAO(conf, mongoClient); + dao.init(); + } + + @After + public void close() throws RyaDAOException { + dao.destroy(); + + if (mongoClient != null) { + mongoClient.close(); + } + if (testsFactory != null) { + testsFactory.shutdown(); + } + MongoConnectorFactory.closeMongoClient(); + } + + @Test + public void simpleQueryWithoutBindingSet() + throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + dao.add(statement); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + + StatementMetadataNode<?> node = new StatementMetadataNode<>(spList, conf); + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(new QueryBindingSet()); + + QueryBindingSet bs = new QueryBindingSet(); + bs.addBinding("x", new LiteralImpl("CoffeeShop")); + bs.addBinding("y", new LiteralImpl("Joe")); + + List<BindingSet> bsList = new ArrayList<>(); + while (iteration.hasNext()) { + bsList.add(iteration.next()); + } + + Assert.assertEquals(1, bsList.size()); + Assert.assertEquals(bs, bsList.get(0)); + dao.delete(statement, conf); + } + + /** + * Tests if results are filtered correctly using the metadata properties. In + * this case, the date for the ingested RyaStatement differs from the date + * specified in the query. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithoutBindingSetInvalidProperty() + throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Doug")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-02-15")); + + RyaStatement statement = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + dao.add(statement); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + StatementMetadataNode<MongoDBRdfConfiguration> node = new StatementMetadataNode<>(spList, conf); + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(new QueryBindingSet()); + + List<BindingSet> bsList = new ArrayList<>(); + while (iteration.hasNext()) { + bsList.add(iteration.next()); + } + Assert.assertEquals(0, bsList.size()); + dao.delete(statement, conf); + } + + @Test + public void simpleQueryWithBindingSet() throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + RyaStatement statement2 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("HardwareStore"), new RyaURI("http://context"), "", metadata); + dao.add(statement1); + dao.add(statement2); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + StatementMetadataNode<MongoDBRdfConfiguration> node = new StatementMetadataNode<>(spList, conf); + + QueryBindingSet bsConstraint = new QueryBindingSet(); + bsConstraint.addBinding("x", new LiteralImpl("CoffeeShop")); + bsConstraint.addBinding("z", new LiteralImpl("Virginia")); + + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(bsConstraint); + + QueryBindingSet expected = new QueryBindingSet(); + expected.addBinding("x", new LiteralImpl("CoffeeShop")); + expected.addBinding("y", new LiteralImpl("Joe")); + expected.addBinding("z", new LiteralImpl("Virginia")); + + List<BindingSet> bsList = new ArrayList<>(); + while (iteration.hasNext()) { + bsList.add(iteration.next()); + } + + Assert.assertEquals(1, bsList.size()); + Assert.assertEquals(expected, bsList.get(0)); + + dao.delete(statement1, conf); + dao.delete(statement2, conf); + } + + /** + * Tests to see if correct result is passed back when a metadata statement + * is joined with a StatementPattern statement (i.e. a common variable + * appears in a StatementPattern statement and a metadata statement). + * StatementPattern statements have either rdf:subject, rdf:predicate, or + * rdf:object as the predicate while a metadata statement is any statement + * in the reified query whose predicate is not rdf:type and not a + * StatementPattern predicate. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithBindingSetJoinPropertyToSubject() + throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaURI("http://Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + RyaStatement statement2 = new RyaStatement(new RyaURI("http://Bob"), new RyaURI("http://worksAt"), + new RyaType("HardwareStore"), new RyaURI("http://context"), "", metadata); + dao.add(statement1); + dao.add(statement2); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query2, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + StatementMetadataNode<MongoDBRdfConfiguration> node = new StatementMetadataNode<>(spList, conf); + + List<BindingSet> bsCollection = new ArrayList<>(); + QueryBindingSet bsConstraint1 = new QueryBindingSet(); + bsConstraint1.addBinding("y", new LiteralImpl("CoffeeShop")); + bsConstraint1.addBinding("z", new LiteralImpl("Virginia")); + + QueryBindingSet bsConstraint2 = new QueryBindingSet(); + bsConstraint2.addBinding("y", new LiteralImpl("HardwareStore")); + bsConstraint2.addBinding("z", new LiteralImpl("Maryland")); + bsCollection.add(bsConstraint1); + bsCollection.add(bsConstraint2); + + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(bsCollection); + + QueryBindingSet expected = new QueryBindingSet(); + expected.addBinding("y", new LiteralImpl("CoffeeShop")); + expected.addBinding("x", new URIImpl("http://Joe")); + expected.addBinding("z", new LiteralImpl("Virginia")); + + List<BindingSet> bsList = new ArrayList<>(); + while (iteration.hasNext()) { + bsList.add(iteration.next()); + } + + Assert.assertEquals(1, bsList.size()); + Assert.assertEquals(expected, bsList.get(0)); + + dao.delete(statement1, conf); + dao.delete(statement2, conf); + } + + /** + * Tests if the StatementMetadataNode joins BindingSet correctly for + * variables appearing in metadata statements. In this case, the metadata + * statements are (_:blankNode <http://createdOn 2017-01-04 ) and + * (_:blankNode <http://createdBy> ?y). The variable ?y appears as the + * object in the above metadata statement and its values are joined to the + * constraint BindingSets in the example below. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithBindingSetJoinOnProperty() + throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + dao.add(statement1); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + StatementMetadataNode<MongoDBRdfConfiguration> node = new StatementMetadataNode<>(spList, conf); + + QueryBindingSet bsConstraint = new QueryBindingSet(); + bsConstraint.addBinding("x", new LiteralImpl("CoffeeShop")); + bsConstraint.addBinding("y", new LiteralImpl("Doug")); + + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(bsConstraint); + + List<BindingSet> bsList = new ArrayList<>(); + while (iteration.hasNext()) { + bsList.add(iteration.next()); + } + + Assert.assertEquals(0, bsList.size()); + dao.delete(statement1, conf); + } + + /** + * Tests if StatementMetadataNode joins BindingSet values correctly for + * variables appearing as the object in one of the StatementPattern + * statements (in the case ?x appears as the Object in the statement + * _:blankNode rdf:object ?x). StatementPattern statements have either + * rdf:subject, rdf:predicate, or rdf:object as the predicate. + * + * @throws MalformedQueryException + * @throws QueryEvaluationException + * @throws RyaDAOException + */ + @Test + public void simpleQueryWithBindingSetCollection() + throws MalformedQueryException, QueryEvaluationException, RyaDAOException { + + StatementMetadata metadata = new StatementMetadata(); + metadata.addMetadata(new RyaURI("http://createdBy"), new RyaType("Joe")); + metadata.addMetadata(new RyaURI("http://createdOn"), new RyaType(XMLSchema.DATE, "2017-01-04")); + + RyaStatement statement1 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("CoffeeShop"), new RyaURI("http://context"), "", metadata); + RyaStatement statement2 = new RyaStatement(new RyaURI("http://Joe"), new RyaURI("http://worksAt"), + new RyaType("HardwareStore"), new RyaURI("http://context"), "", metadata); + dao.add(statement1); + dao.add(statement2); + + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + List<StatementPattern> spList = StatementPatternCollector.process(pq.getTupleExpr()); + StatementMetadataNode<MongoDBRdfConfiguration> node = new StatementMetadataNode<>(spList, conf); + + List<BindingSet> bsCollection = new ArrayList<>(); + QueryBindingSet bsConstraint1 = new QueryBindingSet(); + bsConstraint1.addBinding("x", new LiteralImpl("CoffeeShop")); + bsConstraint1.addBinding("z", new LiteralImpl("Virginia")); + + QueryBindingSet bsConstraint2 = new QueryBindingSet(); + bsConstraint2.addBinding("x", new LiteralImpl("HardwareStore")); + bsConstraint2.addBinding("z", new LiteralImpl("Maryland")); + + QueryBindingSet bsConstraint3 = new QueryBindingSet(); + bsConstraint3.addBinding("x", new LiteralImpl("BurgerShack")); + bsConstraint3.addBinding("z", new LiteralImpl("Delaware")); + bsCollection.add(bsConstraint1); + bsCollection.add(bsConstraint2); + bsCollection.add(bsConstraint3); + + CloseableIteration<BindingSet, QueryEvaluationException> iteration = node.evaluate(bsCollection); + + Set<BindingSet> expected = new HashSet<>(); + QueryBindingSet expected1 = new QueryBindingSet(); + expected1.addBinding("x", new LiteralImpl("CoffeeShop")); + expected1.addBinding("y", new LiteralImpl("Joe")); + expected1.addBinding("z", new LiteralImpl("Virginia")); + + QueryBindingSet expected2 = new QueryBindingSet(); + expected2.addBinding("x", new LiteralImpl("HardwareStore")); + expected2.addBinding("y", new LiteralImpl("Joe")); + expected2.addBinding("z", new LiteralImpl("Maryland")); + expected.add(expected1); + expected.add(expected2); + + Set<BindingSet> bsSet = new HashSet<>(); + while (iteration.hasNext()) { + bsSet.add(iteration.next()); + } + + Assert.assertEquals(expected, bsSet); + + dao.delete(statement1, conf); + dao.delete(statement2, conf); + } + + private MongoDBRdfConfiguration getConf() throws IOException { + + String host = mongoClient.getServerAddressList().get(0).getHost(); + int port = mongoClient.getServerAddressList().get(0).getPort(); + Set<RyaURI> propertySet = new HashSet<RyaURI>( + Arrays.asList(new RyaURI("http://createdBy"), new RyaURI("http://createdOn"))); + MongoDBRdfConfiguration conf = new MongoDBRdfConfiguration(); + conf.set(ConfigUtils.USE_MONGO, "true"); + conf.setMongoInstance(host); + conf.setMongoPort(Integer.toString(port)); + conf.setMongoDBName("local"); + conf.setCollectionName("rya"); + conf.setTablePrefix("rya_"); + conf.setUseStatementMetadata(true); + conf.setStatementMetadataProperties(propertySet); + return conf; + } +} http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/11349b11/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/StatementMetadataExternalSetProviderTest.java ---------------------------------------------------------------------- diff --git a/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/StatementMetadataExternalSetProviderTest.java b/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/StatementMetadataExternalSetProviderTest.java new file mode 100644 index 0000000..2a41396 --- /dev/null +++ b/extras/indexing/src/test/java/org/apache/rya/indexing/statement/metadata/StatementMetadataExternalSetProviderTest.java @@ -0,0 +1,178 @@ +package org.apache.rya.indexing.statement.metadata; +/* + * 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. + */ +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.hadoop.conf.Configuration; +import org.apache.rya.accumulo.AccumuloRdfConfiguration; +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.external.matching.JoinSegment; +import org.apache.rya.indexing.statement.metadata.matching.StatementMetadataExternalSetProvider; +import org.apache.rya.indexing.statement.metadata.matching.StatementMetadataNode; +import org.apache.rya.mongodb.MongoDBRdfConfiguration; +import org.junit.Assert; +import org.junit.Test; +import org.openrdf.query.MalformedQueryException; +import org.openrdf.query.algebra.Filter; +import org.openrdf.query.algebra.QueryModelNode; +import org.openrdf.query.algebra.StatementPattern; +import org.openrdf.query.algebra.ValueExpr; +import org.openrdf.query.algebra.helpers.StatementPatternCollector; +import org.openrdf.query.parser.ParsedQuery; +import org.openrdf.query.parser.sparql.SPARQLParser; + +public class StatementMetadataExternalSetProviderTest { + + private final String query = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode rdf:type rdf:Statement; rdf:subject <http://Joe>; " + + "rdf:predicate <http://worksAt>; rdf:object ?x; <http://createdBy> ?y; <http://createdOn> \'2017-01-04\'^^xsd:date }"; + private final String query3 = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode1 rdf:type rdf:Statement. _:blankNode2 rdf:type rdf:Statement; rdf:subject <http://Bob>; " + + "rdf:predicate <http://worksAt>; rdf:object ?x; <http://createdBy> ?y; <http://createdOn> \'2017-02-04\'^^xsd:date }"; + private final String query2 = "prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode1 rdf:type rdf:Statement; rdf:subject <http://Joe>; " + + "rdf:predicate <http://worksAt>; rdf:object ?x; <http://createdBy> ?y; <http://createdOn> \'2017-01-04\'^^xsd:date. " + + "_:blankNode2 rdf:type rdf:Statement; rdf:subject <http://Bob>; " + + "rdf:predicate <http://worksAt>; rdf:object ?x; <http://createdBy> ?y; <http://createdOn> \'2017-02-04\'^^xsd:date }"; + + @Test + public void createSingleAccumuloMetadataNode() throws MalformedQueryException { + + AccumuloRdfConfiguration conf = (AccumuloRdfConfiguration) getConf(false); + Set<RyaURI> propertySet = new HashSet<>(); + propertySet.add(new RyaURI("http://createdBy")); + conf.setStatementMetadataProperties(propertySet); + StatementMetadataExternalSetProvider metaProvider = new StatementMetadataExternalSetProvider( + conf); + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + + List<QueryModelNode> patterns = new ArrayList<>(); + List<StatementMetadataNode<?>> expected = new ArrayList<>(); + Set<StatementPattern> sp = StatementMetadataTestUtils.getMetadataStatementPatterns(pq.getTupleExpr(), propertySet); + + patterns.addAll(StatementPatternCollector.process(pq.getTupleExpr())); + JoinSegment<StatementMetadataNode<?>> segment = new JoinSegment<>( + new HashSet<QueryModelNode>(patterns), patterns, new HashMap<ValueExpr, Filter>()); + List<StatementMetadataNode<?>> extSets = metaProvider.getExternalSets(segment); + + expected.add(new StatementMetadataNode<>(sp, conf)); + + Assert.assertEquals(expected, extSets); + + } + + @Test + public void createSingleMongoMetadataNode() throws MalformedQueryException { + + MongoDBRdfConfiguration conf = (MongoDBRdfConfiguration) getConf(true); + Set<RyaURI> propertySet = new HashSet<>(); + propertySet.add(new RyaURI("http://createdBy")); + conf.setStatementMetadataProperties(propertySet); + StatementMetadataExternalSetProvider metaProvider = new StatementMetadataExternalSetProvider(conf); + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq = parser.parseQuery(query, null); + + List<QueryModelNode> patterns = new ArrayList<>(); + List<StatementMetadataNode<?>> expected = new ArrayList<>(); + Set<StatementPattern> sp = StatementMetadataTestUtils.getMetadataStatementPatterns(pq.getTupleExpr(), propertySet); + + patterns.addAll(StatementPatternCollector.process(pq.getTupleExpr())); + JoinSegment<StatementMetadataNode<?>> segment = new JoinSegment<>( + new HashSet<QueryModelNode>(patterns), patterns, new HashMap<ValueExpr, Filter>()); + List<StatementMetadataNode<?>> extSets = metaProvider.getExternalSets(segment); + + expected.add(new StatementMetadataNode<>(sp,conf)); + + Assert.assertEquals(expected, extSets); + + } + + + @Test + public void createMultipleMetadataNode() throws MalformedQueryException { + + MongoDBRdfConfiguration conf = (MongoDBRdfConfiguration) getConf(true); + Set<RyaURI> propertySet = new HashSet<>(); + propertySet.add(new RyaURI("http://createdBy")); + propertySet.add(new RyaURI("http://createdOn")); + conf.setStatementMetadataProperties(propertySet); + StatementMetadataExternalSetProvider metaProvider = new StatementMetadataExternalSetProvider(conf); + SPARQLParser parser = new SPARQLParser(); + ParsedQuery pq2 = parser.parseQuery(query2, null); + ParsedQuery pq3 = parser.parseQuery(query3, null); + ParsedQuery pq1 = parser.parseQuery(query, null); + + List<QueryModelNode> patterns = new ArrayList<>(); + List<StatementMetadataNode<?>> expected = new ArrayList<>(); + Set<StatementPattern> sp1 = StatementMetadataTestUtils.getMetadataStatementPatterns(pq1.getTupleExpr(), propertySet); + Set<StatementPattern> sp3 = StatementMetadataTestUtils.getMetadataStatementPatterns(pq3.getTupleExpr(), propertySet); + //added extra blankNode into query3 to make blankNode names line up with query2. Need to remove it now so that + //StatementMetadataNode doesn't blow up because all subjects aren't the same. + removePatternWithGivenSubject("-anon-1", sp3); + + patterns.addAll(StatementPatternCollector.process(pq2.getTupleExpr())); + JoinSegment<StatementMetadataNode<?>> segment = new JoinSegment<>( + new HashSet<QueryModelNode>(patterns), patterns, new HashMap<ValueExpr, Filter>()); + List<StatementMetadataNode<?>> extSets = metaProvider.getExternalSets(segment); + + expected.add(new StatementMetadataNode<>(sp1,conf)); + expected.add(new StatementMetadataNode<>(sp3,conf)); + + Assert.assertEquals(expected, extSets); + } + + private static Configuration getConf(boolean useMongo) { + + if (useMongo) { + MongoDBRdfConfiguration conf = new MongoDBRdfConfiguration(); + conf.setBoolean("sc.useMongo", true); + conf.setMongoInstance("localhost"); + conf.setMongoPort("27017"); + conf.setMongoDBName("rya_"); + return conf; + } else { + + AccumuloRdfConfiguration conf = new AccumuloRdfConfiguration(); + conf.setBoolean(ConfigUtils.USE_MOCK_INSTANCE, true); + conf.set(RdfCloudTripleStoreConfiguration.CONF_TBL_PREFIX, "rya_"); + conf.set(ConfigUtils.CLOUDBASE_USER, "root"); + conf.set(ConfigUtils.CLOUDBASE_PASSWORD, ""); + conf.set(ConfigUtils.CLOUDBASE_INSTANCE, "instance"); + conf.set(ConfigUtils.CLOUDBASE_AUTHS, ""); + + return conf; + } + } + + private void removePatternWithGivenSubject(String subject, Set<StatementPattern> patterns) { + Iterator<StatementPattern> spIter = patterns.iterator(); + while(spIter.hasNext()) { + StatementPattern sp = spIter.next(); + if(sp.getSubjectVar().getName().equals(subject)) { + spIter.remove(); + } + } + } + +}
