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 ba...@apache.org on 2016/03/21 16:07:45 UTC

svn commit: r1735984 - in /jackrabbit/oak/branches/1.4: ./ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/ oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/

Author: baedke
Date: Mon Mar 21 15:07:44 2016
New Revision: 1735984

URL: http://svn.apache.org/viewvc?rev=1735984&view=rev
Log:
OAK-3910: Migrating node inheriting from mix:versionable without version history

Creating empty version histories for certain inconsistent versionable nodes during Crx2Oak migration. Patch supplied by Tomek Rekawek (tomekr@apache.com).

Modified:
    jackrabbit/oak/branches/1.4/   (props changed)
    jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java
    jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionableEditor.java
    jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/BrokenVersionableTest.java

Propchange: jackrabbit/oak/branches/1.4/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Mon Mar 21 15:07:44 2016
@@ -1,3 +1,3 @@
 /jackrabbit/oak/branches/1.0:1665962
-/jackrabbit/oak/trunk:1733615,1733875,1733913,1734230,1734254,1735052,1735405,1735484,1735549,1735588,1735622,1735638,1735919
+/jackrabbit/oak/trunk:1733615,1733875,1733913,1734230,1734254,1735052,1735405,1735484,1735549,1735588,1735622,1735638,1735919,1735983
 /jackrabbit/trunk:1345480

Modified: jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java?rev=1735984&r1=1735983&r2=1735984&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java (original)
+++ jackrabbit/oak/branches/1.4/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/version/ReadWriteVersionManager.java Mon Mar 21 15:07:44 2016
@@ -74,13 +74,13 @@ import static org.apache.jackrabbit.oak.
  * Extends the {@link ReadOnlyVersionManager} with methods to modify the
  * version store.
  */
