jackrabbit-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From un...@apache.org
Subject svn commit: r1444501 - in /jackrabbit/trunk/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/query/lucene/ConsistencyCheck.java test/java/org/apache/jackrabbit/core/query/lucene/SearchIndexConsistencyCheckTest.java
Date Sun, 10 Feb 2013 08:15:21 GMT
Author: unico
Date: Sun Feb 10 08:15:20 2013
New Revision: 1444501

URL: http://svn.apache.org/r1444501
Log:
JCR-3516 also report and fix wrong parent relation in the index

Modified:
    jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ConsistencyCheck.java
    jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/lucene/SearchIndexConsistencyCheckTest.java

Modified: jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ConsistencyCheck.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ConsistencyCheck.java?rev=1444501&r1=1444500&r2=1444501&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ConsistencyCheck.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ConsistencyCheck.java
Sun Feb 10 08:15:20 2013
@@ -19,7 +19,7 @@ package org.apache.jackrabbit.core.query
 import org.apache.jackrabbit.core.HierarchyManager;
 import org.apache.jackrabbit.core.persistence.IterablePersistenceManager;
 import org.apache.jackrabbit.core.persistence.PersistenceManager;
-import org.apache.jackrabbit.core.persistence.check.ConsistencyChecker;
+import org.apache.jackrabbit.core.state.ItemState;
 import org.apache.jackrabbit.core.state.ItemStateManager;
 import org.apache.jackrabbit.core.state.NoSuchItemStateException;
 import org.apache.jackrabbit.core.state.NodeState;
@@ -284,23 +284,34 @@ public class ConsistencyCheck {
                 }
                 Document d = reader.document(i, FieldSelectors.UUID_AND_PARENT);
                 NodeId id = new NodeId(d.get(FieldNames.UUID));
