| 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 static org.junit.Assert.assertEquals; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Set; |
| |
| 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.indexing.statement.metadata.matching.StatementMetadataOptimizer; |
| import org.apache.rya.mongodb.MongoDBRdfConfiguration; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.Parameterized; |
| import org.junit.runners.Parameterized.Parameters; |
| 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.TupleExpr; |
| 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; |
| |
| @RunWith(value = Parameterized.class) |
| public class StatementMetadataOptimizerTest { |
| |
| private static final String query1 = "prefix owl: <http://www.w3.org/2002/07/owl#> prefix ano: <http://www.w3.org/2002/07/owl#annotated> prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode rdf:type owl:Annotated; ano:Source <http://Joe>; " |
| + "ano:Property <http://worksAt>; ano:Target ?x; <http://createdBy> ?y; <http://createdOn> \'2017-01-04\'^^xsd:date }"; |
| private static final String query2 = "prefix owl: <http://www.w3.org/2002/07/owl#> prefix ano: <http://www.w3.org/2002/07/owl#annotated> prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode2 rdf:type owl:Annotated; ano:Source <http://Bob>; " |
| + "ano:Property <http://worksAt>; ano:Target ?x; <http://createdBy> ?y; <http://createdOn> \'2017-02-04\'^^xsd:date }"; |
| private static final String query3 = "prefix owl: <http://www.w3.org/2002/07/owl#> prefix ano: <http://www.w3.org/2002/07/owl#annotated> prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode2 rdf:type owl:Annotated; ano:Source <http://Frank>; " |
| + "ano:Property <http://worksAt>; ano:Target ?x; <http://createdBy> ?y; <http://createdOn> \'2017-03-04\'^^xsd:date }"; |
| private static final String query4 = "prefix owl: <http://www.w3.org/2002/07/owl#> prefix ano: <http://www.w3.org/2002/07/owl#annotated> prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode1 rdf:type owl:Annotated; ano:Source <http://Joe>; " |
| + "ano:Property <http://worksAt>; ano:Target ?x; <http://createdBy> ?y; <http://createdOn> \'2017-01-04\'^^xsd:date. " |
| + "_:blankNode2 rdf:type rdf:Statement; rdf:subject <http://Bob>; " |
| + "ano:Property <http://worksAt>; ano:Target ?x; <http://createdBy> ?y; <http://createdOn> \'2017-02-04\'^^xsd:date }"; |
| private static final String query5 = "prefix owl: <http://www.w3.org/2002/07/owl#> prefix ano: <http://www.w3.org/2002/07/owl#annotated> prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {_:blankNode1 rdf:type owl:Annotated; ano:Source <http://Joe>; " |
| + "ano:Property <http://worksAt>; ano:Target ?x; <http://createdBy> ?y; <http://createdOn> \'2017-01-04\'^^xsd:date. " |
| + "_:blankNode2 rdf:type owl:Annotated; rdf:subject <http://Bob>; " |
| + "ano:Property <http://worksAt>; ano:Target ?a; <http://createdBy> ?b; <http://createdOn> \'2017-02-04\'^^xsd:date. " |
| + "OPTIONAL{ _:blankNode3 rdf:type owl:Annotated; ano:Source <http://Frank>; " |
| + "ano:Property <http://worksAt>; ano:Target ?c; <http://createdBy> <http://Doug>; <http://createdOn> \'2017-03-04\'^^xsd:date } }"; |
| private static final String query6 = "prefix owl: <http://www.w3.org/2002/07/owl#> prefix ano: <http://www.w3.org/2002/07/owl#annotated> prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?x ?y where {?m rdf:type owl:Annotated; ano:Source <http://Joe>; " |
| + "ano:Property <http://worksAt>; ano:Target ?x; <http://createdBy> ?y; <http://createdOn> \'2017-01-04\'^^xsd:date. " |
| + "{ ?o rdf:type owl:Annotated; ano:Source <http://Frank>; " |
| + "ano:Property <http://worksAt>; ano:Target ?c; <http://createdBy> ?p; <http://createdOn> \'2017-03-04\'^^xsd:date . } " |
| + "UNION {?n ano:Property <http://worksAt>; ano:Target ?a; <http://createdBy> ?c; <http://createdOn> \'2017-02-04\'^^xsd:date; " |
| + "rdf:type owl:Annotated; ano:Source ?p. } }"; |
| |
| private String query; |
| private Set<StatementMetadataNode<?>> expected; |
| private static SPARQLParser parser = new SPARQLParser(); |
| private StatementMetadataOptimizer mongoOptimizer; |
| private StatementMetadataOptimizer accumuloOptimizer; |
| |
| public StatementMetadataOptimizerTest(String query, Set<StatementMetadataNode<?>> expected) { |
| this.query = query; |
| this.expected = expected; |
| } |
| |
| @Before |
| public void init() { |
| RdfCloudTripleStoreConfiguration mongoConf = getConf(true); |
| RdfCloudTripleStoreConfiguration accumuloConf = getConf(false); |
| mongoOptimizer = new StatementMetadataOptimizer(mongoConf); |
| accumuloOptimizer = new StatementMetadataOptimizer(accumuloConf); |
| } |
| |
| @Parameters |
| public static Collection<Object[]> data() throws MalformedQueryException { |
| return Arrays.asList(new Object[][] { { query1, getExpected(query1) }, { query2, getExpected(query2) }, |
| { query3, getExpected(query3) }, { query4, getExpected(query4) }, { query5, getExpected(query5) }, |
| { query6, getExpected(query6) } }); |
| } |
| |
| @Test |
| public void testAccumuloMatchQuery() throws MalformedQueryException { |
| ParsedQuery pq = parser.parseQuery(query, null); |
| TupleExpr te = pq.getTupleExpr(); |
| System.out.println("Parametrized query is : " + te); |
| accumuloOptimizer.optimize(te, null, null); |
| System.out.println("Result of optimization is : " + te); |
| assertEquals(expected, StatementMetadataTestUtils.getMetadataNodes(te)); |
| } |
| |
| @Test |
| public void testMongoMatchQuery() throws MalformedQueryException { |
| SPARQLParser parser = new SPARQLParser(); |
| ParsedQuery pq = parser.parseQuery(query, null); |
| TupleExpr te = pq.getTupleExpr(); |
| System.out.println("Parametrized query is : " + te); |
| mongoOptimizer.optimize(te, null, null); |
| System.out.println("Result of optimization is : " + te); |
| assertEquals(expected, StatementMetadataTestUtils.getMetadataNodes(te)); |
| } |
| |
| private static RdfCloudTripleStoreConfiguration getConf(boolean useMongo) { |
| |
| RdfCloudTripleStoreConfiguration conf; |
| Set<RyaURI> propertySet = new HashSet<>( |
| Arrays.asList(new RyaURI("http://createdBy"), new RyaURI("http://createdOn"))); |
| if (useMongo) { |
| MongoDBRdfConfiguration mConf = new MongoDBRdfConfiguration(); |
| mConf.setBoolean("sc.useMongo", true); |
| mConf.setMongoHostname("localhost"); |
| mConf.setMongoPort("27017"); |
| mConf.setMongoDBName("rya_"); |
| conf = mConf; |
| } else { |
| 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.setStatementMetadataProperties(propertySet); |
| return conf; |
| } |
| |
| private static Set<StatementMetadataNode<?>> getExpected(String query) throws MalformedQueryException { |
| ParsedQuery pq = parser.parseQuery(query, null); |
| StatementMetadataExternalSetProvider provider = new StatementMetadataExternalSetProvider( |
| getConf(false)); |
| List<StatementPattern> patterns = StatementPatternCollector.process(pq.getTupleExpr()); |
| JoinSegment<StatementMetadataNode<?>> segment = new JoinSegment<>( |
| new HashSet<QueryModelNode>(patterns), new ArrayList<QueryModelNode>(patterns), |
| new HashMap<ValueExpr, Filter>()); |
| return new HashSet<>(provider.getExternalSets(segment)); |
| } |
| } |