Author: chetanm
Date: Fri May 12 09:14:27 2017
New Revision: 1794947

URL: http://svn.apache.org/viewvc?rev=1794947&view=rev
Log:
OAK-6192 - Lucene IndexInfoProvider implementation

Compute the diff between stored index definition and current index
definition. The diff needs to ignore system generated properties like
reindexCount, reindex etc

Modified:
    
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexInfoProvider.java
    
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexInfoProvider.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexInfoProvider.java?rev=1794947&r1=1794946&r2=1794947&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexInfoProvider.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexInfoProvider.java
 Fri May 12 09:14:27 2017
@@ -23,10 +23,12 @@ import java.io.File;
 import java.io.IOException;
 import java.util.Set;
 
+import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Sets;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.Type;
+import org.apache.jackrabbit.oak.json.JsopDiff;
 import org.apache.jackrabbit.oak.plugins.index.AsyncIndexInfo;
 import org.apache.jackrabbit.oak.plugins.index.AsyncIndexInfoService;
 import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
@@ -35,6 +37,7 @@ import org.apache.jackrabbit.oak.plugins
 import org.apache.jackrabbit.oak.plugins.index.lucene.directory.DirectoryUtils;
 import 
org.apache.jackrabbit.oak.plugins.index.lucene.directory.IndexConsistencyChecker;
 import 
org.apache.jackrabbit.oak.plugins.index.lucene.writer.MultiplexersLucene;
+import org.apache.jackrabbit.oak.spi.state.EqualsDiff;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.apache.jackrabbit.oak.spi.state.NodeStateUtils;
 import org.apache.jackrabbit.oak.spi.state.NodeStore;
@@ -42,11 +45,15 @@ import org.apache.jackrabbit.oak.spi.sta
 import org.apache.jackrabbit.util.ISO8601;
 import org.apache.lucene.index.DirectoryReader;
 import org.apache.lucene.store.Directory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