-class ReadWriteVersionManager extends ReadOnlyVersionManager {
+public class ReadWriteVersionManager extends ReadOnlyVersionManager {
 
     private final NodeBuilder versionStorageNode;
     private final NodeBuilder workspaceRoot;
     private ReadOnlyNodeTypeManager ntMgr;
 
-    ReadWriteVersionManager(NodeBuilder versionStorageNode,
+    public ReadWriteVersionManager(NodeBuilder versionStorageNode,
                             NodeBuilder workspaceRoot) {
         this.versionStorageNode = checkNotNull(versionStorageNode);
         this.workspaceRoot = checkNotNull(workspaceRoot);
@@ -119,7 +119,7 @@ class ReadWriteVersionManager extends Re
      *                                  {@code jcr:uuid} property.
      */
     @Nonnull
-    NodeBuilder getOrCreateVersionHistory(@Nonnull NodeBuilder versionable, @Nonnull Map<String, Object> infoMap)
+    public NodeBuilder getOrCreateVersionHistory(@Nonnull NodeBuilder versionable, @Nonnull Map<String, Object> infoMap)
             throws CommitFailedException {
         checkNotNull(versionable);
         String vUUID = uuidFromNode(versionable);
@@ -379,7 +379,7 @@ class ReadWriteVersionManager extends Re
 
         // jcr:frozenNode of created version
         VersionableState versionableState = VersionableState.fromVersion(
-                version, vHistory, versionable, this, ntMgr);
+                version, vHistory, versionable, this, getNodeTypeManager());
         if (!isRootVersion) {
             versionableState.create();
         }

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionableEditor.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionableEditor.java?rev=1735984&r1=1735983&r2=1735984&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionableEditor.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionableEditor.java Mon Mar 21 15:07:44 2016
@@ -19,7 +19,9 @@ package org.apache.jackrabbit.oak.upgrad
 import org.apache.jackrabbit.oak.api.CommitFailedException;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants;
 import org.apache.jackrabbit.oak.plugins.nodetype.TypePredicate;
+import org.apache.jackrabbit.oak.plugins.version.ReadWriteVersionManager;
 import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
 import org.apache.jackrabbit.oak.spi.commit.DefaultEditor;
 import org.apache.jackrabbit.oak.spi.commit.Editor;
@@ -29,6 +31,7 @@ import org.apache.jackrabbit.oak.spi.sta
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Collections;
 import java.util.Set;
 
 import static com.google.common.collect.ImmutableSet.of;
@@ -43,6 +46,7 @@ import static org.apache.jackrabbit.JcrC
 import static org.apache.jackrabbit.JcrConstants.MIX_VERSIONABLE;
 import static org.apache.jackrabbit.oak.plugins.memory.MultiGenericPropertyState.nameProperty;
 import static org.apache.jackrabbit.oak.plugins.version.VersionConstants.MIX_REP_VERSIONABLE_PATHS;
+import static org.apache.jackrabbit.oak.upgrade.version.VersionHistoryUtil.getVersionHistoryNodeState;
 
 /**
  * The VersionableEditor provides two possible ways to handle
@@ -58,6 +62,8 @@ import static org.apache.jackrabbit.oak.
  */
 public class VersionableEditor extends DefaultEditor {
 
+    private static final Logger logger = LoggerFactory.getLogger(VersionableEditor.class);
+
     private static final Set<String> SKIPPED_PATHS = of("/oak:index", "/jcr:system/jcr:versionStorage");
 
     private final Provider provider;
@@ -70,6 +76,8 @@ public class VersionableEditor extends D
 
     private final VersionCopier versionCopier;
 
+    private final ReadWriteVersionManager vMgr;
+
     private String path;
 
     private VersionableEditor(Provider provider, NodeBuilder builder) {
@@ -79,6 +87,9 @@ public class VersionableEditor extends D
         this.isReferenceable = new TypePredicate(builder.getNodeState(), MIX_REFERENCEABLE);
         this.versionCopier = new VersionCopier(provider.sourceRoot, builder);
         this.path = "/";
+
+        NodeBuilder vsRoot = rootBuilder.child(NodeTypeConstants.JCR_SYSTEM).child(NodeTypeConstants.JCR_VERSIONSTORAGE);
+        this.vMgr = new ReadWriteVersionManager(vsRoot, rootBuilder);
     }
 
     public static class Provider implements EditorProvider {
@@ -128,7 +139,12 @@ public class VersionableEditor extends D
             if (isVersionHistoryExists(versionableUuid)) {
                 setVersionablePath(versionableUuid);
             } else {
-                removeVersionProperties(getNodeBuilder(rootBuilder, this.path));
+                NodeBuilder versionableBuilder = getNodeBuilder(rootBuilder, this.path);
+                removeVersionProperties(versionableBuilder);
+                if (isVersionable.apply(versionableBuilder.getNodeState())) {
+                    logger.warn("Node {} is still versionable. Creating empty version history.", path);
+                    createEmptyHistory(versionableBuilder);
+                }
             }
         }
 
@@ -149,7 +165,7 @@ public class VersionableEditor extends D
     }
 
     private boolean isVersionHistoryExists(String versionableUuid) {
-        return VersionHistoryUtil.getVersionHistoryNodeState(rootBuilder.getNodeState(), versionableUuid).exists();
+        return getVersionHistoryNodeState(rootBuilder.getNodeState(), versionableUuid).exists();
     }
 
     private void removeVersionProperties(final NodeBuilder versionableBuilder) {
@@ -169,6 +185,10 @@ public class VersionableEditor extends D
         versionableBuilder.removeProperty(JCR_ISCHECKEDOUT);
     }
 
+    private void createEmptyHistory(NodeBuilder versionable) throws CommitFailedException {
+        vMgr.getOrCreateVersionHistory(versionable, Collections.<String,Object>emptyMap());
+    }
+
     @Override
     public Editor childNodeChanged(String name, NodeState before, NodeState after) throws CommitFailedException {
         return childNodeAdded(name, after);

Modified: jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/BrokenVersionableTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/BrokenVersionableTest.java?rev=1735984&r1=1735983&r2=1735984&view=diff
==============================================================================
--- jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/BrokenVersionableTest.java (original)
+++ jackrabbit/oak/branches/1.4/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/BrokenVersionableTest.java Mon Mar 21 15:07:44 2016
@@ -16,7 +16,12 @@
  */
 package org.apache.jackrabbit.oak.upgrade;
 
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.jackrabbit.api.JackrabbitSession;
+import org.apache.jackrabbit.commons.cnd.CndImporter;
 import org.apache.jackrabbit.oak.Oak;
 import org.apache.jackrabbit.oak.jcr.Jcr;
 import org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl;
@@ -35,11 +40,15 @@ import javax.jcr.Node;
 import javax.jcr.RepositoryException;
 import javax.jcr.Session;
 import javax.jcr.SimpleCredentials;
+import javax.jcr.version.VersionHistory;
+import javax.jcr.version.VersionIterator;
 import javax.jcr.version.VersionManager;
 
 import static org.apache.jackrabbit.JcrConstants.MIX_VERSIONABLE;
 import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 
 public class BrokenVersionableTest {
 
@@ -70,17 +79,27 @@ public class BrokenVersionableTest {
         SegmentNodeStore source = new SegmentNodeStore();
         RepositoryImpl repository = (RepositoryImpl) new Jcr(new Oak(source)).createRepository();
         Session session = repository.login(CREDENTIALS);
-        String versionHistoryPath;
+        List<String> versionHistoryPaths = new ArrayList<String>();
         try {
+            CndImporter.registerNodeTypes(new StringReader("<test = 'http://jackrabbit.apache.org/ns/test'>\n"
+                    + "[test:Versionable] > nt:unstructured, mix:versionable"), session);
+
             Node root = session.getRootNode();
-            Node versionable = root.addNode("versionable", NT_UNSTRUCTURED);
-            versionable.addMixin(MIX_VERSIONABLE);
-            versionable.addNode("child", NT_UNSTRUCTURED);
+
+            Node versionable1 = root.addNode("versionable1", NT_UNSTRUCTURED);
+            versionable1.addMixin(MIX_VERSIONABLE);
+            versionable1.addNode("child", NT_UNSTRUCTURED);
+
+            Node versionable2 = root.addNode("versionable2", "test:Versionable");
+            versionable2.addNode("child", NT_UNSTRUCTURED);
+
             session.save();
 
             VersionManager vMgr = session.getWorkspace().getVersionManager();
-            vMgr.checkin("/versionable");
-            versionHistoryPath = vMgr.getVersionHistory("/versionable").getPath();
+            vMgr.checkin("/versionable1");
+            vMgr.checkin("/versionable2");
+            versionHistoryPaths.add(vMgr.getVersionHistory("/versionable1").getPath());
+            versionHistoryPaths.add(vMgr.getVersionHistory("/versionable2").getPath());
         } finally {
             session.logout();
             repository.shutdown();
@@ -88,9 +107,10 @@ public class BrokenVersionableTest {
 
         // remove version history to corrupt the JCR repository structure
         NodeBuilder rootBuilder = source.getRoot().builder();
-        NodeStateTestUtils.createOrGetBuilder(rootBuilder, versionHistoryPath).remove();
+        for (String versionHistoryPath : versionHistoryPaths) {
+            NodeStateTestUtils.createOrGetBuilder(rootBuilder, versionHistoryPath).remove();
+        }
         source.merge(rootBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
-
         return source;
     }
 
@@ -101,8 +121,16 @@ public class BrokenVersionableTest {
     @Test
     public void verifyNoVersionable() throws RepositoryException {
         Session session = createAdminSession();
+        VersionManager vMgr = session.getWorkspace().getVersionManager();
         try {
-            assertFalse(session.getNode("/versionable").isNodeType(MIX_VERSIONABLE));
+            assertFalse(session.getNode("/versionable1").isNodeType(MIX_VERSIONABLE));
+
+            Node versionable2 = session.getNode("/versionable2");
+            assertTrue(versionable2.isNodeType(MIX_VERSIONABLE));
+            VersionHistory history = vMgr.getVersionHistory(versionable2.getPath());
+            VersionIterator versions = history.getAllVersions();
+            assertEquals("jcr:rootVersion", versions.nextVersion().getName());
+            assertFalse(versions.hasNext());
         } finally {
             session.logout();
         }