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 ca...@apache.org on 2015/12/15 23:27:59 UTC
svn commit: r1720262 -
/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAugmentTest.java
Author: catholicon
Date: Tue Dec 15 22:27:59 2015
New Revision: 1720262
URL: http://svn.apache.org/viewvc?rev=1720262&view=rev
Log:
OAK-3576: Allow custom extension to augment indexed lucene documents
OAK-3789: Index definition for properties should allow "not creating any fields" for that property
Test cases for the mentioned issues
Added:
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAugmentTest.java (with props)
Added: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAugmentTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAugmentTest.java?rev=1720262&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAugmentTest.java (added)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAugmentTest.java Tue Dec 15 22:27:59 2015
@@ -0,0 +1,271 @@
+/*
+ * 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.lucene;
+
+import com.google.common.collect.Lists;
+import org.apache.commons.io.IOUtils;
+import org.apache.jackrabbit.JcrConstants;
+import org.apache.jackrabbit.oak.Oak;
+import org.apache.jackrabbit.oak.api.ContentRepository;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.lucene.indexAugment.IndexAugmentorFactory;
+import org.apache.jackrabbit.oak.plugins.index.lucene.indexAugment.impl.IndexAugmentorFactoryImpl;
+import org.apache.jackrabbit.oak.plugins.index.lucene.score.ScorerProviderFactory;
+import org.apache.jackrabbit.oak.plugins.index.lucene.spi.FulltextQueryTermsProvider;
+import org.apache.jackrabbit.oak.plugins.index.lucene.spi.IndexFieldProvider;
+import org.apache.jackrabbit.oak.plugins.nodetype.write.NodeTypeRegistry;
+import org.apache.jackrabbit.oak.query.AbstractQueryTest;
+import org.apache.jackrabbit.oak.spi.commit.Observer;
+import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
+import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.StringField;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.junit.Test;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+
+public class LuceneIndexAugmentTest extends AbstractQueryTest {
+ private final SimpleIndexAugmentorFactory factory = new SimpleIndexAugmentorFactory();
+
+ @Override
+ protected void createTestIndexNode() throws Exception {
+ setTraversalEnabled(false);
+ }
+
+ @Override
+ protected ContentRepository createRepository() {
+ LuceneIndexEditorProvider editorProvider = new LuceneIndexEditorProvider(null,
+ new ExtractedTextCache(0, 0),
+ factory);
+ LuceneIndexProvider provider = new LuceneIndexProvider(new IndexTracker(),
+ ScorerProviderFactory.DEFAULT,
+ factory);
+ return new Oak()
+ .with(new OpenSecurityProvider())
+ .with((QueryIndexProvider) provider)
+ .with((Observer) provider)
+ .with(editorProvider)
+ .createContentRepository();
+ }
+
+ //OAK-3789
+ @Test
+ public void skipDefaultIndexing() throws Exception {
+ //setup repo and index
+ NodeTypeRegistry.register(root, IOUtils.toInputStream(TestUtil.TEST_NODE_TYPE), "test nodeType");
+ Tree props = createIndex(TestUtil.NT_TEST);
+
+ Tree prop = TestUtil.enablePropertyIndex(props, "subChild/foo", false);
+ prop.setProperty(LuceneIndexConstants.PROP_SKIP_DEFAULT_INDEXING, true);
+
+ prop = TestUtil.enablePropertyIndex(props, "foo1", false);
+ prop.setProperty(LuceneIndexConstants.PROP_SKIP_DEFAULT_INDEXING, true);
+
+ root.commit();
+
+ //add content
+ Tree test = root.getTree("/").addChild("test");
+ Tree node = createNodeWithType(test, "item1", TestUtil.NT_TEST);
+ node.setProperty("foo1", "bar1");
+ Tree subChild = node.addChild("subChild");
+ subChild.setProperty("foo", "bar");
+ root.commit();
+
+ //queries
+ String query = "select * from [oak:TestNode] AS s where [subChild/foo]='bar'";
+ List<String> paths = executeQuery(query, SQL2);
+ assertEquals("There should not be any rows", 0, paths.size());
+
+ query = "select * from [oak:TestNode] AS s where [foo1]='bar1'";
+ paths = executeQuery(query, SQL2);
+ assertEquals("There should not be any rows", 0, paths.size());
+ }
+
+ //OAK-3576
+ @Test public void queryHook() throws Exception {
+ //setup repo and index
+ NodeTypeRegistry.register(root, IOUtils.toInputStream(TestUtil.TEST_NODE_TYPE), "test nodeType");
+ Tree props = createIndex(TestUtil.NT_TEST);
+ TestUtil.enableForFullText(props, "foo");
+ root.commit();
+
+ //setup query augmentor
+ final String searchText = "search this text";
+ factory.fulltextQueryTermsProvider = new FulltextQueryTermsProvider() {
+ @Override
+ public Query getQueryTerm(String text, Analyzer analyzer) {
+ assertEquals("Full text term passed to provider isn't same as the one passed in query",
+ searchText, text);
+ return new TermQuery(new Term(":fulltext", "bar"));
+ }
+ };
+
+ //add content
+ Tree test = root.getTree("/").addChild("test");
+ Tree node = createNodeWithType(test, "item", TestUtil.NT_TEST);
+ node.setProperty("foo", "bar");
+ root.commit();
+
+ //query (searchText doesn't have 'bar'... our augment would search for :fulltext:bar
+ String query = "select [jcr:path] from [oak:TestNode] where CONTAINS(*, '" + searchText + "')";
+ List<String> paths = executeQuery(query, SQL2);
+ assertEquals("Augmented query wasn't used to search", 1, paths.size());
+ assertEquals("/test/item", paths.get(0));
+ }
+
+ //OAK-3576
+ @Test public void indexHookCallbackFrequency() throws Exception {
+ //setup repo and index
+ NodeTypeRegistry.register(root, IOUtils.toInputStream(TestUtil.TEST_NODE_TYPE), "test nodeType");
+ Tree props = createIndex(TestUtil.NT_TEST);
+ TestUtil.enablePropertyIndex(props, "foo1", false);
+ TestUtil.enablePropertyIndex(props, "foo2", false);
+ TestUtil.enablePropertyIndex(props, "subChild/foo3", false);
+ root.commit();
+
+ //setup index augmentor
+ final AtomicInteger counter = new AtomicInteger(0);
+ factory.indexFieldProvider = new IndexFieldProvider() {
+ @Override
+ public Iterable<Field> getAugmentedFields(String path, String propertyName,
+ NodeState document, PropertyState property,
+ NodeState indexDefinition) {
+ counter.incrementAndGet();
+ return null;
+ }
+ };
+
+ //add content
+ counter.set(0);
+ Tree test = root.getTree("/").addChild("test");
+ Tree node = createNodeWithType(test, "item", TestUtil.NT_TEST);
+ node.setProperty("foo1", "bar1");
+ node.setProperty("foo2", "bar2");
+ Tree subChild = node.addChild("subChild");
+ subChild.setProperty("foo3", "bar3");
+ root.commit();
+ assertEquals("Number of callbacks should be same as number of changed properties", 3, counter.get());
+
+ //change sub-property
+ counter.set(0);
+ subChild = root.getTree("/test/item/subChild");
+ subChild.setProperty("foo3", "bar4");
+ root.commit();
+ assertEquals("Sub child property change should make call backs for all indexed properties", 3, counter.get());
+ }
+
+ //OAK-3576
+ @Test public void indexHookCallbackAndStorage() throws Exception {
+ final String propName = "subChild/foo";
+
+ //setup repo and index
+ NodeTypeRegistry.register(root, IOUtils.toInputStream(TestUtil.TEST_NODE_TYPE), "test nodeType");
+ Tree props = createIndex(TestUtil.NT_TEST);
+ TestUtil.enableForFullText(props, propName);
+ root.commit();
+
+ //setup index augmentor
+ factory.indexFieldProvider = new IndexFieldProvider() {
+ @Override
+ public Iterable<Field> getAugmentedFields(String path, String propertyName,
+ NodeState document, PropertyState property,
+ NodeState indexDefinition) {
+ assertEquals("/test/item", path);
+ assertEquals(propName, propertyName);
+ assertEquals(TestUtil.NT_TEST, document.getName(JcrConstants.JCR_PRIMARYTYPE));
+ assertEquals("foo", property.getName());
+ assertEquals(IndexConstants.INDEX_DEFINITIONS_NODE_TYPE,
+ indexDefinition.getName(JcrConstants.JCR_PRIMARYTYPE));
+ return Lists.<Field>newArrayList(new StringField(
+ property.getValue(Type.STRING) + property.getValue(Type.STRING),
+ "1",
+ Field.Store.NO
+ ));
+ }
+ };
+ factory.fulltextQueryTermsProvider = new FulltextQueryTermsProvider() {
+ @Override
+ public Query getQueryTerm(String text, Analyzer analyzer) {
+ return new TermQuery(new Term(text, "1"));
+ }
+ };
+
+ //add content
+ Tree test = root.getTree("/").addChild("test");
+ Tree node = createNodeWithType(test, "item", TestUtil.NT_TEST).addChild("subChild");
+ node.setProperty("foo", "bar");
+ root.commit();
+
+ //do some queries... explicitly looking for terms we augmented (i.e. barbar=1)
+ String query = "select [jcr:path] from [oak:TestNode] AS s where CONTAINS(*, 'barbar')";
+ List<String> paths = executeQuery(query, SQL2);
+ List<String> expected = Collections.singletonList("/test/item");
+ assertThat(paths, is(expected));
+ }
+
+ private static Tree createNodeWithType(Tree t, String nodeName, String typeName){
+ t = t.addChild(nodeName);
+ t.setProperty(JcrConstants.JCR_PRIMARYTYPE, typeName, Type.NAME);
+ return t;
+ }
+
+ private Tree createIndex(String nodeType) throws Exception {
+ Tree rootTree = root.getTree("/");
+ return createIndex(rootTree, nodeType);
+ }
+
+ private Tree createIndex(Tree root, String nodeType) throws Exception {
+ Tree index = createTestIndexNode(root, LuceneIndexConstants.TYPE_LUCENE);
+ return TestUtil.newRulePropTree(index, nodeType);
+ }
+
+ private static class SimpleIndexAugmentorFactory implements IndexAugmentorFactory {
+ private IndexFieldProvider indexFieldProvider = null;
+ private FulltextQueryTermsProvider fulltextQueryTermsProvider = null;
+
+ @Override
+ public IndexFieldProvider getIndexFieldProvider() {
+ return indexFieldProvider==null?
+ IndexAugmentorFactoryImpl.DEFAULT.getIndexFieldProvider():
+ indexFieldProvider;
+ }
+
+ @Override
+ public FulltextQueryTermsProvider getFulltextQueryTermsProvider() {
+ return fulltextQueryTermsProvider==null?
+ IndexAugmentorFactoryImpl.DEFAULT.getFulltextQueryTermsProvider():
+ fulltextQueryTermsProvider;
+ }
+ }
+}
Propchange: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexAugmentTest.java
------------------------------------------------------------------------------
svn:eol-style = native