Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NameFilteringNodeState.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NameFilteringNodeState.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NameFilteringNodeState.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NameFilteringNodeState.java Tue Nov 21 10:52:20 2017 @@ -18,7 +18,6 @@ package org.apache.jackrabbit.oak.upgrad import com.google.common.base.Charsets; import org.apache.jackrabbit.oak.api.PropertyState; -import org.apache.jackrabbit.oak.plugins.document.util.Utils; import org.apache.jackrabbit.oak.spi.state.NodeState; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -70,7 +69,7 @@ public class NameFilteringNodeState exte * * @param name * to check - * @return true if the name is longer than {@link Utils#NODE_NAME_LIMIT} + * @return true if the name is longer than {@code org.apache.jackrabbit.oak.plugins.document.util.Utils#NODE_NAME_LIMIT} */ public static boolean isNameTooLong(@Nonnull String name) { // OAK-1589: maximum supported length of name for DocumentNodeStore
Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/NodeStateCopier.java Tue Nov 21 10:52:20 2017 @@ -65,6 +65,9 @@ import static java.util.Collections.empt * <b>Exclude paths:</b> if exclude paths are set, any nodes matching * or below the excluded path are not copied. If an excluded node does * exist in the target, it is removed (see also merge paths). + * <b>Exclude fragments:</b> if exclude fragments are set, nodes with names + * matching any of the fragments (and their subtrees) are not copied. If an + * excluded node does exist in the target, it is removed. * <b>Merge paths:</b> if merge paths are set, any nodes matching or * below the merged path will not be deleted from target, even if they * are missing in (or excluded from) the source. @@ -77,11 +80,17 @@ public class NodeStateCopier { private final Set<String> excludePaths; + private final Set<String> fragmentPaths; + + private final Set<String> excludeFragments; + private final Set<String> mergePaths; - private NodeStateCopier(Set<String> includePaths, Set<String> excludePaths, Set<String> mergePaths) { + private NodeStateCopier(Set<String> includePaths, Set<String> excludePaths, Set<String> fragmentPaths, Set<String> excludeFragments, Set<String> mergePaths) { this.includePaths = includePaths; this.excludePaths = excludePaths; + this.fragmentPaths = fragmentPaths; + this.excludeFragments = excludeFragments; this.mergePaths = mergePaths; } @@ -89,7 +98,7 @@ public class NodeStateCopier { * Create a NodeStateCopier.Builder. * * @return a NodeStateCopier.Builder - * @see org.apache.jackrabbit.oak.upgrade.nodestate.NodeStateCopier.Builder + * @see NodeStateCopier.Builder */ public static Builder builder() { return new Builder(); @@ -103,7 +112,7 @@ public class NodeStateCopier { * @param target NodeStore to copy to. * @return true if the target has been modified * @throws CommitFailedException if the operation fails - * @see org.apache.jackrabbit.oak.upgrade.nodestate.NodeStateCopier.Builder#copy(NodeStore, NodeStore) + * @see NodeStateCopier.Builder#copy(NodeStore, NodeStore) */ public static boolean copyNodeStore(@Nonnull final NodeStore source, @Nonnull final NodeStore target) throws CommitFailedException { @@ -141,7 +150,7 @@ public class NodeStateCopier { } private boolean copyNodeState(@Nonnull final NodeState sourceRoot, @Nonnull final NodeBuilder targetRoot) { - final NodeState wrappedSource = FilteringNodeState.wrap("/", sourceRoot, this.includePaths, this.excludePaths); + final NodeState wrappedSource = FilteringNodeState.wrap("/", sourceRoot, this.includePaths, this.excludePaths, this.fragmentPaths, this.excludeFragments); boolean hasChanges = false; for (String includePath : this.includePaths) { hasChanges = copyMissingAncestors(sourceRoot, targetRoot, includePath) || hasChanges; @@ -294,6 +303,10 @@ public class NodeStateCopier { private Set<String> excludePaths = emptySet(); + private Set<String> fragmentPaths = emptySet(); + + private Set<String> excludeFragments = emptySet(); + private Set<String> mergePaths = emptySet(); private Builder() {} @@ -304,7 +317,7 @@ public class NodeStateCopier { * * @param paths include paths * @return this Builder instance - * @see NodeStateCopier#NodeStateCopier(Set, Set, Set) + * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set, Set) */ @Nonnull public Builder include(@Nonnull Set<String> paths) { @@ -319,7 +332,7 @@ public class NodeStateCopier { * * @param paths include paths * @return this Builder instance - * @see NodeStateCopier#NodeStateCopier(Set, Set, Set) + * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set, Set) */ @Nonnull public Builder include(@Nonnull String... paths) { @@ -331,7 +344,7 @@ public class NodeStateCopier { * * @param paths exclude paths * @return this Builder instance - * @see NodeStateCopier#NodeStateCopier(Set, Set, Set) + * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set, Set) */ @Nonnull public Builder exclude(@Nonnull Set<String> paths) { @@ -346,7 +359,7 @@ public class NodeStateCopier { * * @param paths exclude paths * @return this Builder instance - * @see NodeStateCopier#NodeStateCopier(Set, Set, Set) + * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set, Set) */ @Nonnull public Builder exclude(@Nonnull String... paths) { @@ -354,11 +367,65 @@ public class NodeStateCopier { } /** + * Set fragment paths. + * + * @param paths fragment paths + * @return this Builder instance + * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set, Set) + */ + @Nonnull + public Builder supportFragment(@Nonnull Set<String> paths) { + if (!checkNotNull(paths).isEmpty()) { + this.fragmentPaths = copyOf(paths); + } + return this; + } + + /** + * Convenience wrapper for {@link #supportFragment(Set)}. + * + * @param paths fragment paths + * @return this Builder instance + * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set, Set) + */ + @Nonnull + public Builder supportFragment(@Nonnull String... paths) { + return supportFragment(copyOf(checkNotNull(paths))); + } + + /** + * Set exclude fragments. + * + * @param fragments exclude fragments + * @return this Builder instance + * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set, Set) + */ + @Nonnull + public Builder excludeFragments(@Nonnull Set<String> fragments) { + if (!checkNotNull(fragments).isEmpty()) { + this.excludeFragments = copyOf(fragments); + } + return this; + } + + /** + * Convenience wrapper for {@link #exclude(Set)}. + * + * @param fragments exclude fragments + * @return this Builder instance + * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set, Set) + */ + @Nonnull + public Builder excludeFragments(@Nonnull String... fragments) { + return exclude(copyOf(checkNotNull(fragments))); + } + + /** * Set merge paths. * * @param paths merge paths * @return this Builder instance - * @see NodeStateCopier#NodeStateCopier(Set, Set, Set) + * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set, Set) */ @Nonnull public Builder merge(@Nonnull Set<String> paths) { @@ -373,7 +440,7 @@ public class NodeStateCopier { * * @param paths merge paths * @return this Builder instance - * @see NodeStateCopier#NodeStateCopier(Set, Set, Set) + * @see NodeStateCopier#NodeStateCopier(Set, Set, Set, Set, Set) */ @Nonnull public Builder merge(@Nonnull String... paths) { @@ -394,7 +461,7 @@ public class NodeStateCopier { * the same content */ public boolean copy(@Nonnull final NodeState sourceRoot, @Nonnull final NodeBuilder targetRoot) { - final NodeStateCopier copier = new NodeStateCopier(includePaths, excludePaths, mergePaths); + final NodeStateCopier copier = new NodeStateCopier(includePaths, excludePaths, fragmentPaths, excludeFragments, mergePaths); return copier.copyNodeState(checkNotNull(sourceRoot), checkNotNull(targetRoot)); } Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/LoggingReporter.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/LoggingReporter.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/LoggingReporter.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/LoggingReporter.java Tue Nov 21 10:52:20 2017 @@ -18,6 +18,7 @@ */ package org.apache.jackrabbit.oak.upgrade.nodestate.report; +import com.google.common.collect.EvictingQueue; import org.apache.jackrabbit.oak.commons.PathUtils; import org.slf4j.Logger; @@ -34,6 +35,8 @@ public class LoggingReporter extends Per private final String verb; + private final EvictingQueue lastPaths = EvictingQueue.create(100); + /** * Constructor that allows setting the intervals to log node and property * accesses to a given logger. @@ -72,4 +75,14 @@ public class LoggingReporter extends Per protected void reportPeriodicProperty(final long count, @Nonnull final ReportingNodeState parent, @Nonnull final String propertyName) { logger.info("{} properties #{}: {}", verb, count, PathUtils.concat(parent.getPath(), propertyName)); } -} + + protected boolean skipNodeState(@Nonnull final ReportingNodeState nodeState) { + String path = nodeState.getPath(); + if (lastPaths.contains(path)) { + return true; + } else { + lastPaths.add(path); + return false; + } + } +} \ No newline at end of file Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporter.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporter.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporter.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/nodestate/report/PeriodicReporter.java Tue Nov 21 10:52:20 2017 @@ -68,12 +68,21 @@ public abstract class PeriodicReporter i protected abstract void reportPeriodicProperty( final long count, @Nonnull final ReportingNodeState parent, @Nonnull final String propertyName); + + protected boolean skipNodeState(@Nonnull final ReportingNodeState nodeState) { + return false; + } + @Override public final void reportNode(@Nonnull final ReportingNodeState nodeState) { if (nodeLogInterval == -1) { return; } + if (skipNodeState(nodeState)) { + return; + } + final long count = nodes.incrementAndGet(); if (count % nodeLogInterval == 0) { reportPeriodicNode(count, nodeState); Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionCopier.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionCopier.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionCopier.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionCopier.java Tue Nov 21 10:52:20 2017 @@ -16,24 +16,20 @@ */ package org.apache.jackrabbit.oak.upgrade.version; -import static org.apache.jackrabbit.JcrConstants.JCR_CREATED; import static org.apache.jackrabbit.JcrConstants.NT_VERSION; import java.util.Calendar; import java.util.Iterator; -import org.apache.jackrabbit.oak.api.Type; import org.apache.jackrabbit.oak.plugins.nodetype.TypePredicate; -import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry; import org.apache.jackrabbit.oak.spi.state.NodeBuilder; import org.apache.jackrabbit.oak.spi.state.NodeState; import org.apache.jackrabbit.oak.upgrade.DescendantsIterator; import org.apache.jackrabbit.oak.upgrade.nodestate.NodeStateCopier; -import org.apache.jackrabbit.util.ISO8601; import static org.apache.jackrabbit.oak.plugins.version.VersionConstants.VERSION_STORE_PATH; - import static org.apache.jackrabbit.oak.upgrade.version.VersionHistoryUtil.getRelativeVersionHistoryPath; +import static org.apache.jackrabbit.oak.upgrade.version.VersionHistoryUtil.getVersionHistoryLastModified; import static org.apache.jackrabbit.oak.upgrade.version.VersionHistoryUtil.getVersionHistoryNodeState; /** @@ -94,21 +90,4 @@ public class VersionCopier { return false; } - private Calendar getVersionHistoryLastModified(final NodeState versionHistory) { - Calendar youngest = Calendar.getInstance(); - youngest.setTimeInMillis(0); - for (final ChildNodeEntry entry : versionHistory.getChildNodeEntries()) { - final NodeState version = entry.getNodeState(); - if (!isVersion.apply(version)) { - continue; - } - if (version.hasProperty(JCR_CREATED)) { - final Calendar created = ISO8601.parse(version.getProperty(JCR_CREATED).getValue(Type.DATE)); - if (created.after(youngest)) { - youngest = created; - } - } - } - return youngest; - } } Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionHistoryUtil.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionHistoryUtil.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionHistoryUtil.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionHistoryUtil.java Tue Nov 21 10:52:20 2017 @@ -16,24 +16,46 @@ */ package org.apache.jackrabbit.oak.upgrade.version; +import static com.google.common.collect.ImmutableSet.of; import static com.google.common.collect.Iterables.concat; +import static com.google.common.collect.Sets.newHashSet; import static java.util.Collections.singleton; +import static org.apache.jackrabbit.JcrConstants.JCR_BASEVERSION; +import static org.apache.jackrabbit.JcrConstants.JCR_CREATED; +import static org.apache.jackrabbit.JcrConstants.JCR_ISCHECKEDOUT; +import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES; +import static org.apache.jackrabbit.JcrConstants.JCR_PREDECESSORS; import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE; import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM; +import static org.apache.jackrabbit.JcrConstants.JCR_UUID; +import static org.apache.jackrabbit.JcrConstants.JCR_VERSIONHISTORY; import static org.apache.jackrabbit.JcrConstants.JCR_VERSIONSTORAGE; +import static org.apache.jackrabbit.JcrConstants.MIX_REFERENCEABLE; +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.REP_VERSIONSTORAGE; import java.util.ArrayList; +import java.util.Calendar; import java.util.List; +import java.util.Set; import org.apache.jackrabbit.oak.api.Type; +import org.apache.jackrabbit.oak.commons.PathUtils; +import org.apache.jackrabbit.oak.plugins.nodetype.TypePredicate; +import org.apache.jackrabbit.oak.spi.state.ChildNodeEntry; import org.apache.jackrabbit.oak.spi.state.NodeBuilder; import org.apache.jackrabbit.oak.spi.state.NodeState; import com.google.common.base.Joiner; +import org.apache.jackrabbit.util.ISO8601; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; public class VersionHistoryUtil { + private static final Logger LOG = LoggerFactory.getLogger(VersionHistoryUtil.class); + public static String getRelativeVersionHistoryPath(String versionableUuid) { return Joiner.on('/').join(concat( singleton(""), @@ -44,7 +66,7 @@ public class VersionHistoryUtil { /** * Constructs the version history path based on the versionable's UUID. * - * @param root The root NodeState below which to look for the version. + * @param versionStorage below which to look for the version. * @param versionableUuid The String representation of the versionable's UUID. * @return The NodeState corresponding to the version history, or {@code null} * if it does not exist. @@ -57,7 +79,7 @@ public class VersionHistoryUtil { return historyParent.getChildNode(versionableUuid); } - static NodeBuilder getVersionHistoryBuilder(NodeBuilder versionStorage, String versionableUuid) { + public static NodeBuilder getVersionHistoryBuilder(NodeBuilder versionStorage, String versionableUuid) { NodeBuilder history = versionStorage; for (String segment : getRelativeVersionHistoryPathSegments(versionableUuid)) { history = history.getChildNode(segment); @@ -89,4 +111,108 @@ public class VersionHistoryUtil { return vs; } + public static List<String> getVersionableNodes(NodeState root, TypePredicate isVersionable, Calendar olderThan) { + List<String> paths = new ArrayList<String>(); + NodeState versionStorage = getVersionStorage(root); + getVersionableNodes(root, versionStorage, isVersionable, olderThan, "/", paths); + return paths; + } + + + private static void getVersionableNodes(NodeState node, NodeState versionStorage, TypePredicate isVersionable, Calendar olderThan, String path, List<String> paths) { + if (isVersionable.apply(node)) { + if (olderThan == null) { + paths.add(path); + } else { + NodeState versionHistory = getVersionHistoryNodeState(versionStorage, node.getString(JCR_UUID)); + Calendar lastModified = getVersionHistoryLastModified(versionHistory); + if (lastModified.before(olderThan)) { + paths.add(path); + } + } + } + for (ChildNodeEntry c : node.getChildNodeEntries()) { + getVersionableNodes(c.getNodeState(), versionStorage, isVersionable, olderThan, PathUtils.concat(path, c.getName()), paths); + } + } + + public static Calendar getVersionHistoryLastModified(NodeState versionHistory) { + Calendar youngest = Calendar.getInstance(); + youngest.setTimeInMillis(0); + for (final ChildNodeEntry entry : versionHistory.getChildNodeEntries()) { + final NodeState version = entry.getNodeState(); + if (version.hasProperty(JCR_CREATED)) { + final Calendar created = ISO8601.parse(version.getProperty(JCR_CREATED).getValue(Type.DATE)); + if (created.after(youngest)) { + youngest = created; + } + } + } + return youngest; + } + + public static void removeVersionProperties(NodeBuilder versionableBuilder, TypePredicate isReferenceable) { + assert versionableBuilder.exists(); + + removeMixin(versionableBuilder, MIX_VERSIONABLE); + + // we don't know if the UUID is otherwise referenced, + // so make sure the node remains referencable + if (!isReferenceable.apply(versionableBuilder.getNodeState())) { + addMixin(versionableBuilder, MIX_REFERENCEABLE); + } + + versionableBuilder.removeProperty(JCR_VERSIONHISTORY); + versionableBuilder.removeProperty(JCR_PREDECESSORS); + versionableBuilder.removeProperty(JCR_BASEVERSION); + versionableBuilder.removeProperty(JCR_ISCHECKEDOUT); + } + + static void addMixin(NodeBuilder builder, String name) { + if (builder.hasProperty(JCR_MIXINTYPES)) { + final Set<String> mixins = newHashSet(builder.getProperty(JCR_MIXINTYPES).getValue(Type.NAMES)); + if (mixins.add(name)) { + builder.setProperty(nameProperty(JCR_MIXINTYPES, mixins)); + } + } else { + builder.setProperty(nameProperty(JCR_MIXINTYPES, of(name))); + } + } + + private static void removeMixin(NodeBuilder builder, String name) { + if (builder.hasProperty(JCR_MIXINTYPES)) { + final Set<String> mixins = newHashSet(builder.getProperty(JCR_MIXINTYPES).getValue(Type.NAMES)); + if (mixins.remove(name)) { + if (mixins.isEmpty()) { + builder.removeProperty(JCR_MIXINTYPES); + } else { + builder.setProperty(nameProperty(JCR_MIXINTYPES, mixins)); + } + } + } + } + + public static NodeBuilder removeVersions(NodeState root, + List<String> toRemove) { + NodeBuilder rootBuilder = root.builder(); + TypePredicate isReferenceable = new TypePredicate(root, MIX_REFERENCEABLE); + NodeBuilder versionStorage = getVersionStorage(rootBuilder); + for (String p : toRemove) { + LOG.info("Removing version history for {}", p); + NodeBuilder b = getBuilder(rootBuilder, p); + String uuid = b.getString(JCR_UUID); + VersionHistoryUtil.removeVersionProperties(b, isReferenceable); + getVersionHistoryBuilder(versionStorage, uuid).remove(); + } + return rootBuilder; + } + + private static NodeBuilder getBuilder(NodeBuilder root, String path) { + NodeBuilder builder = root; + for (String e : PathUtils.elements(path)) { + builder = builder.child(e); + } + return builder; + } + } Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionableEditor.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionableEditor.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionableEditor.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionableEditor.java Tue Nov 21 10:52:20 2017 @@ -34,19 +34,14 @@ import java.util.Collections; import java.util.Set; import static com.google.common.collect.ImmutableSet.of; -import static com.google.common.collect.Sets.newHashSet; -import static org.apache.jackrabbit.JcrConstants.JCR_BASEVERSION; -import static org.apache.jackrabbit.JcrConstants.JCR_ISCHECKEDOUT; -import static org.apache.jackrabbit.JcrConstants.JCR_MIXINTYPES; -import static org.apache.jackrabbit.JcrConstants.JCR_PREDECESSORS; import static org.apache.jackrabbit.JcrConstants.JCR_UUID; -import static org.apache.jackrabbit.JcrConstants.JCR_VERSIONHISTORY; import static org.apache.jackrabbit.JcrConstants.MIX_REFERENCEABLE; 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.addMixin; import static org.apache.jackrabbit.oak.upgrade.version.VersionHistoryUtil.getVersionHistoryBuilder; import static org.apache.jackrabbit.oak.upgrade.version.VersionHistoryUtil.getVersionStorage; +import static org.apache.jackrabbit.oak.upgrade.version.VersionHistoryUtil.removeVersionProperties; /** * The VersionableEditor provides two possible ways to handle @@ -56,7 +51,7 @@ import static org.apache.jackrabbit.oak. * <li> * it can skip copying version histories and remove the * {@code mix:versionable} mixin together with any related - * properties (see {@link #removeVersionProperties(NodeBuilder)}). + * properties (see {@link VersionHistoryUtil#removeVersionProperties(NodeBuilder, TypePredicate)}). * </li> * </ul> */ @@ -143,7 +138,7 @@ public class VersionableEditor extends D setVersionablePath(versionableUuid); } else { NodeBuilder versionableBuilder = getNodeBuilder(rootBuilder, this.path); - removeVersionProperties(versionableBuilder); + removeVersionProperties(versionableBuilder, isReferenceable); if (isVersionable.apply(versionableBuilder.getNodeState())) { logger.warn("Node {} is still versionable. Creating empty version history.", path); createEmptyHistory(versionableBuilder); @@ -173,23 +168,6 @@ public class VersionableEditor extends D return getVersionHistoryBuilder(versionStorage, versionableUuid).exists(); } - private void removeVersionProperties(final NodeBuilder versionableBuilder) { - assert versionableBuilder.exists(); - - removeMixin(versionableBuilder, MIX_VERSIONABLE); - - // we don't know if the UUID is otherwise referenced, - // so make sure the node remains referencable - if (!isReferenceable.apply(versionableBuilder.getNodeState())) { - addMixin(versionableBuilder, MIX_REFERENCEABLE); - } - - versionableBuilder.removeProperty(JCR_VERSIONHISTORY); - versionableBuilder.removeProperty(JCR_PREDECESSORS); - versionableBuilder.removeProperty(JCR_BASEVERSION); - versionableBuilder.removeProperty(JCR_ISCHECKEDOUT); - } - private void createEmptyHistory(NodeBuilder versionable) throws CommitFailedException { vMgr.getOrCreateVersionHistory(versionable, Collections.<String,Object>emptyMap()); } @@ -224,27 +202,5 @@ public class VersionableEditor extends D return builder; } - private static void addMixin(NodeBuilder builder, String name) { - if (builder.hasProperty(JCR_MIXINTYPES)) { - final Set<String> mixins = newHashSet(builder.getProperty(JCR_MIXINTYPES).getValue(Type.NAMES)); - if (mixins.add(name)) { - builder.setProperty(nameProperty(JCR_MIXINTYPES, mixins)); - } - } else { - builder.setProperty(nameProperty(JCR_MIXINTYPES, of(name))); - } - } - private static void removeMixin(NodeBuilder builder, String name) { - if (builder.hasProperty(JCR_MIXINTYPES)) { - final Set<String> mixins = newHashSet(builder.getProperty(JCR_MIXINTYPES).getValue(Type.NAMES)); - if (mixins.remove(name)) { - if (mixins.isEmpty()) { - builder.removeProperty(JCR_MIXINTYPES); - } else { - builder.setProperty(nameProperty(JCR_MIXINTYPES, mixins)); - } - } - } - } } Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionablePropertiesEditor.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionablePropertiesEditor.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionablePropertiesEditor.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/version/VersionablePropertiesEditor.java Tue Nov 21 10:52:20 2017 @@ -69,8 +69,6 @@ public final class VersionableProperties private final TypePredicate isVersionable; - private final TypePredicate isSimpleVersionable; - private final TypePredicate isNtVersion; private final TypePredicate isFrozenNode; @@ -80,7 +78,6 @@ public final class VersionableProperties this.rootBuilder = rootBuilder; this.versionStorage = getVersionStorage(rootBuilder); this.isVersionable = new TypePredicate(rootBuilder.getNodeState(), MIX_VERSIONABLE); - this.isSimpleVersionable = new TypePredicate(rootBuilder.getNodeState(), MIX_SIMPLE_VERSIONABLE); this.isNtVersion = new TypePredicate(rootBuilder.getNodeState(), NT_VERSION); this.isFrozenNode = new TypePredicate(rootBuilder.getNodeState(), NT_FROZENNODE); } @@ -90,7 +87,6 @@ public final class VersionableProperties this.rootBuilder = parent.rootBuilder; this.versionStorage = parent.versionStorage; this.isVersionable = parent.isVersionable; - this.isSimpleVersionable = parent.isSimpleVersionable; this.isNtVersion = parent.isNtVersion; this.isFrozenNode = parent.isFrozenNode; } Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistorySidegradeTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistorySidegradeTest.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistorySidegradeTest.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistorySidegradeTest.java Tue Nov 21 10:52:20 2017 @@ -32,7 +32,6 @@ import java.io.IOException; public class CopyVersionHistorySidegradeTest extends CopyVersionHistoryTest { private static NodeStore sourceNodeStore; - @Before @Override public void upgradeRepository() throws Exception { @@ -50,15 +49,10 @@ public class CopyVersionHistorySidegrade } @Override - protected Session performCopy(VersionCopySetup setup) throws RepositoryException, IOException { - final NodeStore targetNodeStore = new MemoryNodeStore(); - final RepositorySidegrade sidegrade = new RepositorySidegrade(sourceNodeStore, targetNodeStore); + protected void migrate(VersionCopySetup setup, NodeStore target, String includePath) throws RepositoryException, IOException { + final RepositorySidegrade sidegrade = new RepositorySidegrade(sourceNodeStore, target); + sidegrade.setIncludes(includePath); setup.setup(sidegrade.versionCopyConfiguration); sidegrade.copy(); - - repository = (RepositoryImpl) new Jcr(new Oak(targetNodeStore)).createRepository(); - Session s = repository.login(AbstractRepositoryUpgradeTest.CREDENTIALS); - sessions.add(s); - return s; } } Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistoryTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistoryTest.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistoryTest.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistoryTest.java Tue Nov 21 10:52:20 2017 @@ -255,23 +255,50 @@ public class CopyVersionHistoryTest exte .getPrimaryNodeType()); } + @Test + public void removeVersionHistory() throws RepositoryException, IOException { + final NodeStore targetNodeStore = new SegmentNodeStore(); + migrate(new VersionCopySetup() { + @Override + public void setup(VersionCopyConfiguration config) { + } + }, targetNodeStore, "/"); + migrate(new VersionCopySetup() { + @Override + public void setup(VersionCopyConfiguration config) { + config.setCopyVersions(null); + config.setCopyOrphanedVersions(null); + } + }, targetNodeStore, "/versionables"); + repository = (RepositoryImpl) new Jcr(new Oak(targetNodeStore)).createRepository(); + Session s = repository.login(AbstractRepositoryUpgradeTest.CREDENTIALS); + sessions.add(s); + assertMissingHistories(s, VERSIONABLES_OLD, VERSIONABLES_YOUNG); + assertNonVersionablePaths(s, VERSIONABLES_OLD, VERSIONABLES_YOUNG); + + } + protected Session performCopy(VersionCopySetup setup) throws RepositoryException, IOException { + final NodeStore targetNodeStore = new SegmentNodeStore(); + migrate(setup, targetNodeStore, "/"); + repository = (RepositoryImpl) new Jcr(new Oak(targetNodeStore)).createRepository(); + Session s = repository.login(AbstractRepositoryUpgradeTest.CREDENTIALS); + sessions.add(s); + return s; + } + + protected void migrate(VersionCopySetup setup, NodeStore target, String includePath) throws RepositoryException, IOException { final RepositoryConfig sourceConfig = RepositoryConfig.create(source); final RepositoryContext sourceContext = RepositoryContext.create(sourceConfig); - final NodeStore targetNodeStore = new SegmentNodeStore(); try { - final RepositoryUpgrade upgrade = new RepositoryUpgrade(sourceContext, targetNodeStore); + final RepositoryUpgrade upgrade = new RepositoryUpgrade(sourceContext, target); + upgrade.setIncludes(includePath); setup.setup(upgrade.versionCopyConfiguration); - upgrade.setEarlyShutdown(true); + upgrade.setEarlyShutdown(false); upgrade.copy(null); } finally { sourceContext.getRepository().shutdown(); } - - repository = (RepositoryImpl) new Jcr(new Oak(targetNodeStore)).createRepository(); - Session s = repository.login(AbstractRepositoryUpgradeTest.CREDENTIALS); - sessions.add(s); - return s; } @After @@ -357,6 +384,18 @@ public class CopyVersionHistoryTest exte } } } + + private static void assertNonVersionablePaths(final Session session, final String... names) + throws RepositoryException { + for (final String mixin : MIXINS) { + final String pathPrefix = VERSIONABLES_PATH_PREFIX + mixin + "/"; + for (final String name : names) { + final String path = pathPrefix + name; + final Node node = session.getNode(path); + assertFalse("Node " + path + " shouldn't have mix:versionable mixin", node.isNodeType(MIX_VERSIONABLE)); + } + } + } private static void assertVersionablePath(final VersionHistory history, final String versionablePath) throws RepositoryException { Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java Tue Nov 21 10:52:20 2017 @@ -64,7 +64,8 @@ public class IncludeExcludeSidegradeTest final RepositorySidegrade sidegrade = new RepositorySidegrade(segmentNodeStore, target); sidegrade.setIncludes( "/content/foo/en", - "/content/assets/foo" + "/content/assets/foo", + "/content/other" ); sidegrade.setExcludes( "/content/assets/foo/2013", @@ -72,6 +73,12 @@ public class IncludeExcludeSidegradeTest "/content/assets/foo/2011", "/content/assets/foo/2010" ); + sidegrade.setExcludeFragments( + "oak-mount-libs-xyz" + ); + sidegrade.setFragmentPaths( + "/content/other/path" + ); sidegrade.copy(); } finally { fileStore.close(); Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeUpgradeTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeUpgradeTest.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeUpgradeTest.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeUpgradeTest.java Tue Nov 21 10:52:20 2017 @@ -54,7 +54,10 @@ public class IncludeExcludeUpgradeTest e JcrUtils.getOrCreateByPath("/content/assets/foo/2011", "nt:folder", session); JcrUtils.getOrCreateByPath("/content/assets/foo/2010", "nt:folder", session); JcrUtils.getOrCreateByPath("/content/assets/foo/2010/12", "nt:folder", session); - JcrUtils.getOrCreateByPath("/content/assets/foo/2010/11", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/other/path/foo/oak-mount-libs-xyz/node1", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/other/path/foo/oak-mount-libs-xyz/node2", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/other/path/foo/oak-mount-apps-abc/node3", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/other/path/foo/oak-mount-apps-abc/node4", "nt:folder", session); session.save(); } @@ -66,7 +69,8 @@ public class IncludeExcludeUpgradeTest e final RepositoryUpgrade upgrade = new RepositoryUpgrade(context, target); upgrade.setIncludes( "/content/foo/en", - "/content/assets/foo" + "/content/assets/foo", + "/content/other" ); upgrade.setExcludes( "/content/assets/foo/2013", @@ -74,6 +78,12 @@ public class IncludeExcludeUpgradeTest e "/content/assets/foo/2011", "/content/assets/foo/2010" ); + upgrade.setExcludeFragments( + "oak-mount-libs-xyz" + ); + upgrade.setFragmentPaths( + "/content/other/path" + ); upgrade.copy(null); } finally { context.getRepository().shutdown(); @@ -86,7 +96,9 @@ public class IncludeExcludeUpgradeTest e "/content/foo/en", "/content/assets/foo/2015/02", "/content/assets/foo/2015/01", - "/content/assets/foo/2014" + "/content/assets/foo/2014", + "/content/other/path/foo/oak-mount-apps-abc/node3", + "/content/other/path/foo/oak-mount-apps-abc/node4" ); } @@ -105,7 +117,9 @@ public class IncludeExcludeUpgradeTest e "/content/assets/foo/2013", "/content/assets/foo/2012", "/content/assets/foo/2011", - "/content/assets/foo/2010" + "/content/assets/foo/2010", + "/content/other/path/foo/oak-mount-libs-xyz/node1", + "/content/other/path/foo/oak-mount-libs-xyz/node2" ); } } Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeIndexTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeIndexTest.java?rev=1815907&view=auto ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeIndexTest.java (added) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeIndexTest.java Tue Nov 21 10:52:20 2017 @@ -0,0 +1,131 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.jackrabbit.oak.upgrade; + +import com.google.common.base.Joiner; +import org.apache.jackrabbit.oak.commons.IOUtils; +import org.apache.jackrabbit.oak.commons.PathUtils; +import org.apache.jackrabbit.oak.spi.state.NodeState; +import org.apache.jackrabbit.oak.spi.state.NodeStore; +import org.apache.jackrabbit.oak.upgrade.cli.AbstractOak2OakTest; +import org.apache.jackrabbit.oak.upgrade.cli.OakUpgrade; +import org.apache.jackrabbit.oak.upgrade.cli.container.BlobStoreContainer; +import org.apache.jackrabbit.oak.upgrade.cli.container.FileDataStoreContainer; +import org.apache.jackrabbit.oak.upgrade.cli.container.MongoNodeStoreContainer; +import org.apache.jackrabbit.oak.upgrade.cli.container.NodeStoreContainer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.jcr.RepositoryException; +import java.io.IOException; + +import static junit.framework.TestCase.assertTrue; +import static org.apache.jackrabbit.oak.upgrade.cli.container.MongoNodeStoreContainer.isMongoAvailable; +import static org.junit.Assert.assertFalse; +import static org.junit.Assume.assumeTrue; + +public class IncludeIndexTest extends AbstractOak2OakTest { + + private static final Logger log = LoggerFactory.getLogger(IncludeIndexTest.class); + + private final BlobStoreContainer blob; + + private final NodeStoreContainer source; + + private final NodeStoreContainer destination; + + private NodeStore nodeStore; + + @Before + public void prepare() throws Exception { + NodeStore source = getSourceContainer().open(); + try { + initContent(source); + } finally { + getSourceContainer().close(); + } + + String[] args = getArgs(); + log.info("oak2oak {}", Joiner.on(' ').join(args)); + OakUpgrade.main(args); + + nodeStore = destination.open(); + } + + @After + public void clean() throws IOException { + IOUtils.closeQuietly(getDestinationContainer()); + getDestinationContainer().clean(); + getSourceContainer().clean(); + } + + public IncludeIndexTest() throws IOException { + assumeTrue(isMongoAvailable()); + blob = new FileDataStoreContainer(); + source = new MongoNodeStoreContainer(blob); + destination = new MongoNodeStoreContainer(blob); + } + + @Override + protected NodeStoreContainer getSourceContainer() { + return source; + } + + @Override + protected NodeStoreContainer getDestinationContainer() { + return destination; + } + + @Override + protected String[] getArgs() { + return new String[] { "--src-datastore", blob.getDescription(), "--copy-versions=false", "--skip-init", "--include-index", "--include-paths=/apps,/libs", source.getDescription(), destination.getDescription() }; + } + + @Test + public void validateMigration() throws RepositoryException, IOException { + assertNodeExists("/oak:index/nodetype/:index/nt%3Afile/libs/sling/xss/config.xml"); + assertNodeExists("/oak:index/uuid/:index/" + getUuid("/apps/repl/components/repl/repl.html/jcr:content")); + + assertNodeMissing("/oak:index/nodetype/:index/nt%3Afile/sling.css"); + assertNodeMissing("/oak:index/uuid/:index/" + getUuid("/index.html/jcr:content")); + } + + private String getUuid(String path) { + return getNode(path).getString("jcr:uuid"); + } + + private void assertNodeMissing(String path) { + assertFalse(getNode(path).exists()); + } + + private void assertNodeExists(String path) { + assertTrue(getNode(path).exists()); + } + + private NodeState getNode(String path) { + NodeState ns = nodeStore.getRoot(); + for (String element : PathUtils.elements(path)) { + ns = ns.getChildNode(element); + } + return ns; + } +} \ No newline at end of file Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java Tue Nov 21 10:52:20 2017 @@ -39,7 +39,6 @@ import org.apache.jackrabbit.oak.plugins import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore; import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore; import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore; -import org.apache.jackrabbit.oak.plugins.segment.memory.MemoryStore; import org.apache.jackrabbit.oak.spi.state.NodeState; import org.apache.jackrabbit.oak.spi.state.NodeStore; import org.apache.jackrabbit.oak.stats.Clock; @@ -140,7 +139,7 @@ public class LongNameTest { @Test public void longNameOnSegmentStoreWorksFine() throws RepositoryException, IOException { - NodeStore nodeStore = new SegmentNodeStore(new MemoryStore()); + NodeStore nodeStore = new SegmentNodeStore(); upgrade(nodeStore, false, false); NodeState parent = getParent(nodeStore.getRoot()); Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java Tue Nov 21 10:52:20 2017 @@ -27,6 +27,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.List; +import java.util.Map; import java.util.Random; import javax.annotation.Nullable; @@ -43,6 +44,7 @@ import org.apache.commons.codec.digest.D import org.apache.jackrabbit.oak.Oak; import org.apache.jackrabbit.oak.api.Blob; import org.apache.jackrabbit.oak.api.CommitFailedException; +import org.apache.jackrabbit.oak.api.Type; import org.apache.jackrabbit.oak.commons.IOUtils; import org.apache.jackrabbit.oak.jcr.Jcr; import org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl; @@ -145,11 +147,12 @@ public abstract class AbstractOak2OakTes builder.setProperty("binary-prop", getRandomBlob(target)); builder.setProperty("checkpoint-state", "before"); target.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY); - target.checkpoint(60000); + String cp = target.checkpoint(60000); builder.setProperty("checkpoint-state", "after"); builder.setProperty("binary-prop", getRandomBlob(target)); - builder.child(":async").setProperty("test", "123"); + builder.child(":async").setProperty("test", cp); + builder.child(":async").setProperty("test2", Arrays.asList("123", cp, "321"), Type.STRINGS); target.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY); } @@ -218,7 +221,11 @@ public abstract class AbstractOak2OakTes String checkpointReference = null; for (CheckpointRetriever.Checkpoint c : CheckpointRetriever.getCheckpoints(destination)) { - checkpointReference = c.getName(); + String name = c.getName(); + if ("before".equals(destination.retrieve(name).getString("checkpoint-state"))) { + checkpointReference = name; + break; + } } assertNotNull(checkpointReference); @@ -226,7 +233,8 @@ public abstract class AbstractOak2OakTes NodeState checkpoint = destination.retrieve(checkpointReference); assertEquals("before", checkpoint.getString("checkpoint-state")); - assertEquals("123", destination.getRoot().getChildNode(":async").getString("test")); + assertEquals(checkpointReference, destination.getRoot().getChildNode(":async").getString("test")); + assertEquals(Arrays.asList("123", checkpointReference, "321"), destination.getRoot().getChildNode(":async").getStrings("test2")); for (String name : new String[] {"var", "etc", "sling.css", "apps", "libs", "sightly"}) { assertSameRecord(destination.getRoot().getChildNode(name), checkpoint.getChildNode(name)); Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactoryTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactoryTest.java?rev=1815907&view=auto ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactoryTest.java (added) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactoryTest.java Tue Nov 21 10:52:20 2017 @@ -0,0 +1,53 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.jackrabbit.oak.upgrade.cli.blob; + +import org.apache.jackrabbit.aws.ext.ds.S3DataStore; +import org.apache.jackrabbit.core.data.CachingDataStore; +import org.junit.Test; + +import java.lang.reflect.Field; +import java.util.Properties; + +import static org.junit.Assert.assertEquals; + +public class S3DataStoreFactoryTest { + + @Test + public void testPopulateProperties() throws NoSuchFieldException, IllegalAccessException { + Properties props = new Properties(); + props.setProperty("cacheSize", "123"); + + S3DataStore ds = S3DataStoreFactory.createDS("xyz", props); + assertEquals(123, readLong("cacheSize", CachingDataStore.class, ds)); + } + + @Test + public void testStripOsgiPrefix() throws NoSuchFieldException, IllegalAccessException { + Properties props = new Properties(); + props.setProperty("cacheSize", "I\"123\""); + + S3DataStore ds = S3DataStoreFactory.createDS("xyz", props); + assertEquals(123, readLong("cacheSize", CachingDataStore.class, ds)); + } + + private static long readLong(String fieldName, Class<?> clazz, Object object) throws NoSuchFieldException, IllegalAccessException { + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + return field.getLong(object); + } +} Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java Tue Nov 21 10:52:20 2017 @@ -22,9 +22,7 @@ import java.io.IOException; import org.apache.commons.io.FileUtils; import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore; import org.apache.jackrabbit.oak.plugins.segment.file.FileStore; -import org.apache.jackrabbit.oak.spi.state.NodeState; import org.apache.jackrabbit.oak.spi.state.NodeStore; -import org.apache.jackrabbit.oak.upgrade.cli.node.TarNodeStore; public class SegmentNodeStoreContainer implements NodeStoreContainer { @@ -66,12 +64,7 @@ public class SegmentNodeStoreContainer i builder.withBlobStore(blob.open()); } fs = builder.create(); - return new TarNodeStore(new SegmentNodeStore(fs), new TarNodeStore.SuperRootProvider() { - @Override - public NodeState getSuperRoot() { - return fs.getHead(); - } - }); + return new SegmentNodeStore(fs); } @Override Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeStateTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeStateTest.java?rev=1815907&r1=1815906&r2=1815907&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeStateTest.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/nodestate/FilteringNodeStateTest.java Tue Nov 21 10:52:20 2017 @@ -16,6 +16,21 @@ */ package org.apache.jackrabbit.oak.upgrade.nodestate; +import com.google.common.base.Predicate; +import com.google.common.collect.Iterables; +import org.apache.jackrabbit.oak.api.CommitFailedException; +import org.apache.jackrabbit.oak.api.PropertyState; +import org.apache.jackrabbit.oak.api.Type; +import org.apache.jackrabbit.oak.spi.state.NodeBuilder; +import org.apache.jackrabbit.oak.spi.state.NodeState; +import org.apache.jackrabbit.oak.spi.state.NodeStore; +import org.junit.Before; +import org.junit.Test; + +import javax.jcr.RepositoryException; +import java.io.IOException; +import java.util.Set; + import static com.google.common.collect.ImmutableSet.of; import static com.google.common.collect.Lists.newArrayList; import static java.util.Arrays.asList; @@ -36,22 +51,6 @@ import static org.junit.Assert.assertNul import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import java.io.IOException; -import java.util.Set; - -import javax.jcr.RepositoryException; - -import com.google.common.base.Predicate; -import com.google.common.collect.Iterables; -import org.apache.jackrabbit.oak.api.CommitFailedException; -import org.apache.jackrabbit.oak.api.PropertyState; -import org.apache.jackrabbit.oak.api.Type; -import org.apache.jackrabbit.oak.spi.state.NodeBuilder; -import org.apache.jackrabbit.oak.spi.state.NodeState; -import org.apache.jackrabbit.oak.spi.state.NodeStore; -import org.junit.Before; -import org.junit.Test; - public class FilteringNodeStateTest { private static final Set<String> DEFAULT_INCLUDES = FilteringNodeState.ALL; @@ -80,46 +79,46 @@ public class FilteringNodeStateTest { @Test public void shouldNotDecorateForNullArgs() { - final NodeState decorated = wrap("/", rootNodeState, null, null); + final NodeState decorated = wrap("/", rootNodeState, null, null, null, null); assertSame("root should be identical to decorated", rootNodeState, decorated); } @Test public void shouldNotDecorateForDefaultIncludes() { - final NodeState decorated = wrap("/", rootNodeState, DEFAULT_INCLUDES, null); + final NodeState decorated = wrap("/", rootNodeState, DEFAULT_INCLUDES, null, null, null); assertSame("root should be identical to decorated", rootNodeState, decorated); } @Test public void shouldNotDecorateForDefaultExcludes() { - final NodeState decorated = wrap("/", rootNodeState, null, DEFAULT_EXCLUDES); + final NodeState decorated = wrap("/", rootNodeState, null, DEFAULT_EXCLUDES, null, null); assertSame("root should be identical to decorated", rootNodeState, decorated); } @Test public void shouldNotDecorateForDefaultIncludesAndExcludes() { - final NodeState decorated = wrap("/", rootNodeState, DEFAULT_INCLUDES, DEFAULT_EXCLUDES); + final NodeState decorated = wrap("/", rootNodeState, DEFAULT_INCLUDES, DEFAULT_EXCLUDES, null, null); assertSame("root should be identical to decorated", rootNodeState, decorated); } @Test public void shouldNotDecorateIncludedPath() { final NodeState content = getNodeState(rootNodeState, "/content"); - final NodeState decorated = wrap("/content", content, of("/content"), null); + final NodeState decorated = wrap("/content", content, of("/content"), null, null, null); assertSame("content should be identical to decorated", content, decorated); } @Test public void shouldNotDecorateIncludedDescendants() { final NodeState foo = getNodeState(rootNodeState, "/content/foo"); - final NodeState decorated = wrap("/content/foo", foo, of("/content"), null); + final NodeState decorated = wrap("/content/foo", foo, of("/content"), null, null, null); assertSame("foo should be identical to decorated", foo, decorated); } @Test public void shouldDecorateAncestorOfExcludedDescendants() { final NodeState foo = getNodeState(rootNodeState, "/content/foo"); - final NodeState decorated = wrap("/content/foo", foo, of("/content"), of("/content/foo/de")); + final NodeState decorated = wrap("/content/foo", foo, of("/content"), of("/content/foo/de"), null, null); assertNotSame("foo should not be identical to decorated", foo, decorated); assertMissing(decorated, "de"); @@ -135,7 +134,7 @@ public class FilteringNodeStateTest { @Test public void shouldHaveCorrectChildOrderProperty() throws CommitFailedException { final NodeState content = rootNodeState.getChildNode("content"); - final NodeState decorated = wrap("/content", content, null, of("/content/foo")); + final NodeState decorated = wrap("/content", content, null, of("/content/foo"), null, null); assertTrue(decorated.hasProperty(OAK_CHILD_ORDER)); @@ -160,7 +159,7 @@ public class FilteringNodeStateTest { @Test public void shouldDecorateExcludedNode() { - final NodeState decoratedRoot = wrap("/", rootNodeState, of("/content"), of("/content/foo/de")); + final NodeState decoratedRoot = wrap("/", rootNodeState, of("/content"), of("/content/foo/de"), null, null); final NodeState de = getNodeState(rootNodeState, "/content/foo/de"); final NodeState decorated = getNodeState(decoratedRoot, "/content/foo/de"); assertFalse("de should not be equal to decorated", de.equals(decorated)); @@ -170,14 +169,14 @@ public class FilteringNodeStateTest { @Test public void shouldDecorateImplicitlyExcludedNode() { final NodeState content = getNodeState(rootNodeState, "/content"); - final NodeState decorated = wrap("/content", content, of("/apps"), null); + final NodeState decorated = wrap("/content", content, of("/apps"), null, null, null); assertNotSame("content should not be identical to decorated", content, decorated); } @Test public void shouldHideExcludedPathsViaExists() { - final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", "/libs")); + final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", "/libs"), null, null); assertMissing(decorated, "apps"); assertMissing(decorated, "libs/foo/install"); @@ -187,7 +186,7 @@ public class FilteringNodeStateTest { @Test public void shouldHideExcludedPathsViaHasChildNode() { - final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", "/libs")); + final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", "/libs"), null, null); assertExistingHasChildNode(decorated, "content"); assertMissingHasChildNode(decorated, "apps"); @@ -196,7 +195,7 @@ public class FilteringNodeStateTest { @Test public void shouldHideExcludedPathsViaGetChildNodeNames() { - final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", "/libs")); + final NodeState decorated = wrap("/", rootNodeState, null, of("/apps", "/libs"), null, null); assertExistingChildNodeName(decorated, "content"); assertMissingChildNodeName(decorated, "apps"); @@ -205,7 +204,7 @@ public class FilteringNodeStateTest { @Test public void shouldHideMissingIncludedPathsViaExists() { - final NodeState decorated = wrap("/", rootNodeState, of("/content"), null); + final NodeState decorated = wrap("/", rootNodeState, of("/content"), null, null, null); assertMissing(decorated, "apps"); assertMissing(decorated, "libs/foo/install"); @@ -215,7 +214,7 @@ public class FilteringNodeStateTest { @Test public void shouldHideMissingIncludedPathsViaHasChildNode() { - final NodeState decorated = wrap("/", rootNodeState, of("/content"), null); + final NodeState decorated = wrap("/", rootNodeState, of("/content"), null, null, null); assertExistingHasChildNode(decorated, "content"); assertMissingHasChildNode(decorated, "apps"); @@ -224,7 +223,7 @@ public class FilteringNodeStateTest { @Test public void shouldHideMissingIncludedPathsViaGetChildNodeNames() { - final NodeState decorated = wrap("/", rootNodeState, of("/content"), null); + final NodeState decorated = wrap("/", rootNodeState, of("/content"), null, null, null); assertExistingChildNodeName(decorated, "content"); assertMissingChildNodeName(decorated, "apps"); @@ -233,15 +232,15 @@ public class FilteringNodeStateTest { @Test public void shouldGivePrecedenceForExcludesOverIncludes() { - final NodeState conflictingRules = wrap("/", rootNodeState, of("/content"), of("/content")); + final NodeState conflictingRules = wrap("/", rootNodeState, of("/content"), of("/content"), null, null); assertMissingChildNodeName(conflictingRules, "content"); - final NodeState overlappingRules = wrap("/", rootNodeState, of("/content"), of("/content/foo")); + final NodeState overlappingRules = wrap("/", rootNodeState, of("/content"), of("/content/foo"), null, null); assertExistingChildNodeName(overlappingRules, "content"); assertMissingChildNodeName(overlappingRules.getChildNode("content"), "foo"); - final NodeState overlappingRules2 = wrap("/", rootNodeState, of("/content/foo"), of("/content")); + final NodeState overlappingRules2 = wrap("/", rootNodeState, of("/content/foo"), of("/content"), null, null); assertMissingChildNodeName(overlappingRules2, "content"); assertMissingChildNodeName(overlappingRules2.getChildNode("content"), "foo"); @@ -249,7 +248,7 @@ public class FilteringNodeStateTest { @Test public void shouldRespectPathBoundariesForIncludes() { - final NodeState decorated = wrap("/", rootNodeState, of("/content/foo"), null); + final NodeState decorated = wrap("/", rootNodeState, of("/content/foo"), null, null, null); assertExistingChildNodeName(decorated, "content"); assertExistingChildNodeName(decorated.getChildNode("content"), "foo"); @@ -258,7 +257,7 @@ public class FilteringNodeStateTest { @Test public void shouldRespectPathBoundariesForExcludes() { - final NodeState decorated = wrap("/", rootNodeState, null, of("/content/foo")); + final NodeState decorated = wrap("/", rootNodeState, null, of("/content/foo"), null, null); assertExistingChildNodeName(decorated, "content"); assertMissingChildNodeName(decorated.getChildNode("content"), "foo"); @@ -267,7 +266,7 @@ public class FilteringNodeStateTest { @Test public void shouldDelegatePropertyCount() { - final NodeState decorated = wrap("/", rootNodeState, null, of("/content/foo/de")); + final NodeState decorated = wrap("/", rootNodeState, null, of("/content/foo/de"), null, null); assertEquals(1, getNodeState(decorated, "/content").getPropertyCount()); assertEquals(0, getNodeState(decorated, "/content/foo").getPropertyCount()); @@ -276,7 +275,7 @@ public class FilteringNodeStateTest { @Test public void shouldDelegateGetProperty() { - final NodeState decorated = wrap("/", rootNodeState, null, of("/content/foo")); + final NodeState decorated = wrap("/", rootNodeState, null, of("/content/foo"), null, null); final NodeState content = getNodeState(decorated, "/content"); assertNotNull(content.getProperty(OAK_CHILD_ORDER)); @@ -286,7 +285,7 @@ public class FilteringNodeStateTest { @Test public void shouldDelegateHasProperty() { - final NodeState decorated = wrap("/", rootNodeState, null, of("/content/foo/de")); + final NodeState decorated = wrap("/", rootNodeState, null, of("/content/foo/de"), null, null); assertTrue(getNodeState(decorated, "/content").hasProperty(OAK_CHILD_ORDER)); assertFalse(getNodeState(decorated, "/content").hasProperty("foo")); @@ -295,7 +294,7 @@ public class FilteringNodeStateTest { @Test public void exists() { - final NodeState decorated = wrap("/", rootNodeState, null, of("/content/foo")); + final NodeState decorated = wrap("/", rootNodeState, null, of("/content/foo"), null, null); assertTrue("/content should exist and be visible", getNodeState(decorated, "/content").exists()); assertFalse("/content/foo should be hidden", getNodeState(decorated, "/content/foo").exists()); assertFalse("/nonexisting should not exist", getNodeState(decorated, "/nonexisting").exists());