-                String parentUUIDString = d.get(FieldNames.PARENT);
-                NodeId parentId = null;
-                if (parentUUIDString.length() > 0) {
-                    parentId = new NodeId(parentUUIDString);
+                String parent = d.get(FieldNames.PARENT);
+                NodeId parentId;
+                if (parent != null && !parent.isEmpty()) {
+                    parentId = new NodeId(parent);
+                } else {
+                    continue;
                 }
 
-                boolean parentExists = parentId != null && nodeIds.containsKey(parentId);
+                boolean parentExists = nodeIds.containsKey(parentId);
                 boolean parentIndexed = parentExists && nodeIds.get(parentId);
-                if (parentId == null || parentIndexed) {
+                if (parentIndexed) {
                     continue;
                 }
 
-                // parent is missing
+                // parent is missing from index
                 if (parentExists) {
                     errors.add(new MissingAncestor(id, parentId));
                 } else {
-                    errors.add(new UnknownParent(id, parentId));
+                    try {
+                        final ItemState itemState = stateMgr.getItemState(id);
+                        if (parentId.equals(itemState.getParentId())) {
+                            // orphaned node
+                            errors.add(new UnknownParent(id, parentId));
+                        } else {
+                            errors.add(new WrongParent(id, parentId, itemState.getParentId()));
+                        }
+                    } catch (ItemStateException ignored) {
+                    }
                 }
             }
         } finally {
@@ -439,7 +450,7 @@ public class ConsistencyCheck {
             while (ancestorId != null && nodeIds.containsKey(ancestorId) &&
nodeIds.get(ancestorId)) {
                 try {
                     NodeState n = (NodeState) stateMgr.getItemState(ancestorId);
-                    log.info("Reparing missing node " + getPath(n) + " (" + ancestorId +
")");
+                    log.info("Repairing missing node " + getPath(n) + " (" + ancestorId +
")");
                     Document d = index.createDocument(n);
                     index.addDocument(d);
                     nodeIds.put(n.getNodeId(), Boolean.TRUE);
@@ -454,7 +465,7 @@ public class ConsistencyCheck {
     }
 
     /**
-     * The parent of a node is not available through the ItemStateManager.
+     * The parent of a node is not in the repository
      */
     private static class UnknownParent extends ConsistencyCheckError {
 
@@ -479,6 +490,43 @@ public class ConsistencyCheck {
     }
 
     /**
+     * The parent as indexed does not correspond with the actual parent in the repository
+     */
+    private class WrongParent extends ConsistencyCheckError {
+
+        private WrongParent(NodeId id, NodeId indexedParentId, NodeId actualParentId) {
+            super("Node " + id + " has wrong parent: " + indexedParentId + ", should be :
" + actualParentId, id);
+        }
+
+        @Override
+        public boolean repairable() {
+            return true;
+        }
+
+        /**
+         * Reindex node.
+         */
+        @Override
+        void repair() throws IOException {
+            index.removeAllDocuments(id);
+            try {
+                NodeState node = (NodeState) stateMgr.getItemState(id);
+                log.info("Re-indexing node with wrong parent in index: " + getPath(node));
+                Document d = index.createDocument(node);
+                index.addDocument(d);
+                nodeIds.put(node.getNodeId(), Boolean.TRUE);
+            } catch (NoSuchItemStateException e) {
+                log.info("Not re-indexing node with wrong parent because node no longer exists");
+            } catch (ItemStateException e) {
+                throw new IOException(e.toString());
+            } catch (RepositoryException e) {
+                throw new IOException(e.toString());
+            }
+        }
+
+    }
+
+    /**
      * A node is present multiple times in the index.
      */
     private class MultipleEntries extends ConsistencyCheckError {
@@ -510,6 +558,8 @@ public class ConsistencyCheck {
                 Document d = index.createDocument(node);
                 index.addDocument(d);
                 nodeIds.put(node.getNodeId(), Boolean.TRUE);
+            } catch (NoSuchItemStateException e) {
+                log.info("Not re-indexing node with multiple occurrences because node no
longer exists");
             } catch (ItemStateException e) {
                 throw new IOException(e.toString());
             } catch (RepositoryException e) {
@@ -560,11 +610,14 @@ public class ConsistencyCheck {
         void repair() throws IOException {
             try {
                 NodeState nodeState = (NodeState) stateMgr.getItemState(id);
+                log.info("Adding missing node to index: " + getPath(nodeState));
                 final Iterator<NodeId> remove = Collections.<NodeId>emptyList().iterator();
                 final Iterator<NodeState> add = Collections.singletonList(nodeState).iterator();
                 handler.updateNodes(remove, add);
             } catch (RepositoryException e) {
                 throw new IOException(e.toString());
+            } catch (NoSuchItemStateException e) {
+                log.info("Not adding missing node because node no longer exists");
             } catch (ItemStateException e) {
                 throw new IOException(e.toString());
             }

Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/lucene/SearchIndexConsistencyCheckTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/lucene/SearchIndexConsistencyCheckTest.java?rev=1444501&r1=1444500&r2=1444501&view=diff
==============================================================================
--- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/lucene/SearchIndexConsistencyCheckTest.java
(original)
+++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/lucene/SearchIndexConsistencyCheckTest.java
Sun Feb 10 08:15:20 2013
@@ -18,6 +18,7 @@ package org.apache.jackrabbit.core.query
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
@@ -101,6 +102,71 @@ public class SearchIndexConsistencyCheck
         assertTrue("Consistency check still reports errors", searchIndex.runConsistencyCheck().getErrors().isEmpty());
     }
 
+    public void testIndexMissesAncestor() throws Exception {
+        Session s = getHelper().getSuperuserSession();
+        SearchManager searchManager = TestHelper.getSearchManager(s);
+        SearchIndex searchIndex = (SearchIndex) searchManager.getQueryHandler();
+
+        Node foo = testRootNode.addNode("foo");
+        Node bar = foo.addNode("bar");
+        testRootNode.getSession().save();
+        NodeId fooId = new NodeId(foo.getIdentifier());
+        NodeId barId = new NodeId(bar.getIdentifier());
+
+        Iterator<NodeId> remove = Collections.singletonList(fooId).iterator();
+        Iterator<NodeState> add = Collections.<NodeState>emptyList().iterator();
+
+        searchIndex.updateNodes(remove, add);
+
+        ConsistencyCheck consistencyCheck = searchIndex.runConsistencyCheck();
+        List<ConsistencyCheckError> errors = consistencyCheck.getErrors();
+
+        assertEquals("Expected 2 index consistency errors", 2, errors.size());
+
+        assertEquals("Different node was reported to have missing parent", errors.get(0).id,
barId);
+        assertEquals("Different node was reported to be missing", errors.get(1).id, fooId);
+
+        consistencyCheck.repair(false);
+
+        assertTrue("Index was not repaired properly", searchIndexContainsNode(searchIndex,
fooId));
+
+        assertTrue("Consistency check still reports errors", searchIndex.runConsistencyCheck().getErrors().isEmpty());
+    }
+
+    public void testIndexContainsMultipleEntries() throws Exception {
+        Session s = getHelper().getSuperuserSession();
+        SearchManager searchManager = TestHelper.getSearchManager(s);
+        SearchIndex searchIndex = (SearchIndex) searchManager.getQueryHandler();
+
+        Node foo = testRootNode.addNode("foo");
+        testRootNode.getSession().save();
+        NodeId fooId = new NodeId(foo.getIdentifier());
+
+        NodeState nodeState = new NodeState(fooId, null, null, 1, false);
+        Iterator<NodeId> remove = Collections.<NodeId>emptyList().iterator();
+        Iterator<NodeState> add = Arrays.asList(nodeState).iterator();
+
+        searchIndex.updateNodes(remove, add);
+
+        searchIndex.flush();
+
+        remove = Collections.<NodeId>emptyList().iterator();
+        add = Arrays.asList(nodeState).iterator();
+
+        searchIndex.updateNodes(remove, add);
+
+        ConsistencyCheck consistencyCheck = searchIndex.runConsistencyCheck();
+        List<ConsistencyCheckError> errors = consistencyCheck.getErrors();
+
+        assertEquals("Expected 1 index consistency error", 1, errors.size());
+        assertEquals("Different node was reported to be duplicate", errors.get(0).id, fooId);
+
+        consistencyCheck.repair(false);
+
+        assertTrue("Index was not repaired properly", searchIndexContainsNode(searchIndex,
fooId));
+        assertTrue("Consistency check still reports errors", searchIndex.runConsistencyCheck().getErrors().isEmpty());
+    }
+
     private boolean searchIndexContainsNode(SearchIndex searchIndex, NodeId nodeId) throws
IOException {
         final List<Integer> docs = new ArrayList<Integer>(1);
         final IndexReader reader = searchIndex.getIndexReader();



Mime
View raw message