Author: tomekr Date: Thu Jun 21 11:49:45 2018 New Revision: 1833998 URL: http://svn.apache.org/viewvc?rev=1833998&view=rev Log: OAK-7561: Don't migrate the checkpoints (reverted)
Modified: jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/InitialContentMigrator.java jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/InitialContentMigratorTest.java Modified: jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/InitialContentMigrator.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/InitialContentMigrator.java?rev=1833998&r1=1833997&r2=1833998&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/InitialContentMigrator.java (original) +++ jackrabbit/oak/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/InitialContentMigrator.java Thu Jun 21 11:49:45 2018 @@ -17,8 +17,10 @@ package org.apache.jackrabbit.oak.composite; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; import org.apache.jackrabbit.oak.api.CommitFailedException; -import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState; +import org.apache.jackrabbit.oak.api.PropertyState; +import org.apache.jackrabbit.oak.api.Type; import org.apache.jackrabbit.oak.plugins.migration.FilteringNodeState; import org.apache.jackrabbit.oak.plugins.migration.report.LoggingReporter; import org.apache.jackrabbit.oak.plugins.migration.report.ReportingNodeState; @@ -35,8 +37,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; -import java.util.Collections; import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; import java.util.Set; public class InitialContentMigrator { @@ -121,20 +125,61 @@ public class InitialContentMigrator { LOG.info("Exclude: {}", excludePaths); LOG.info("Exclude fragments: {} @ {}", excludeFragments, fragmentPaths); - NodeState targetRoot = targetNodeStore.getRoot(); - NodeBuilder targetBuilder = targetRoot.builder(); - NodeState seedRoot = wrapNodeState(seedNodeStore.getRoot(), true); - seedRoot.compareAgainstBaseState(EmptyNodeState.EMPTY_NODE, new ApplyDiff(targetBuilder)); - targetNodeStore.merge(targetBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY); + Map<String, String> nameToRevision = new LinkedHashMap<>(); + Map<String, String> checkpointSegmentToDoc = new LinkedHashMap<>(); + + NodeState initialRoot = targetNodeStore.getRoot(); + NodeState targetRoot = initialRoot; + NodeState previousRoot = initialRoot; + for (String checkpointName : seedNodeStore.checkpoints()) { + NodeState checkpointRoot = seedNodeStore.retrieve(checkpointName); + Map<String, String> checkpointInfo = seedNodeStore.checkpointInfo(checkpointName); + + if (previousRoot == initialRoot) { + LOG.info("Migrating first checkpoint: {}", checkpointName); + } else { + LOG.info("Applying diff to {}", checkpointName); + } + LOG.info("Checkpoint metadata: {}", checkpointInfo); + + targetRoot = copyDiffToTarget(previousRoot, checkpointRoot, targetRoot); + previousRoot = checkpointRoot; + + String newCheckpointName = targetNodeStore.checkpoint(Long.MAX_VALUE, checkpointInfo); + if (checkpointInfo.containsKey("name")) { + nameToRevision.put(checkpointInfo.get("name"), newCheckpointName); + } + checkpointSegmentToDoc.put(checkpointName, newCheckpointName); + } + + NodeState sourceRoot = seedNodeStore.getRoot(); + if (previousRoot == initialRoot) { + LOG.info("No checkpoints found; migrating head"); + } else { + LOG.info("Applying diff to head"); + } - String fullTextAsyncId = targetNodeStore.checkpoint(Long.MAX_VALUE, Collections.singletonMap("name", "fulltext-async")); - String asyncId = targetNodeStore.checkpoint(Long.MAX_VALUE, Collections.singletonMap("name", "async")); + targetRoot = copyDiffToTarget(previousRoot, sourceRoot, targetRoot); + + LOG.info("Rewriting checkpoint names in /:async {}", nameToRevision); + NodeBuilder targetBuilder = targetRoot.builder(); + NodeBuilder async = targetBuilder.getChildNode(":async"); + for (Map.Entry<String, String> e : nameToRevision.entrySet()) { + async.setProperty(e.getKey(), e.getValue(), Type.STRING); + + PropertyState temp = async.getProperty(e.getKey() + "-temp"); + if (temp == null) { + continue; + } + List<String> tempValues = Lists.newArrayList(temp.getValue(Type.STRINGS)); + for (Map.Entry<String, String> sToD : checkpointSegmentToDoc.entrySet()) { + if (tempValues.contains(sToD.getKey())) { + tempValues.set(tempValues.indexOf(sToD.getKey()), sToD.getValue()); + } + } + async.setProperty(e.getKey() + "-temp", tempValues, Type.STRINGS); + } - targetBuilder = targetNodeStore.getRoot().builder(); - targetBuilder.getChildNode(":async").remove(); - NodeBuilder asyncNode = targetBuilder.child(":async"); - asyncNode.setProperty("fulltext-async", fullTextAsyncId); - asyncNode.setProperty("async", asyncId); targetNodeStore.merge(targetBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY); markMigrationAsDone(); @@ -147,6 +192,15 @@ public class InitialContentMigrator { targetNodeStore.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY); } + private NodeState copyDiffToTarget(NodeState before, NodeState after, NodeState targetRoot) throws CommitFailedException { + NodeBuilder targetBuilder = targetRoot.builder(); + NodeState currentRoot = wrapNodeState(after, true); + NodeState baseRoot = wrapNodeState(before, false); + currentRoot.compareAgainstBaseState(baseRoot, new ApplyDiff(targetBuilder)); + return targetNodeStore.merge(targetBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY); + } + + private NodeState wrapNodeState(NodeState nodeState, boolean logPaths) { NodeState wrapped = nodeState; wrapped = FilteringNodeState.wrap("/", wrapped, includePaths, excludePaths, fragmentPaths, excludeFragments); Modified: jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/InitialContentMigratorTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/InitialContentMigratorTest.java?rev=1833998&r1=1833997&r2=1833998&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/InitialContentMigratorTest.java (original) +++ jackrabbit/oak/trunk/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/InitialContentMigratorTest.java Thu Jun 21 11:49:45 2018 @@ -16,9 +16,7 @@ */ package org.apache.jackrabbit.oak.composite; -import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; @@ -26,6 +24,8 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.UUID; +import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicBoolean; import java.util.stream.Collectors; @@ -48,20 +48,27 @@ import org.junit.Test; public class InitialContentMigratorTest { @Test - public void migrateContent() throws IOException, CommitFailedException { + public void migrateContentWithCheckpoints() throws IOException, CommitFailedException { + // 1. populate the seed store with // . // \- first // \- second // \- third // - // 2. the mount only includes the '/first' path, so only the + // 2. checkpoint before adding the third node + // + // 3. the mount only includes the '/first' path, so only the // 'second' and 'third' nodes should be available MemoryNodeStore seed = new MemoryNodeStore(); NodeBuilder root = seed.getRoot().builder(); root.child("first"); root.child("second"); + seed.merge(root, EmptyHook.INSTANCE, CommitInfo.EMPTY); + String checkpoint1 = seed.checkpoint(TimeUnit.MINUTES.toMillis(10)); + + root = seed.getRoot().builder(); root.child("third"); seed.merge(root, EmptyHook.INSTANCE, CommitInfo.EMPTY); @@ -78,15 +85,13 @@ public class InitialContentMigratorTest assertFalse("Node /first should not have been migrated", targetRoot.hasChildNode("first")); assertTrue("Node /second should have been migrated", targetRoot.hasChildNode("second")); assertTrue("Node /third should have been migrated", targetRoot.hasChildNode("third")); + + // verify that the 'second' node is visible in the migrated store when retrieving the checkpoint + NodeState checkpointTargetRoot = target.retrieve(checkpoint1); + assertFalse("Node /first should not have been migrated", checkpointTargetRoot.hasChildNode("first")); + assertTrue("Node /second should have been migrated", checkpointTargetRoot.hasChildNode("second")); + assertFalse("Node /third should not be visible from the migrated checkpoint", checkpointTargetRoot.hasChildNode("third")); - // verify that the async and fulltext-async checkpoints are available - NodeState mountAsync = target.getRoot().getChildNode(":async"); - assertNotNull(target.retrieve(mountAsync.getString("async"))); - assertNotNull(target.retrieve(mountAsync.getString("fulltext-async"))); - - // verify the info objects for the checkpoints - assertEquals("async", target.checkpointInfo(mountAsync.getString("async")).get("name")); - assertEquals("fulltext-async", target.checkpointInfo(mountAsync.getString("fulltext-async")).get("name")); } @Test