You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by to...@apache.org on 2013/02/21 09:51:32 UTC

svn commit: r1448550 [2/6] - in /jackrabbit/oak/trunk: ./ oak-parent/ oak-solr-core/ oak-solr-core/src/ oak-solr-core/src/main/ oak-solr-core/src/main/java/ oak-solr-core/src/main/java/org/ oak-solr-core/src/main/java/org/apache/ oak-solr-core/src/main...

Added: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,69 @@
+/*
+ * 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.jackrabbit.oak.plugins.index.solr.query;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.jackrabbit.oak.plugins.index.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfigurationProvider;
+import org.apache.jackrabbit.oak.plugins.index.solr.SolrServerProvider;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.buildIndexDefinitions;
+
+/**
+ * {@link QueryIndexProvider} for {@link SolrQueryIndex}
+ */
+@Component
+@Service(QueryIndexProvider.class)
+public class SolrQueryIndexProvider implements QueryIndexProvider {
+
+    private Logger log = LoggerFactory.getLogger(SolrQueryIndexProvider.class);
+
+    @Reference
+    private SolrServerProvider solrServerProvider;
+
+    @Reference
+    private OakSolrConfigurationProvider oakSolrConfigurationProvider;
+
+    @Nonnull
+    @Override
+    public List<? extends QueryIndex> getQueryIndexes(NodeState nodeState) {
+        List<QueryIndex> tempIndexes = new ArrayList<QueryIndex>();
+        for (IndexDefinition child : buildIndexDefinitions(nodeState, "/",
+                SolrQueryIndex.TYPE)) {
+            if (log.isInfoEnabled()) {
+                log.info("found a Solr index definition {}", child);
+            }
+            try {
+                tempIndexes.add(new SolrQueryIndex(child, solrServerProvider.getSolrServer(), oakSolrConfigurationProvider.getConfiguration()));
+            } catch (Exception e) {
+                log.error("unable to create Solr query index at {} due to {}", new Object[]{child.getPath(), e});
+            }
+        }
+        return tempIndexes;
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryIndexProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrBaseTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrBaseTest.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrBaseTest.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrBaseTest.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,65 @@
+/*
+ * 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.jackrabbit.oak.plugins.index.solr;
+
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.core.MicroKernelImpl;
+import org.apache.jackrabbit.oak.core.RootImpl;
+import org.apache.jackrabbit.oak.kernel.KernelNodeStore;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.solr.client.solrj.SolrServer;
+import org.junit.After;
+import org.junit.Before;
+
+/**
+ * Test base class for Oak-Solr
+ */
+public abstract class SolrBaseTest {
+
+    protected KernelNodeStore store;
+    protected NodeState state;
+    protected SolrServer server;
+    protected OakSolrConfiguration configuration;
+
+    @Before
+    public void setUp() throws Exception {
+        MicroKernel microKernel = new MicroKernelImpl();
+        store = new KernelNodeStore(microKernel);
+        state = createInitialState(microKernel);
+        server = TestUtils.createSolrServer();
+        configuration = TestUtils.getTestConfiguration();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        if (server != null && server.ping() != null) {
+            server.deleteByQuery("*:*");
+            server.commit();
+            server = null;
+        }
+    }
+
+    protected NodeState createInitialState(MicroKernel microKernel) {
+        String jsop = "^\"a\":1 ^\"b\":2 ^\"c\":3 +\"x\":{} +\"y\":{} +\"z\":{}";
+        microKernel.commit("/", jsop, microKernel.getHeadRevision(), "test data");
+        return store.getRoot();
+    }
+
+    protected RootImpl createRootImpl() {
+        return new RootImpl(store);
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/SolrBaseTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/TestUtils.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/TestUtils.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/TestUtils.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/TestUtils.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,142 @@
+/*
+ * 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.jackrabbit.oak.plugins.index.solr;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.IndexHook;
+import org.apache.jackrabbit.oak.plugins.index.IndexHookProvider;
+import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfiguration;
+import org.apache.jackrabbit.oak.plugins.index.solr.index.SolrIndexDiff;
+import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
+import org.apache.solr.core.CoreContainer;
+
+import com.google.common.collect.ImmutableList;
+
+import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.buildIndexDefinitions;
+
+/**
+ * Utility class for tests
+ */
+public class TestUtils {
+
+    private static final String SOLR_HOME_PATH = "target/test-classes/solr";
+    private static final String SOLRCONFIG_PATH = "target/test-classes/solr/solr.xml";
+
+    public static OakSolrConfiguration getTestConfiguration() {
+        return new OakSolrConfiguration() {
+            @Override
+            public String getFieldNameFor(Type<?> propertyType) {
+                return null;
+            }
+
+            @Override
+            public String getPathField() {
+                return "path_exact";
+            }
+
+            @Override
+            public String getFieldForPathRestriction(Filter.PathRestriction pathRestriction) {
+                String fieldName = null;
+                switch (pathRestriction) {
+                    case ALL_CHILDREN: {
+                        fieldName = "path_des";
+                        break;
+                    }
+                    case DIRECT_CHILDREN: {
+                        fieldName = "path_child";
+                        break;
+                    }
+                    case EXACT: {
+                        fieldName = "path_exact";
+                        break;
+                    }
+                    case PARENT: {
+                        fieldName = "path_anc";
+                        break;
+                    }
+
+                }
+                return fieldName;
+            }
+
+            @Override
+            public String getFieldForPropertyRestriction(Filter.PropertyRestriction propertyRestriction) {
+                return null;
+            }
+        };
+    }
+
+    public static QueryIndexProvider getTestQueryIndexProvider(final SolrServer solrServer, final OakSolrConfiguration configuration) {
+        return new QueryIndexProvider() {
+            @Nonnull
+            @Override
+            public List<? extends QueryIndex> getQueryIndexes(NodeState nodeState) {
+                List<QueryIndex> tempIndexes = new ArrayList<QueryIndex>();
+                for (IndexDefinition child : buildIndexDefinitions(nodeState, "/",
+                        SolrQueryIndex.TYPE)) {
+                    try {
+                        tempIndexes.add(new SolrQueryIndex(child, solrServer, configuration));
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+                return tempIndexes;
+            }
+        };
+    }
+
+    public static IndexHookProvider getTestIndexHookProvider(final SolrServer solrServer, final OakSolrConfiguration configuration) {
+        return new IndexHookProvider() {
+            @Nonnull
+            @Override
+            public List<? extends IndexHook> getIndexHooks(String s, NodeBuilder nodeBuilder) {
+                if (SolrQueryIndex.TYPE.equals(s)) {
+                    try {
+                        IndexHook indexHook = new SolrIndexDiff(nodeBuilder, solrServer, configuration);
+                        return ImmutableList.of(indexHook);
+                    } catch (Exception e) {
+                        throw new RuntimeException(e);
+                    }
+                }
+                return ImmutableList.of();
+            }
+        };
+
+    }
+
+
+    public static SolrServer createSolrServer() throws Exception {
+        CoreContainer coreContainer = new CoreContainer(SOLR_HOME_PATH);
+        coreContainer.load(SOLR_HOME_PATH, new File(SOLRCONFIG_PATH));
+        return new EmbeddedSolrServer(coreContainer, "oak");
+    }
+
+
+}

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/TestUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,83 @@
+/*
+ * 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.jackrabbit.oak.plugins.index.solr.index;
+
+import javax.security.auth.Subject;
+
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.core.RootImpl;
+import org.apache.jackrabbit.oak.plugins.index.solr.index.SolrCommitHook;
+import org.apache.jackrabbit.oak.plugins.index.solr.SolrBaseTest;
+import org.apache.jackrabbit.oak.spi.query.CompositeQueryIndexProvider;
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.response.QueryResponse;
+import org.apache.solr.common.SolrInputDocument;
+import org.junit.Test;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Integration test for {@link org.apache.jackrabbit.oak.plugins.index.solr.index.SolrCommitHook}
+ */
+public class SolrCommitHookIT extends SolrBaseTest {
+
+    @Override
+    protected RootImpl createRootImpl() {
+        return new RootImpl(store, new SolrCommitHook(server), "solr-commit-hook-it", new Subject(),
+                new OpenSecurityProvider(), new CompositeQueryIndexProvider());
+    }
+
+    @Test
+    public void testAddSomeNodes() throws Exception {
+        Root r = createRootImpl();
+        r.getTree("/").addChild("a").addChild("b").addChild("doc1").
+                setProperty("text", "hit that hot hat tattoo");
+        r.getTree("/").getChild("a").addChild("c").addChild("doc2").
+                setProperty("text", "it hits hot hats");
+        r.getTree("/").getChild("a").getChild("b").addChild("doc3").
+                setProperty("text", "tattoos hate hot hits");
+        r.getTree("/").getChild("a").getChild("b").addChild("doc4").
+                setProperty("text", "hats tattoos hit hot");
+        r.commit();
+
+        SolrQuery query = new SolrQuery();
+        query.setQuery("*:*");
+        QueryResponse queryResponse = server.query(query);
+        assertTrue("no documents were indexed", queryResponse.getResults().size() > 0);
+    }
+
+    @Test
+    public void testRemoveNode() throws Exception {
+        // pre-populate the index with a node that is already in Oak
+        SolrInputDocument doc = new SolrInputDocument();
+        doc.addField("path_exact", "z");
+        server.add(doc);
+        server.commit();
+
+        // remove the node in oak
+        Root r = createRootImpl();
+        r.getTree("/").getChild("z").remove();
+        r.commit();
+
+        // check the node is not in Solr anymore
+        SolrQuery query = new SolrQuery();
+        query.setQuery("path_exact:z");
+        QueryResponse queryResponse = server.query(query);
+        assertTrue("item with id:z was found in the index", queryResponse.getResults().size() == 0);
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookIT.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookTest.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookTest.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookTest.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,89 @@
+/*
+ * 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.jackrabbit.oak.plugins.index.solr.index;
+
+import org.apache.jackrabbit.mk.api.MicroKernel;
+import org.apache.jackrabbit.mk.core.MicroKernelImpl;
+import org.apache.jackrabbit.oak.kernel.KernelNodeStore;
+import org.apache.jackrabbit.oak.plugins.index.solr.index.SolrCommitHook;
+import org.apache.jackrabbit.oak.plugins.index.solr.SolrBaseTest;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Testcase for {@link org.apache.jackrabbit.oak.plugins.index.solr.index.SolrCommitHook}
+ */
+public class SolrCommitHookTest extends SolrBaseTest {
+
+    private KernelNodeStore store;
+
+    @Before
+    public void setUp() throws Exception {
+        super.setUp();
+        MicroKernel microKernel = new MicroKernelImpl();
+        store = new KernelNodeStore(microKernel);
+    }
+
+    @Test
+    public void testNothingHappened() throws Exception {
+        SolrCommitHook solrCommitHook = new SolrCommitHook(server);
+        NodeState before = store.getRoot().builder().getNodeState();
+        NodeState after = store.getRoot().builder().getNodeState();
+        NodeState changedState = solrCommitHook.processCommit(before, after);
+        assertEquals(after, changedState);
+    }
+
+    @Test
+    public void testAddNode() throws Exception {
+        SolrCommitHook solrCommitHook = new SolrCommitHook(server);
+        NodeState before = store.getRoot().builder().getNodeState();
+        NodeState after = store.getRoot().builder().child("somechild").getNodeState();
+        NodeState changedState = solrCommitHook.processCommit(before, after);
+        assertEquals(after, changedState);
+    }
+
+    @Test
+    public void testRemoveNode() throws Exception {
+        SolrCommitHook solrCommitHook = new SolrCommitHook(server);
+        NodeState before = store.getRoot().builder().child("somechild").getNodeState();
+        NodeState after = before.builder().removeNode("somechild").getNodeState();
+        NodeState changedState = solrCommitHook.processCommit(before, after);
+        assertEquals(after, changedState);
+    }
+
+    @Test
+    public void testPropertyAdded() throws Exception {
+        SolrCommitHook solrCommitHook = new SolrCommitHook(server);
+        NodeState before = store.getRoot().builder().getNodeState();
+        NodeState after = before.builder().setProperty("p", "v").getNodeState();
+        NodeState changedState = solrCommitHook.processCommit(before, after);
+        assertEquals(after, changedState);
+    }
+
+    @Test
+    public void testPropertyRemoved() throws Exception {
+        SolrCommitHook solrCommitHook = new SolrCommitHook(server);
+        NodeState before = store.getRoot().builder().setProperty("p", "v").getNodeState();
+        NodeState after = before.builder().removeProperty("p").getNodeState();
+        NodeState changedState = solrCommitHook.processCommit(before, after);
+        assertEquals(after, changedState);
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrCommitHookTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiffIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiffIT.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiffIT.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiffIT.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,190 @@
+/*
+ * 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.jackrabbit.oak.plugins.index.solr.index;
+
+import org.apache.jackrabbit.oak.plugins.index.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.IndexDefinitionImpl;
+import org.apache.jackrabbit.oak.plugins.index.IndexHook;
+import org.apache.jackrabbit.oak.plugins.index.solr.index.SolrIndexDiff;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState;
+import org.apache.jackrabbit.oak.query.ast.Operator;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.plugins.index.solr.SolrBaseTest;
+import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex;
+import org.apache.jackrabbit.oak.spi.query.Cursor;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.IndexRow;
+import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+
+public class SolrIndexDiffIT extends SolrBaseTest {
+
+    @Test
+    public void testSingleNodeCreation() throws Exception {
+        NodeState root = MemoryNodeState.EMPTY_NODE;
+
+        NodeBuilder builder = root.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty(JCR_PRIMARYTYPE, "oak:queryIndexDefinition")
+                .setProperty("type", "solr");
+
+        NodeState before = builder.getNodeState();
+        builder.child("newnode").setProperty("prop", "val");
+        NodeState after = builder.getNodeState();
+
+        IndexHook l = new SolrIndexDiff(builder, server, configuration);
+        after.compareAgainstBaseState(before, l);
+        l.apply();
+        l.close();
+
+        IndexDefinition testDef = new IndexDefinitionImpl("solr",
+                "solr", "/oak:index/solr");
+        QueryIndex queryIndex = new SolrQueryIndex(testDef, server, configuration);
+        FilterImpl filter = new FilterImpl(null, null);
+        filter.restrictPath("/newnode", Filter.PathRestriction.EXACT);
+        filter.restrictProperty("prop", Operator.EQUAL,
+                PropertyValues.newString("val"));
+        Cursor cursor = queryIndex.query(filter, builder.getNodeState());
+        assertNotNull(cursor);
+        assertTrue("no results found", cursor.hasNext());
+        IndexRow next = cursor.next();
+        assertNotNull("first returned item should not be null", next);
+        assertEquals("/newnode", next.getPath());
+        assertFalse(cursor.hasNext());
+    }
+
+    @Test
+    public void testPropertyAddition() throws Exception {
+        NodeState root = MemoryNodeState.EMPTY_NODE;
+
+        NodeBuilder builder = root.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty(JCR_PRIMARYTYPE, "oak:queryIndexDefinition")
+                .setProperty("type", "solr");
+
+        NodeState before = builder.getNodeState();
+        builder.setProperty("foo", "bar");
+        NodeState after = builder.getNodeState();
+
+        IndexHook l = new SolrIndexDiff(builder, server, configuration);
+        after.compareAgainstBaseState(before, l);
+        l.apply();
+        l.close();
+
+        IndexDefinition testDef = new IndexDefinitionImpl("solr",
+                "solr", "/oak:index/solr");
+        QueryIndex queryIndex = new SolrQueryIndex(testDef, server, configuration);
+        FilterImpl filter = new FilterImpl(null, null);
+        filter.restrictProperty("foo", Operator.EQUAL,
+                PropertyValues.newString("bar"));
+        Cursor cursor = queryIndex.query(filter, builder.getNodeState());
+        assertNotNull(cursor);
+        assertTrue("no results found", cursor.hasNext());
+        IndexRow next = cursor.next();
+        assertNotNull("first returned item should not be null", next);
+        assertEquals("/", next.getPath());
+        assertNotNull(next.getValue("foo"));
+        assertEquals(PropertyValues.newString("[bar]"), next.getValue("foo"));
+        assertFalse(cursor.hasNext());
+    }
+
+    @Test
+    public void testSomeNodesCreationWithFullText() throws Exception {
+        NodeState root = MemoryNodeState.EMPTY_NODE;
+
+        NodeBuilder builder = root.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty(JCR_PRIMARYTYPE, "oak:queryIndexDefinition")
+                .setProperty("type", "solr");
+
+        NodeState before = builder.getNodeState();
+        builder.setProperty("foo", "bar");
+        builder.child("a").setProperty("foo", "bar");
+        builder.child("a").child("b").setProperty("foo", "bar");
+        builder.child("a").child("b").child("c").setProperty("foo", "bar");
+
+        NodeState after = builder.getNodeState();
+
+        IndexHook l = new SolrIndexDiff(builder, server, configuration);
+        after.compareAgainstBaseState(before, l);
+        l.apply();
+        l.close();
+
+        IndexDefinition testDef = new IndexDefinitionImpl("solr",
+                "solr", "/oak:index/solr");
+        QueryIndex queryIndex = new SolrQueryIndex(testDef, server, configuration);
+        FilterImpl filter = new FilterImpl(null, null);
+        filter.restrictProperty("foo", Operator.EQUAL,
+                PropertyValues.newString("bar"));
+        filter.restrictFulltextCondition("bar");
+        Cursor cursor = queryIndex.query(filter, builder.getNodeState());
+
+        assertTrue(cursor.hasNext());
+        assertEquals("/", cursor.next().getPath());
+        assertEquals("/a", cursor.next().getPath());
+        assertEquals("/a/b", cursor.next().getPath());
+        assertEquals("/a/b/c", cursor.next().getPath());
+        assertFalse(cursor.hasNext());
+    }
+
+    @Test
+    public void testSomeNodesCreationWithDescendant() throws Exception {
+        NodeState root = MemoryNodeState.EMPTY_NODE;
+
+        NodeBuilder builder = root.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty(JCR_PRIMARYTYPE, "oak:queryIndexDefinition")
+                .setProperty("type", "solr");
+
+        NodeState before = builder.getNodeState();
+        builder.setProperty("foo", "bar");
+        builder.child("a").setProperty("foo", "bar");
+        builder.child("a").child("b").setProperty("foo", "bar");
+        builder.child("a").child("b").child("c").setProperty("foo", "bar");
+
+        NodeState after = builder.getNodeState();
+
+        IndexHook l = new SolrIndexDiff(builder, server, configuration);
+        after.compareAgainstBaseState(before, l);
+        l.apply();
+        l.close();
+
+        IndexDefinition testDef = new IndexDefinitionImpl("solr",
+                "solr", "/oak:index/solr");
+        QueryIndex queryIndex = new SolrQueryIndex(testDef, server, configuration);
+        FilterImpl filter = new FilterImpl(null, null);
+        filter.restrictPath("/a", Filter.PathRestriction.ALL_CHILDREN);
+        Cursor cursor = queryIndex.query(filter, builder.getNodeState());
+
+        assertTrue(cursor.hasNext());
+        assertEquals("/a", cursor.next().getPath());
+        assertEquals("/a/b", cursor.next().getPath());
+        assertEquals("/a/b/c", cursor.next().getPath());
+        assertFalse(cursor.hasNext());
+    }
+
+
+}

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexDiffIT.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,153 @@
+/*
+ * 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.jackrabbit.oak.plugins.index.solr.index;
+
+import org.apache.jackrabbit.oak.plugins.index.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.IndexDefinitionImpl;
+import org.apache.jackrabbit.oak.plugins.index.IndexHook;
+import org.apache.jackrabbit.oak.plugins.index.solr.index.SolrIndexHook;
+import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeState;
+import org.apache.jackrabbit.oak.query.ast.Operator;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.plugins.index.solr.SolrBaseTest;
+import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex;
+import org.apache.jackrabbit.oak.spi.query.Cursor;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.IndexRow;
+import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
+
+public class SolrIndexHookIT extends SolrBaseTest {
+
+    @Test
+    public void testSingleNodeCreation() throws Exception {
+        NodeState root = MemoryNodeState.EMPTY_NODE;
+
+        NodeBuilder builder = root.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty(JCR_PRIMARYTYPE, "oak:queryIndexDefinition")
+                .setProperty("type", "solr");
+
+        NodeState before = builder.getNodeState();
+        builder.child("newnode").setProperty("prop", "val");
+        NodeState after = builder.getNodeState();
+
+        IndexHook l = new SolrIndexHook("/", builder, server);
+        after.compareAgainstBaseState(before, l);
+        l.apply();
+        l.close();
+
+        IndexDefinition testDef = new IndexDefinitionImpl("solr",
+                "solr", "/oak:index/solr");
+        QueryIndex queryIndex = new SolrQueryIndex(testDef, server, configuration);
+        FilterImpl filter = new FilterImpl(null, null);
+        filter.restrictPath("newnode", Filter.PathRestriction.EXACT);
+        filter.restrictProperty("prop", Operator.EQUAL,
+                PropertyValues.newString("val"));
+        Cursor cursor = queryIndex.query(filter, builder.getNodeState());
+        assertNotNull(cursor);
+        assertTrue("no results found", cursor.hasNext());
+        IndexRow next = cursor.next();
+        assertNotNull("first returned item should not be null", next);
+        assertEquals("newnode", next.getPath());
+        assertFalse(cursor.hasNext());
+    }
+
+    @Test
+    public void testPropertyAddition() throws Exception {
+        NodeState root = MemoryNodeState.EMPTY_NODE;
+
+        NodeBuilder builder = root.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty(JCR_PRIMARYTYPE, "oak:queryIndexDefinition")
+                .setProperty("type", "solr");
+
+        NodeState before = builder.getNodeState();
+        builder.setProperty("foo", "bar");
+        NodeState after = builder.getNodeState();
+
+        IndexHook l = new SolrIndexHook("/", builder, server);
+        after.compareAgainstBaseState(before, l);
+        l.apply();
+        l.close();
+
+        IndexDefinition testDef = new IndexDefinitionImpl("solr",
+                "solr", "/oak:index/solr");
+        QueryIndex queryIndex = new SolrQueryIndex(testDef, server, configuration);
+        FilterImpl filter = new FilterImpl(null, null);
+        filter.restrictProperty("foo", Operator.EQUAL,
+                PropertyValues.newString("bar"));
+        Cursor cursor = queryIndex.query(filter, builder.getNodeState());
+        assertNotNull(cursor);
+        assertTrue("no results found", cursor.hasNext());
+        IndexRow next = cursor.next();
+        assertNotNull("first returned item should not be null", next);
+        assertEquals("/", next.getPath());
+        assertNotNull(next.getValue("foo"));
+        assertEquals(PropertyValues.newString("[bar]"), next.getValue("foo"));
+        assertFalse(cursor.hasNext());
+    }
+
+    @Test
+    public void testSomeNodesCreationWithFullText() throws Exception {
+        NodeState root = MemoryNodeState.EMPTY_NODE;
+
+        NodeBuilder builder = root.builder();
+        builder.child("oak:index").child("solr")
+                .setProperty(JCR_PRIMARYTYPE, "oak:queryIndexDefinition")
+                .setProperty("type", "solr");
+
+        NodeState before = builder.getNodeState();
+        builder.setProperty("foo", "bar");
+        builder.child("a").setProperty("foo", "bar");
+        builder.child("a").child("b").setProperty("foo", "bar");
+        builder.child("a").child("b").child("c").setProperty("foo", "bar");
+
+        NodeState after = builder.getNodeState();
+
+        IndexHook l = new SolrIndexHook("/", builder, server);
+        after.compareAgainstBaseState(before, l);
+        l.apply();
+        l.close();
+
+        IndexDefinition testDef = new IndexDefinitionImpl("solr",
+                "solr", "/oak:index/solr");
+        QueryIndex queryIndex = new SolrQueryIndex(testDef, server, configuration);
+        FilterImpl filter = new FilterImpl(null, null);
+        filter.restrictProperty("foo", Operator.EQUAL,
+                PropertyValues.newString("bar"));
+        filter.restrictFulltextCondition("bar");
+        Cursor cursor = queryIndex.query(filter, builder.getNodeState());
+
+        assertTrue(cursor.hasNext());
+        assertEquals("/", cursor.next().getPath());
+        assertEquals("a", cursor.next().getPath());
+        assertEquals("a/b", cursor.next().getPath());
+        assertEquals("a/b/c", cursor.next().getPath());
+        assertFalse(cursor.hasNext());
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/index/SolrIndexHookIT.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTest.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTest.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTest.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,134 @@
+/*
+ * 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.jackrabbit.oak.plugins.index.solr.query;
+
+import java.util.Iterator;
+
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.api.ContentRepository;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
+import org.apache.jackrabbit.oak.query.AbstractQueryTest;
+import org.apache.jackrabbit.oak.query.JsopUtil;
+import org.apache.jackrabbit.oak.plugins.index.solr.OakSolrConfiguration;
+import org.apache.jackrabbit.oak.plugins.index.solr.TestUtils;
+import org.apache.solr.client.solrj.SolrServer;
+import org.junit.After;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * General query extensive testcase for {@link org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex} and {@link org.apache.jackrabbit.oak.plugins.index.solr.index.SolrIndexDiff}
+ */
+public class SolrIndexQueryTest extends AbstractQueryTest {
+
+    private SolrServer solrServer;
+
+    @After
+    public void tearDown() throws Exception {
+        solrServer.deleteByQuery("*:*");
+        solrServer.commit();
+    }
+
+    @Override
+    protected void createTestIndexNode() throws Exception {
+        Tree index = root.getTree("/");
+        createTestIndexNode(index, SolrQueryIndex.TYPE);
+        root.commit();
+    }
+
+    @Override
+    protected ContentRepository createRepository() {
+        OakSolrConfiguration testConfiguration = TestUtils.getTestConfiguration();
+        try {
+            solrServer = TestUtils.createSolrServer();
+            return new Oak().with(new InitialContent())
+                    .with(TestUtils.getTestQueryIndexProvider(solrServer, testConfiguration))
+                    .with(TestUtils.getTestIndexHookProvider(solrServer, testConfiguration))
+                    .createContentRepository();
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Test
+    @Ignore("failing")
+    public void sql2() throws Exception {
+        test("sql2.txt");
+    }
+
+    @Test
+    @Ignore("OAK-420")
+    public void sql2Measure() throws Exception {
+        test("sql2_measure.txt");
+    }
+
+    @Test
+    public void descendantTest() throws Exception {
+        JsopUtil.apply(root, "/ + \"test\": { \"a\": {}, \"b\": {} }");
+        root.commit();
+
+        Iterator<String> result = executeQuery(
+                "select * from [nt:base] where isdescendantnode('/test')",
+                "JCR-SQL2").iterator();
+        assertTrue(result.hasNext());
+        assertEquals("/test/a", result.next());
+        assertEquals("/test/b", result.next());
+        assertFalse(result.hasNext());
+    }
+
+    @Test
+    public void descendantTest2() throws Exception {
+        JsopUtil.apply(
+                root,
+                "/ + \"test\": { \"a\": { \"name\": [\"Hello\", \"World\" ] }, \"b\": { \"name\" : \"Hello\" }}");
+        root.commit();
+
+        Iterator<String> result = executeQuery(
+                "select * from [nt:base] where isdescendantnode('/test') and name='World'",
+                "JCR-SQL2").iterator();
+        assertTrue(result.hasNext());
+        assertEquals("/test/a", result.next());
+        assertFalse(result.hasNext());
+    }
+
+    @Test
+    public void ischildnodeTest() throws Exception {
+        JsopUtil.apply(
+                root,
+                "/ + \"parents\": { \"p0\": {\"id\": \"0\"}, \"p1\": {\"id\": \"1\"}, \"p2\": {\"id\": \"2\"}}");
+        JsopUtil.apply(
+                root,
+                "/ + \"children\": { \"c1\": {\"p\": \"1\"}, \"c2\": {\"p\": \"1\"}, \"c3\": {\"p\": \"2\"}, \"c4\": {\"p\": \"3\"}}");
+        root.commit();
+
+        Iterator<String> result = executeQuery(
+                "select * from [nt:base] as p inner join [nt:base] as p2 on ischildnode(p2, p) where p.[jcr:path] = '/'",
+                "JCR-SQL2").iterator();
+        assertTrue(result.hasNext());
+        assertEquals("/, /children", result.next());
+        assertEquals("/, /jcr:system", result.next());
+        assertEquals("/, /oak:index", result.next());
+        assertEquals("/, /parents", result.next());
+        assertFalse(result.hasNext());
+    }
+}

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrIndexQueryTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryEngineIT.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryEngineIT.java?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryEngineIT.java (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryEngineIT.java Thu Feb 21 08:51:30 2013
@@ -0,0 +1,77 @@
+/*
+ * 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.jackrabbit.oak.plugins.index.solr.query;
+
+import javax.security.auth.Subject;
+
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.core.RootImpl;
+import org.apache.jackrabbit.oak.plugins.index.IndexDefinition;
+import org.apache.jackrabbit.oak.plugins.index.IndexDefinitionImpl;
+import org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex;
+import org.apache.jackrabbit.oak.query.ast.Operator;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.plugins.index.solr.SolrBaseTest;
+import org.apache.jackrabbit.oak.plugins.index.solr.index.SolrCommitHook;
+import org.apache.jackrabbit.oak.spi.query.CompositeQueryIndexProvider;
+import org.apache.jackrabbit.oak.spi.query.Cursor;
+import org.apache.jackrabbit.oak.spi.query.Filter;
+import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.query.QueryIndex;
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.junit.Test;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.assertTrue;
+
+/**
+ * Integration test for {@link org.apache.jackrabbit.oak.plugins.index.solr.query.SolrQueryIndex} and {@link org.apache.jackrabbit.oak.plugins.index.solr.index.SolrCommitHook} working
+ * together
+ */
+public class SolrQueryEngineIT extends SolrBaseTest {
+
+    @Override
+    protected RootImpl createRootImpl() {
+        return new RootImpl(store, new SolrCommitHook(server), "solr-query-engine-it", new Subject(),
+                new OpenSecurityProvider(), new CompositeQueryIndexProvider());
+    }
+
+    @Test
+    public void testSolrQueryEngine() throws Exception {
+        IndexDefinition testID = new IndexDefinitionImpl("solr-test",
+                "solr", "/");
+        Root root = createRootImpl();
+        Tree tree = root.getTree("/");
+
+        tree.addChild("somenode").setProperty("foo", "bar");
+        root.commit();
+
+        QueryIndex index = new SolrQueryIndex(testID, server, configuration);
+        FilterImpl filter = new FilterImpl(null, null);
+        filter.restrictPath("somenode", Filter.PathRestriction.EXACT);
+        filter.restrictProperty("foo", Operator.EQUAL, PropertyValues.newString("bar"));
+        Cursor cursor = index.query(filter, store.getRoot());
+        assertNotNull(cursor);
+        assertTrue(cursor.hasNext());
+        assertEquals("somenode", cursor.next().getPath());
+        assertFalse(cursor.hasNext());
+    }
+
+}

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/solr/query/SolrQueryEngineIT.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/currency.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/currency.xml?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/currency.xml (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/currency.xml Thu Feb 21 08:51:30 2013
@@ -0,0 +1,67 @@
+<?xml version="1.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.
+-->
+
+<!-- Example exchange rates file for CurrencyField type named "currency" in example schema -->
+
+<currencyConfig version="1.0">
+  <rates>
+    <!-- Updated from http://www.exchangerate.com/ at 2011-09-27 -->
+    <rate from="USD" to="ARS" rate="4.333871" comment="ARGENTINA Peso" />
+    <rate from="USD" to="AUD" rate="1.025768" comment="AUSTRALIA Dollar" />
+    <rate from="USD" to="EUR" rate="0.743676" comment="European Euro" />
+    <rate from="USD" to="BRL" rate="1.881093" comment="BRAZIL Real" />
+    <rate from="USD" to="CAD" rate="1.030815" comment="CANADA Dollar" />
+    <rate from="USD" to="CLP" rate="519.0996" comment="CHILE Peso" />
+    <rate from="USD" to="CNY" rate="6.387310" comment="CHINA Yuan" />
+    <rate from="USD" to="CZK" rate="18.47134" comment="CZECH REP. Koruna" />
+    <rate from="USD" to="DKK" rate="5.515436" comment="DENMARK Krone" />
+    <rate from="USD" to="HKD" rate="7.801922" comment="HONG KONG Dollar" />
+    <rate from="USD" to="HUF" rate="215.6169" comment="HUNGARY Forint" />
+    <rate from="USD" to="ISK" rate="118.1280" comment="ICELAND Krona" />
+    <rate from="USD" to="INR" rate="49.49088" comment="INDIA Rupee" />
+    <rate from="USD" to="XDR" rate="0.641358" comment="INTNL MON. FUND SDR" />
+    <rate from="USD" to="ILS" rate="3.709739" comment="ISRAEL Sheqel" />
+    <rate from="USD" to="JPY" rate="76.32419" comment="JAPAN Yen" />
+    <rate from="USD" to="KRW" rate="1169.173" comment="KOREA (SOUTH) Won" />
+    <rate from="USD" to="KWD" rate="0.275142" comment="KUWAIT Dinar" />
+    <rate from="USD" to="MXN" rate="13.85895" comment="MEXICO Peso" />
+    <rate from="USD" to="NZD" rate="1.285159" comment="NEW ZEALAND Dollar" />
+    <rate from="USD" to="NOK" rate="5.859035" comment="NORWAY Krone" />
+    <rate from="USD" to="PKR" rate="87.57007" comment="PAKISTAN Rupee" />
+    <rate from="USD" to="PEN" rate="2.730683" comment="PERU Sol" />
+    <rate from="USD" to="PHP" rate="43.62039" comment="PHILIPPINES Peso" />
+    <rate from="USD" to="PLN" rate="3.310139" comment="POLAND Zloty" />
+    <rate from="USD" to="RON" rate="3.100932" comment="ROMANIA Leu" />
+    <rate from="USD" to="RUB" rate="32.14663" comment="RUSSIA Ruble" />
+    <rate from="USD" to="SAR" rate="3.750465" comment="SAUDI ARABIA Riyal" />
+    <rate from="USD" to="SGD" rate="1.299352" comment="SINGAPORE Dollar" />
+    <rate from="USD" to="ZAR" rate="8.329761" comment="SOUTH AFRICA Rand" />
+    <rate from="USD" to="SEK" rate="6.883442" comment="SWEDEN Krona" />
+    <rate from="USD" to="CHF" rate="0.906035" comment="SWITZERLAND Franc" />
+    <rate from="USD" to="TWD" rate="30.40283" comment="TAIWAN Dollar" />
+    <rate from="USD" to="THB" rate="30.89487" comment="THAILAND Baht" />
+    <rate from="USD" to="AED" rate="3.672955" comment="U.A.E. Dirham" />
+    <rate from="USD" to="UAH" rate="7.988582" comment="UKRAINE Hryvnia" />
+    <rate from="USD" to="GBP" rate="0.647910" comment="UNITED KINGDOM Pound" />
+    
+    <!-- Cross-rates for some common currencies -->
+    <rate from="EUR" to="GBP" rate="0.869914" />  
+    <rate from="EUR" to="NOK" rate="7.800095" />  
+    <rate from="GBP" to="NOK" rate="8.966508" />  
+  </rates>
+</currencyConfig>

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/currency.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/protwords.txt
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/protwords.txt?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/protwords.txt (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/protwords.txt Thu Feb 21 08:51:30 2013
@@ -0,0 +1,14 @@
+# 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.

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/protwords.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Added: jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/schema.xml
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/schema.xml?rev=1448550&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/schema.xml (added)
+++ jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/schema.xml Thu Feb 21 08:51:30 2013
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+ 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.
+-->
+<schema name="minimal" version="1.5">
+    <types>
+        <fieldType name="string" class="solr.StrField"/>
+        <fieldType name="descendent_path" class="solr.TextField">
+            <analyzer type="index">
+                <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/" />
+            </analyzer>
+            <analyzer type="query">
+                <tokenizer class="solr.KeywordTokenizerFactory" />
+            </analyzer>
+        </fieldType>
+        <fieldType name="children_path" class="solr.TextField">
+            <analyzer type="index">
+                <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/" skip="1" reverse="true" />
+                <filter class="solr.PatternReplaceFilterFactory" pattern="/" replacement="" replace="all"/>
+            </analyzer>
+            <analyzer type="query">
+                <tokenizer class="solr.KeywordTokenizerFactory" />
+                <filter class="solr.PatternReplaceFilterFactory" pattern="/" replacement="" replace="all"/>
+            </analyzer>
+        </fieldType>
+        <fieldType name="parent_path" class="solr.TextField">
+            <analyzer type="index">
+                <tokenizer class="solr.KeywordTokenizerFactory" />
+                <filter class="solr.PatternReplaceFilterFactory" pattern="/" replacement="" replace="all"/>
+            </analyzer>
+            <analyzer type="query">
+                <tokenizer class="solr.PathHierarchyTokenizerFactory" delimiter="/" skip="1" reverse="true"/>
+                <filter class="solr.PatternReplaceFilterFactory" pattern="/" replacement="" replace="all"/>
+            </analyzer>
+        </fieldType>
+        <fieldType name="text_keepcase" class="solr.TextField" positionIncrementGap="100">
+            <analyzer type="index">
+                <tokenizer class="solr.StandardTokenizerFactory"/>
+            </analyzer>
+            <analyzer type="query">
+                <tokenizer class="solr.StandardTokenizerFactory"/>
+            </analyzer>
+        </fieldType>
+        <fieldType name="text_general" class="solr.TextField" positionIncrementGap="100">
+            <analyzer type="index">
+                <tokenizer class="solr.StandardTokenizerFactory"/>
+                <filter class="solr.LowerCaseFilterFactory"/>
+            </analyzer>
+            <analyzer type="query">
+                <tokenizer class="solr.StandardTokenizerFactory"/>
+                <filter class="solr.LowerCaseFilterFactory"/>
+            </analyzer>
+        </fieldType>
+
+        <fieldType name="boolean" class="solr.BoolField" sortMissingLast="true"/>
+
+        <fieldType name="int" class="solr.TrieIntField" precisionStep="0" positionIncrementGap="0"/>
+        <fieldType name="float" class="solr.TrieFloatField" precisionStep="0" positionIncrementGap="0"/>
+        <fieldType name="long" class="solr.TrieLongField" precisionStep="0" positionIncrementGap="0"/>
+        <fieldType name="double" class="solr.TrieDoubleField" precisionStep="0" positionIncrementGap="0"/>
+
+        <fieldType name="tint" class="solr.TrieIntField" precisionStep="8" positionIncrementGap="0"/>
+        <fieldType name="tfloat" class="solr.TrieFloatField" precisionStep="8" positionIncrementGap="0"/>
+        <fieldType name="tlong" class="solr.TrieLongField" precisionStep="8" positionIncrementGap="0"/>
+        <fieldType name="tdouble" class="solr.TrieDoubleField" precisionStep="8" positionIncrementGap="0"/>
+        <fieldType name="date" class="solr.TrieDateField" precisionStep="0" positionIncrementGap="0"/>
+
+        <fieldType name="tdate" class="solr.TrieDateField" precisionStep="6" positionIncrementGap="0"/>
+
+        <fieldtype name="binary" class="solr.BinaryField"/>
+
+        <fieldType name="pint" class="solr.IntField"/>
+        <fieldType name="plong" class="solr.LongField"/>
+        <fieldType name="pfloat" class="solr.FloatField"/>
+        <fieldType name="pdouble" class="solr.DoubleField"/>
+        <fieldType name="pdate" class="solr.DateField" sortMissingLast="true"/>
+
+        <fieldType name="point" class="solr.PointType" dimension="2" subFieldSuffix="_d"/>
+
+        <fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>
+
+        <fieldType name="location_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
+                   geo="true" distErrPct="0.025" maxDistErr="0.000009" units="degrees" />
+
+        <fieldType name="currency" class="solr.CurrencyField" precisionStep="8" defaultCurrency="USD" currencyConfig="currency.xml" />
+
+    </types>
+    <fields>
+        <field name="path_exact" type="string" indexed="true" stored="true"/>
+        <field name="path_child" type="children_path" indexed="true" stored="false"/>
+        <field name="path_anc" type="parent_path" indexed="true" stored="false"/>
+        <field name="path_des" type="descendent_path" indexed="true" stored="false"/>
+        <field name="catch_all" type="text_general" indexed="true" stored="false" multiValued="true"/>
+        <field name="_version_" type="long" indexed="true" stored="true"/>
+
+        <dynamicField name="*_i"  type="int"    indexed="true"  stored="true"/>
+        <dynamicField name="*_is" type="int"    indexed="true"  stored="true"  multiValued="true"/>
+        <dynamicField name="*_s"  type="string"  indexed="true"  stored="true" />
+        <dynamicField name="*_ss" type="string"  indexed="true"  stored="true" multiValued="true"/>
+        <dynamicField name="*_l"  type="long"   indexed="true"  stored="true"/>
+        <dynamicField name="*_ls" type="long"   indexed="true"  stored="true"  multiValued="true"/>
+        <dynamicField name="*_t"  type="text_general"    indexed="true"  stored="true"/>
+        <dynamicField name="*_txt" type="text_general"   indexed="true"  stored="true" multiValued="true"/>
+        <dynamicField name="*_b"  type="boolean" indexed="true" stored="true"/>
+        <dynamicField name="*_bs" type="boolean" indexed="true" stored="true"  multiValued="true"/>
+        <dynamicField name="*_f"  type="float"  indexed="true"  stored="true"/>
+        <dynamicField name="*_fs" type="float"  indexed="true"  stored="true"  multiValued="true"/>
+        <dynamicField name="*_d"  type="double" indexed="true"  stored="true"/>
+        <dynamicField name="*_ds" type="double" indexed="true"  stored="true"  multiValued="true"/>
+
+        <dynamicField name="*_coordinate"  type="tdouble" indexed="true"  stored="false" />
+
+        <dynamicField name="*_dt"  type="date"    indexed="true"  stored="true"/>
+        <dynamicField name="*_dts" type="date"    indexed="true"  stored="true" multiValued="true"/>
+        <dynamicField name="*_p"  type="location" indexed="true" stored="true"/>
+
+        <dynamicField name="*_ti" type="tint"    indexed="true"  stored="true"/>
+        <dynamicField name="*_tl" type="tlong"   indexed="true"  stored="true"/>
+        <dynamicField name="*_tf" type="tfloat"  indexed="true"  stored="true"/>
+        <dynamicField name="*_td" type="tdouble" indexed="true"  stored="true"/>
+        <dynamicField name="*_tdt" type="tdate"  indexed="true"  stored="true"/>
+
+        <dynamicField name="*_pi"  type="pint"    indexed="true"  stored="true"/>
+        <dynamicField name="*_c"   type="currency" indexed="true"  stored="true"/>
+        <dynamicField name="*" type="text_keepcase" indexed="true" stored="true" multiValued="true"/>
+    </fields>
+    <uniqueKey>path_exact</uniqueKey>
+    <copyField source="path_exact" dest="path_anc"/>
+    <copyField source="path_exact" dest="path_des"/>
+    <copyField source="path_exact" dest="path_child"/>
+    <copyField source="*" dest="catch_all"/>
+</schema>

Propchange: jackrabbit/oak/trunk/oak-solr-core/src/test/resources/solr/oak/conf/schema.xml
------------------------------------------------------------------------------
    svn:eol-style = native