+import static 
org.apache.jackrabbit.oak.plugins.index.lucene.IndexDefinition.INDEX_DEFINITION_NODE;
 
 public class LuceneIndexInfoProvider implements IndexInfoProvider {
+    private final Logger log = LoggerFactory.getLogger(getClass());
 
     private final NodeStore nodeStore;
 
@@ -87,6 +94,7 @@ public class LuceneIndexInfoProvider imp
 
         LuceneIndexInfo info = new LuceneIndexInfo(indexPath);
         computeSize(idxState, info);
+        computeIndexDefinitionChange(idxState, info);
         computeLastUpdatedTime(idxState, info);
         computeAsyncIndexInfo(idxState, indexPath, info);
         return info;
@@ -100,8 +108,10 @@ public class LuceneIndexInfoProvider imp
 
     private void computeAsyncIndexInfo(NodeState idxState, String indexPath, 
LuceneIndexInfo info) {
         String asyncName = getAsyncName(idxState, indexPath);
-        checkNotNull(asyncName, "No 'async' value for index definition " +
-                "at [%s]. Definition %s", indexPath, idxState);
+        if (asyncName == null) {
+            log.warn("No 'async' value for index definition at [{}]. 
Definition {}", indexPath, idxState);
+            return;
+        }
 
         AsyncIndexInfo asyncInfo = asyncInfoService.getInfo(asyncName);
         checkNotNull(asyncInfo, "No async info found for name [%s] " +
@@ -134,6 +144,17 @@ public class LuceneIndexInfoProvider imp
         }
     }
 
+    private static void computeIndexDefinitionChange(NodeState idxState, 
LuceneIndexInfo info) {
+        NodeState storedDefn = idxState.getChildNode(INDEX_DEFINITION_NODE);
+        if (storedDefn.exists()) {
+            NodeState currentDefn = 
NodeStateCloner.cloneVisibleState(idxState);
+            if (!FilteringEqualsDiff.equals(storedDefn, currentDefn)){
+                info.indexDefinitionChanged = true;
+                info.indexDiff = JsopDiff.diffToJsop(storedDefn, currentDefn);
+            }
+        }
+    }
+
     private static class LuceneIndexInfo implements IndexInfo {
         String indexPath;
         String asyncName;
@@ -141,6 +162,8 @@ public class LuceneIndexInfoProvider imp
         long size;
         long indexedUptoTime;
         long lastUpdatedTime;
+        boolean indexDefinitionChanged;
+        String indexDiff;
 
         public LuceneIndexInfo(String indexPath) {
             this.indexPath = indexPath;
@@ -183,12 +206,51 @@ public class LuceneIndexInfoProvider imp
 
         @Override
         public boolean hasIndexDefinitionChangedWithoutReindexing() {
-            return false; //TODO To be computed
+            return indexDefinitionChanged;
         }
 
         @Override
         public String getIndexDefinitionDiff() {
-            return null;
+            return indexDiff;
+        }
+    }
+
+    static class FilteringEqualsDiff extends EqualsDiff {
+        private static final Set<String> IGNORED_PROP_NAMES = ImmutableSet.of(
+                IndexConstants.REINDEX_COUNT,
+                IndexConstants.REINDEX_PROPERTY_NAME
+        );
+        public static boolean equals(NodeState before, NodeState after) {
+            return before.exists() == after.exists()
+                    && after.compareAgainstBaseState(before, new 
FilteringEqualsDiff());
+        }
+
+        @Override
+        public boolean propertyChanged(PropertyState before, PropertyState 
after) {
+            if (ignoredProp(before.getName())){
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public boolean propertyAdded(PropertyState after) {
+            if (ignoredProp(after.getName())){
+                return true;
+            }
+            return super.propertyAdded(after);
+        }
+
+        @Override
+        public boolean propertyDeleted(PropertyState before) {
+            if (ignoredProp(before.getName())){
+                return true;
+            }
+            return super.propertyDeleted(before);
+        }
+
+        private boolean ignoredProp(String name) {
+            return IGNORED_PROP_NAMES.contains(name) || 
NodeStateUtils.isHidden(name);
         }
     }
 }

Modified: 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java?rev=1794947&r1=1794946&r2=1794947&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LucenePropertyIndexTest.java
 Fri May 12 09:14:27 2017
@@ -67,6 +67,7 @@ import static org.junit.Assert.assertEqu
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 
@@ -105,7 +106,10 @@ import org.apache.jackrabbit.oak.api.Res
 import org.apache.jackrabbit.oak.api.Tree;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.concurrent.ExecutorCloser;
+import org.apache.jackrabbit.oak.plugins.index.AsyncIndexInfoService;
+import org.apache.jackrabbit.oak.plugins.index.AsyncIndexInfoServiceImpl;
 import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.IndexInfo;
 import org.apache.jackrabbit.oak.plugins.index.fulltext.ExtractedText;
 import 
org.apache.jackrabbit.oak.plugins.index.fulltext.ExtractedText.ExtractionResult;
 import 
org.apache.jackrabbit.oak.plugins.index.fulltext.PreExtractedTextProvider;
@@ -2541,6 +2545,32 @@ public class LucenePropertyIndexTest ext
         assertFalse(NodeStateUtils.getNode(nodeStore.getRoot(), 
clonedDefnPath).exists());
     }
 
+    @Test
+    public void storedIndexDefinitionDiff() throws Exception{
+        IndexDefinitionBuilder idxb = new IndexDefinitionBuilder().noAsync();
+        idxb.indexRule("nt:base").property("foo").propertyIndex();
+        Tree idx = root.getTree("/").getChild("oak:index").addChild("test1");
+        idxb.build(idx);
+        root.commit();
+
+        AsyncIndexInfoService asyncService = new 
AsyncIndexInfoServiceImpl(nodeStore);
+        LuceneIndexInfoProvider indexInfoProvider = new 
LuceneIndexInfoProvider(nodeStore, asyncService, temporaryFolder.newFolder());
+
+        IndexInfo info = indexInfoProvider.getInfo("/oak:index/test1");
+        assertNotNull(info);
+
+        assertFalse(info.hasIndexDefinitionChangedWithoutReindexing());
+        assertNull(info.getIndexDefinitionDiff());
+
+        Tree idxTree = root.getTree("/oak:index/test1");
+        idxTree.setProperty("foo", "bar");
+        root.commit();
+
+        info = indexInfoProvider.getInfo("/oak:index/test1");
+        assertTrue(info.hasIndexDefinitionChangedWithoutReindexing());
+        assertNotNull(info.getIndexDefinitionDiff());
+    }
+
     private void assertPlanAndQuery(String query, String planExpectation, 
List<String> paths){
         assertThat(explain(query), containsString(planExpectation));
         assertQuery(query, paths);


Reply via email to