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 ch...@apache.org on 2017/10/03 05:05:10 UTC

svn commit: r1810626 - in /jackrabbit/oak/trunk/oak-lucene/src: main/java/org/apache/jackrabbit/oak/plugins/index/lucene/ test/java/org/apache/jackrabbit/oak/plugins/index/lucene/

Author: chetanm
Date: Tue Oct  3 05:05:10 2017
New Revision: 1810626

URL: http://svn.apache.org/viewvc?rev=1810626&view=rev
Log:
OAK-6535 - Synchronous Lucene Property Indexes

Introduce a new PropertyUpdateCallback extension which would be invoked
for each indexed property update. Later this would be used to update the
property indexes for sync property definitions

For now callback is invoked for direct properties. Support for relative
property pending

Added:
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/PropertyUpdateCallback.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorContext.java
    jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor2Test.java

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java?rev=1810626&r1=1810625&r2=1810626&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor.java Tue Oct  3 05:05:10 2017
@@ -168,6 +168,7 @@ public class LuceneIndexEditor implement
     public void propertyAdded(PropertyState after) {
         markPropertyChanged(after.getName());
         checkAggregates(after.getName());
+        propertyUpdated(null, after);
     }
 
     @Override
@@ -175,6 +176,7 @@ public class LuceneIndexEditor implement
         markPropertyChanged(before.getName());
         propertiesModified.add(before);
         checkAggregates(before.getName());
+        propertyUpdated(before, after);
     }
 
     @Override
@@ -182,6 +184,7 @@ public class LuceneIndexEditor implement
         markPropertyChanged(before.getName());
         propertiesModified.add(before);
         checkAggregates(before.getName());
+        propertyUpdated(before, null);
     }
 
     @Override
@@ -346,6 +349,26 @@ public class LuceneIndexEditor implement
         }
     }
 
+    private void propertyUpdated(PropertyState before, PropertyState after) {
+        PropertyUpdateCallback callback = context.getPropertyUpdateCallback();
+
+        //Avoid further work if no callback is present
+        if (callback == null) {
+            return;
+        }
+
+        String propertyName = before != null ? before.getName() : after.getName();
+
+        if (isIndexable()) {
+            PropertyDefinition pd = indexingRule.getConfig(propertyName);
+            if (pd != null) {
+                callback.propertyUpdated(getPath(), propertyName, pd, before, after);
+            }
+        }
+
+        //TODO Support for relative props
+    }
+
     private IndexDefinition getDefinition() {
         return context.getDefinition();
     }

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorContext.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorContext.java?rev=1810626&r1=1810625&r2=1810626&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorContext.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditorContext.java Tue Oct  3 05:05:10 2017
@@ -19,6 +19,7 @@ package org.apache.jackrabbit.oak.plugin
 import java.io.IOException;
 import java.util.Calendar;
 
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
 
 import org.apache.jackrabbit.oak.api.CommitFailedException;
@@ -88,6 +89,8 @@ public class LuceneIndexEditorContext im
 
     private BinaryTextExtractor textExtractor;
 
+    private PropertyUpdateCallback propertyUpdateCallback;
+
     LuceneIndexEditorContext(NodeState root, NodeBuilder definition,
                              @Nullable IndexDefinition indexDefinition,
                              IndexUpdateCallback updateCallback,
@@ -127,6 +130,15 @@ public class LuceneIndexEditorContext im
         return indexingContext;
     }
 
+    @CheckForNull
+    public PropertyUpdateCallback getPropertyUpdateCallback() {
+        return propertyUpdateCallback;
+    }
+
+    void setPropertyUpdateCallback(PropertyUpdateCallback propertyUpdateCallback) {
+        this.propertyUpdateCallback = propertyUpdateCallback;
+    }
+
     /**
      * close writer if it's not null
      */

Added: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/PropertyUpdateCallback.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/PropertyUpdateCallback.java?rev=1810626&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/PropertyUpdateCallback.java (added)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/PropertyUpdateCallback.java Tue Oct  3 05:05:10 2017
@@ -0,0 +1,45 @@
+/*
+ * 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 javax.annotation.Nullable;
+
+import org.apache.jackrabbit.oak.api.PropertyState;
+
+/**
+ * Callback to be invoked for each indexable property change
+ */
+public interface PropertyUpdateCallback {
+
+    /**
+     * Invoked upon any change in property either added, updated or removed.
+     * Implementation can determine if property is added, updated or removed based
+     * on whether before or after is null
+     *
+     * @param nodePath path of node for which is to be indexed for this property change
+     * @param propertyRelativePath relative path of the property wrt the indexed node
+     * @param pd property definition associated with the property to be indexed
+     * @param before before state. Is null when property is added. For other cases its not null
+     * @param after after state of the property. Is null when property is removed. For other cases its not null
+     */
+    void propertyUpdated(String nodePath, String propertyRelativePath, PropertyDefinition pd,
+                         @Nullable  PropertyState before, @Nullable PropertyState after);
+
+}

Propchange: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/PropertyUpdateCallback.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor2Test.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor2Test.java?rev=1810626&r1=1810625&r2=1810626&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor2Test.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexEditor2Test.java Tue Oct  3 05:05:10 2017
@@ -29,6 +29,7 @@ import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 
 import org.apache.jackrabbit.oak.api.CommitFailedException;
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.plugins.index.IndexCommitCallback;
 import org.apache.jackrabbit.oak.plugins.index.IndexEditorProvider;
