You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by un...@apache.org on 2012/06/16 08:48:31 UTC

svn commit: r1350869 - in /jackrabbit/branches/2.4/jackrabbit-core/src: main/java/org/apache/jackrabbit/core/persistence/bundle/ConsistencyCheckerImpl.java test/java/org/apache/jackrabbit/core/data/ConsistencyCheckerImplTest.java

Author: unico
Date: Sat Jun 16 06:48:30 2012
New Revision: 1350869

URL: http://svn.apache.org/viewvc?rev=1350869&view=rev
Log:
JCR-3267 fix bundles immediately during checkbundle in order to avoid lost update problem; also add unit test for consistency fixing (backport)

Added:
    jackrabbit/branches/2.4/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/ConsistencyCheckerImplTest.java
      - copied unchanged from r1350221, jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/data/ConsistencyCheckerImplTest.java
Modified:
    jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/ConsistencyCheckerImpl.java

Modified: jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/ConsistencyCheckerImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/ConsistencyCheckerImpl.java?rev=1350869&r1=1350868&r2=1350869&view=diff
==============================================================================
--- jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/ConsistencyCheckerImpl.java (original)
+++ jackrabbit/branches/2.4/jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/ConsistencyCheckerImpl.java Sat Jun 16 06:48:30 2012
@@ -76,8 +76,6 @@ public class ConsistencyCheckerImpl {
             boolean fix, Set<ReportItem> reports, String lostNFoundId)
             throws RepositoryException {
         int count = 0;
-        Collection<NodePropBundle> modifications = new ArrayList<NodePropBundle>();
-        Set<NodeId> orphaned = new HashSet<NodeId>();
 
         NodeId lostNFound = null;
         if (fix && lostNFoundId != null) {
@@ -116,9 +114,7 @@ public class ConsistencyCheckerImpl {
                                 error(id.toString(), "No bundle found for id '"
                                         + id + "'");
                             } else {
-                                checkBundleConsistency(id, bundle, fix,
-                                        modifications, lostNFound, orphaned,
-                                        reports);
+                                checkBundleConsistency(id, bundle, fix, lostNFound, reports);
 
                                 count++;
                                 if (count % 1000 == 0 && listener == null) {
@@ -174,8 +170,7 @@ public class ConsistencyCheckerImpl {
                                     + id + "'");
                         }
                     } else {
-                        checkBundleConsistency(id, bundle, fix, modifications,
-                                lostNFound, orphaned, reports);
+                        checkBundleConsistency(id, bundle, fix, lostNFound, reports);
 
                         if (recursive) {
                             for (NodePropBundle.ChildNodeEntry entry : bundle
@@ -197,49 +192,6 @@ public class ConsistencyCheckerImpl {
             }
         }
 
-        // repair collected broken bundles
-        if (fix && !modifications.isEmpty()) {
-            info(null, pm + ": Fixing " + modifications.size()
-                    + " inconsistent bundle(s)...");
-            for (NodePropBundle bundle : modifications) {
-                try {
-                    info(bundle.getId().toString(), pm + ": Fixing bundle '"
-                            + bundle.getId() + "'");
-                    bundle.markOld(); // use UPDATE instead of INSERT
-                    pm.storeBundle(bundle);
-                    pm.evictBundle(bundle.getId());
-                } catch (ItemStateException e) {
-                    error(bundle.getId().toString(), pm
-                            + ": Error storing fixed bundle: " + e);
-                }
-            }
-        }
-
-        if (fix && lostNFoundId != null && !orphaned.isEmpty()) {
-            // do we have things to add to "lost+found"?
-            try {
-                NodePropBundle lfBundle = pm.loadBundle(lostNFound);
-                if (lfBundle == null) {
-                    error(lostNFoundId, "specified 'lost+found' node does not exist");
-                } else if (!NameConstants.NT_UNSTRUCTURED.equals(lfBundle
-                        .getNodeTypeName())) {
-                    error(lostNFoundId, "specified 'lost+found' node is not of type nt:unstructered");
-                } else {
-                    lfBundle.markOld();
-                    for (NodeId orphan : orphaned) {
-                        String nodeName = orphan + "-"
-                                + System.currentTimeMillis();
-                        lfBundle.addChildNodeEntry(NF.create("", nodeName),
-                                orphan);
-                    }
-                    pm.storeBundle(lfBundle);
-                    pm.evictBundle(lfBundle.getId());
-                }
-            } catch (Exception ex) {
-                error(null, "trying orphan adoption", ex);
-            }
-        }
-
         log.info(pm + ": checked " + count + " bundles.");
 
         return count;
@@ -255,13 +207,8 @@ public class ConsistencyCheckerImpl {
      *            the bundle to check
      * @param fix
      *            if <code>true</code>, repair things that can be repaired
-     * @param modifications
-     *            if <code>fix == true</code>, collect the repaired
-     *            {@linkplain NodePropBundle bundles} here
      */
-    private void checkBundleConsistency(NodeId id, NodePropBundle bundle,
-            boolean fix, Collection<NodePropBundle> modifications,
-            NodeId lostNFoundId, Set<NodeId> orphaned, Set<ReportItem> reports) {
+    private void checkBundleConsistency(NodeId id, NodePropBundle bundle, boolean fix, NodeId lostNFoundId, Set<ReportItem> reports) {
         // log.info(name + ": checking bundle '" + id + "'");
 
         // skip all virtual nodes
@@ -354,7 +301,7 @@ public class ConsistencyCheckerImpl {
             for (NodePropBundle.ChildNodeEntry entry : missingChildren) {
                 bundle.getChildNodeEntries().remove(entry);
             }
-            modifications.add(bundle);
+            fixBundle(bundle);
         }
 
         // check parent reference
@@ -374,10 +321,18 @@ public class ConsistencyCheckerImpl {
                                     + "'";
                             log.error(message);
                             addMessage(reports, id, message);
-                            orphaned.add(id);
-                            if (lostNFoundId != null) {
+                            if (fix && lostNFoundId != null) {
+                                // add a child to lost+found
+                                NodePropBundle lfBundle = pm.loadBundle(lostNFoundId);
+                                lfBundle.markOld();
+                                String nodeName = id + "-" + System.currentTimeMillis();
+                                lfBundle.addChildNodeEntry(NF.create("", nodeName), id);
+                                pm.storeBundle(lfBundle);
+                                pm.evictBundle(lostNFoundId);
+
+                                // set lost+found parent
                                 bundle.setParentId(lostNFoundId);
-                                modifications.add(bundle);
+                                fixBundle(bundle);
                             }
                         }
                     } else {
@@ -403,18 +358,18 @@ public class ConsistencyCheckerImpl {
                                         + parentId + "'";
                                 log.error(message);
                                 addMessage(reports, id, message);
-
-                                int l = (int) System.currentTimeMillis();
-                                int r = new Random().nextInt();
-                                int n = l + r;
-                                String nodeName = Integer.toHexString(n);
-                                parentBundle.addChildNodeEntry(
-                                        NF.create("{}" + nodeName), id);
-                                log.info("NodeState '" + id
-                                        + "' adds itself to its parent node '"
-                                        + parentId + "' with a new name '" + nodeName
-                                        + "'");
-                                modifications.add(parentBundle);
+                                if (fix) {
+                                    int l = (int) System.currentTimeMillis();
+                                    int r = new Random().nextInt();
+                                    int n = l + r;
+                                    String nodeName = Integer.toHexString(n);
+                                    parentBundle.addChildNodeEntry(NF.create("{}" + nodeName), id);
+                                    log.info("NodeState '" + id
+                                            + "' adds itself to its parent node '"
+                                            + parentId + "' with a new name '" + nodeName
+                                            + "'");
+                                    fixBundle(parentBundle);
+                                }
                             }
                         } else {
                             return;
@@ -486,4 +441,15 @@ public class ConsistencyCheckerImpl {
             listener.error(id, message);
         }
     }
+
+    private void fixBundle(NodePropBundle bundle) {
+        try {
+            log.info(pm + ": Fixing bundle '" + bundle.getId() + "'");
+            bundle.markOld(); // use UPDATE instead of INSERT
+            pm.storeBundle(bundle);
+            pm.evictBundle(bundle.getId());
+        } catch (ItemStateException e) {
+            log.error(pm + ": Error storing fixed bundle: " + e);
+        }
+    }
 }