@@ -49,6 +50,10 @@ import org.junit.Test;
 import static org.apache.jackrabbit.oak.InitialContent.INITIAL_CONTENT;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.fail;
 import static org.mockito.Mockito.mock;
 
 public class LuceneIndexEditor2Test {
@@ -59,6 +64,7 @@ public class LuceneIndexEditor2Test {
     private ExtractedTextCache extractedTextCache = new ExtractedTextCache(0, 0);
     private TestIndexingContext indexingContext = new TestIndexingContext();
     private TestWriterFactory writerFactory = new TestWriterFactory();
+    private TestPropertyUpdateCallback propCallback = new TestPropertyUpdateCallback();
     private TestWriter writer = new TestWriter();
     private String indexPath = "/oak:index/fooIndex";
 
@@ -81,6 +87,52 @@ public class LuceneIndexEditor2Test {
         assertThat(writer.docs.keySet(), containsInAnyOrder("/a"));
     }
 
+    @Test
+    public void simplePropertyUpdateCallback() throws Exception{
+        IndexDefinitionBuilder defnb = new IndexDefinitionBuilder();
+        defnb.indexRule("nt:base").property("foo").propertyIndex();
+
+        NodeState defnState = defnb.build();
+        IndexDefinition defn = new IndexDefinition(root, defnState, indexPath);
+        LuceneIndexEditorContext ctx = newContext(defnState.builder(), defn, true);
+        ctx.setPropertyUpdateCallback(propCallback);
+
+        EditorHook hook = createHook(ctx);
+
+        updateBefore(defnb);
+
+        //Property added
+        NodeBuilder builder = before.builder();
+        builder.child("a").setProperty("foo", "bar");
+        builder.child("a").setProperty("foo2", "bar");
+
+        before = hook.processCommit(root, builder.getNodeState(), CommitInfo.EMPTY);
+        propCallback.state.assertState("/a", "foo", UpdateState.ADDED);
+        assertEquals(1, propCallback.invocationCount);
+        propCallback.reset();
+
+        //Property updated
+        builder = before.builder();
+        builder.child("a").setProperty("foo", "bar2");
+        builder.child("a").setProperty("foo2", "bar2");
+        before = hook.processCommit(before, builder.getNodeState(), CommitInfo.EMPTY);
+
+        propCallback.state.assertState("/a", "foo", UpdateState.UPDATED);
+
+        assertEquals(1, propCallback.invocationCount);
+        propCallback.reset();
+
+        //Property deleted
+        builder = before.builder();
+        builder.child("a").removeProperty("foo");
+        builder.child("a").removeProperty("foo2");
+        before = hook.processCommit(before, builder.getNodeState(), CommitInfo.EMPTY);
+
+        propCallback.state.assertState("/a", "foo", UpdateState.DELETED);
+        assertEquals(1, propCallback.invocationCount);
+        propCallback.reset();
+    }
+
     private void updateBefore(IndexDefinitionBuilder defnb) {
         NodeBuilder builder = before.builder();
         NodeBuilder cb = TestUtil.child(builder, PathUtils.getParentPath(indexPath));
@@ -113,6 +165,63 @@ public class LuceneIndexEditor2Test {
     }
 
 
+    private static class TestPropertyUpdateCallback implements PropertyUpdateCallback {
+        int invocationCount;
+        CallbackState state;
+
+        @Override
+        public void propertyUpdated(String nodePath, String propertyRelativePath, PropertyDefinition pd,
+                                    PropertyState before, PropertyState after) {
+            assertNotNull(nodePath);
+            assertNotNull(propertyRelativePath);
+            assertNotNull(pd);
+
+            if (before == null && after == null) {
+                fail("Both states cannot be null at same time");
+            }
+
+            state = new CallbackState(nodePath, propertyRelativePath, pd, before, after);
+            invocationCount++;
+        }
+
+        void reset(){
+            state = null;
+            invocationCount = 0;
+        }
+    }
+
+    enum UpdateState {ADDED, UPDATED, DELETED}
+
+    private static class CallbackState {
+        final String nodePath;
+        final String propertyPath;
+        final PropertyDefinition pd;
+        final PropertyState before;
+        final PropertyState after;
+
+
+        public CallbackState(String nodePath, String propertyPath, PropertyDefinition pd,
+                              PropertyState before, PropertyState after) {
+            this.nodePath = nodePath;
+            this.propertyPath = propertyPath;
+            this.pd = pd;
+            this.before = before;
+            this.after = after;
+        }
+
+        public void assertState(String expectedPath, String expectedName, UpdateState us) {
+            assertEquals(expectedPath, nodePath);
+            assertEquals(expectedName, propertyPath);
+
+            switch (us) {
+                case ADDED: assertNotNull(after); assertNull(before); break;
+                case UPDATED: assertNotNull(after); assertNotNull(before); break;
+                case DELETED: assertNull(after); assertNotNull(before); break;
+            }
+        }
+    }
+
+
     private class TestWriterFactory implements LuceneIndexWriterFactory {
         @Override
         public LuceneIndexWriter newInstance(IndexDefinition definition,