Added: 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=1792993&view=auto ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistoryTest.java (added) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/CopyVersionHistoryTest.java Fri Apr 28 07:16:13 2017 @@ -0,0 +1,398 @@ +/* + * 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 static org.apache.jackrabbit.JcrConstants.JCR_PREDECESSORS; +import static org.apache.jackrabbit.JcrConstants.JCR_VERSIONHISTORY; +import static org.apache.jackrabbit.JcrConstants.MIX_VERSIONABLE; +import static org.apache.jackrabbit.oak.plugins.version.VersionConstants.MIX_REP_VERSIONABLE_PATHS; +import static org.apache.jackrabbit.oak.upgrade.util.VersionCopyTestUtils.createLabeledVersions; +import static org.apache.jackrabbit.oak.upgrade.util.VersionCopyTestUtils.getOrAddNodeWithMixins; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.Calendar; +import java.util.List; +import java.util.Map; + +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyType; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.Value; +import javax.jcr.version.Version; +import javax.jcr.version.VersionHistory; +import javax.jcr.version.VersionManager; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import org.apache.jackrabbit.core.RepositoryContext; +import org.apache.jackrabbit.core.config.RepositoryConfig; +import org.apache.jackrabbit.oak.Oak; +import org.apache.jackrabbit.oak.jcr.Jcr; +import org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl; +import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore; +import org.apache.jackrabbit.oak.spi.state.NodeStore; +import org.apache.jackrabbit.oak.upgrade.util.VersionCopyTestUtils; +import org.apache.jackrabbit.oak.upgrade.util.VersionCopyTestUtils.VersionCopySetup; +import org.apache.jackrabbit.oak.upgrade.version.VersionCopyConfiguration; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Test; + +public class CopyVersionHistoryTest extends AbstractRepositoryUpgradeTest { + + private static final String VERSIONABLES_PATH_PREFIX = "/versionables/"; + + private static final String VERSIONABLES_OLD = "old"; + + private static final String VERSIONABLES_OLD_ORPHANED = "oldOrphaned"; + + private static final String VERSIONABLES_YOUNG = "young"; + + private static final String VERSIONABLES_YOUNG_ORPHANED = "youngOrphaned"; + + protected RepositoryImpl repository; + + protected List<Session> sessions = Lists.newArrayList(); + + private static Calendar betweenHistories; + + private static Map<String, String> pathToVersionHistory = Maps.newHashMap(); + + /** + * Home directory of source repository. + */ + private static File source; + + private static String[] MIXINS; + + @Override + protected void createSourceContent(Session session) throws Exception { + + if (hasSimpleVersioningSupport(session.getRepository())) { + MIXINS = new String[] { "mix:simpleVersionable", MIX_VERSIONABLE }; + } else { + MIXINS = new String[] { MIX_VERSIONABLE }; + } + + final Node root = session.getRootNode(); + + for (final String mixinType : MIXINS) { + final Node parent = VersionCopyTestUtils.getOrAddNode(root, rel(VERSIONABLES_PATH_PREFIX + mixinType)); + + final Node oldNode = getOrAddNodeWithMixins(parent, VERSIONABLES_OLD, mixinType); + pathToVersionHistory.put(oldNode.getPath(), createLabeledVersions(oldNode)); + + final Node oldOrphanNode = getOrAddNodeWithMixins(parent, VERSIONABLES_OLD_ORPHANED, mixinType); + pathToVersionHistory.put(oldOrphanNode.getPath(), createLabeledVersions(oldOrphanNode)); + } + + Thread.sleep(10); + betweenHistories = Calendar.getInstance(); + Thread.sleep(10); + + for (final String mixinType : MIXINS) { + final Node parent = VersionCopyTestUtils.getOrAddNode(root, rel(VERSIONABLES_PATH_PREFIX + mixinType)); + + final Node youngNode = getOrAddNodeWithMixins(parent, VERSIONABLES_YOUNG, mixinType); + pathToVersionHistory.put(youngNode.getPath(), createLabeledVersions(youngNode)); + + final Node youngOrphanNode = getOrAddNodeWithMixins(parent, VERSIONABLES_YOUNG_ORPHANED, mixinType); + pathToVersionHistory.put(youngOrphanNode.getPath(), createLabeledVersions(youngOrphanNode)); + + // create orphaned version histories by deleting the original nodes + parent.getNode(VERSIONABLES_OLD_ORPHANED).remove(); + parent.getNode(VERSIONABLES_YOUNG_ORPHANED).remove(); + } + + session.save(); + } + + private boolean hasSimpleVersioningSupport(final Repository repository) { + return Boolean.parseBoolean(repository.getDescriptor(Repository.OPTION_SIMPLE_VERSIONING_SUPPORTED)); + } + + @Override + protected void doUpgradeRepository(File source, NodeStore target) throws RepositoryException { + // abuse this method to capture the source repo directory + CopyVersionHistoryTest.source = source; + } + + @AfterClass + public static void teardown() { + CopyVersionHistoryTest.pathToVersionHistory.clear(); + CopyVersionHistoryTest.source = null; + } + + @Test + public void copyAllVersions() throws RepositoryException, IOException { + Session session = performCopy(new VersionCopySetup() { + @Override + public void setup(VersionCopyConfiguration config) { + // copying all versions is enabled by default + } + }); + + assertVersionableProperties(session, VERSIONABLES_OLD, VERSIONABLES_YOUNG); + assertExistingHistories(session, + VERSIONABLES_OLD, VERSIONABLES_OLD_ORPHANED, VERSIONABLES_YOUNG, VERSIONABLES_YOUNG_ORPHANED); + assertVersionablePaths(session, VERSIONABLES_OLD, VERSIONABLES_YOUNG); + assertVersionsCanBeRestored(session, VERSIONABLES_OLD, VERSIONABLES_YOUNG); + } + + @Test + public void referencedSinceDate() throws RepositoryException, IOException { + Session session = performCopy(new VersionCopySetup() { + @Override + public void setup(VersionCopyConfiguration config) { + config.setCopyVersions(betweenHistories); + } + }); + + assertVersionableProperties(session, VERSIONABLES_YOUNG); + assertExistingHistories(session, VERSIONABLES_YOUNG, VERSIONABLES_YOUNG_ORPHANED); + assertVersionablePaths(session, VERSIONABLES_YOUNG); + assertMissingHistories(session, VERSIONABLES_OLD, VERSIONABLES_OLD_ORPHANED); + assertVersionsCanBeRestored(session, VERSIONABLES_YOUNG); + } + + @Test + public void referencedOlderThanOrphaned() throws RepositoryException, IOException { + Session session = performCopy(new VersionCopySetup() { + @Override + public void setup(VersionCopyConfiguration config) { + config.setCopyOrphanedVersions(betweenHistories); + } + }); + + assertVersionableProperties(session, VERSIONABLES_OLD, VERSIONABLES_YOUNG); + assertExistingHistories(session, VERSIONABLES_OLD, VERSIONABLES_YOUNG, VERSIONABLES_YOUNG_ORPHANED); + assertVersionablePaths(session, VERSIONABLES_OLD, VERSIONABLES_YOUNG); + assertMissingHistories(session, VERSIONABLES_OLD_ORPHANED); + assertVersionsCanBeRestored(session, VERSIONABLES_OLD, VERSIONABLES_YOUNG); + } + + @Test + public void onlyReferenced() throws RepositoryException, IOException { + Session session = performCopy(new VersionCopySetup() { + @Override + public void setup(VersionCopyConfiguration config) { + config.setCopyOrphanedVersions(null); + } + }); + assertVersionableProperties(session, VERSIONABLES_OLD, VERSIONABLES_YOUNG); + assertExistingHistories(session, VERSIONABLES_OLD, VERSIONABLES_YOUNG); + assertVersionablePaths(session, VERSIONABLES_OLD, VERSIONABLES_YOUNG);; + assertMissingHistories(session, VERSIONABLES_OLD_ORPHANED, VERSIONABLES_YOUNG_ORPHANED); + assertVersionsCanBeRestored(session, VERSIONABLES_OLD, VERSIONABLES_YOUNG); + } + + @Test + public void onlyReferencedAfterDate() throws RepositoryException, IOException { + Session session = performCopy(new VersionCopySetup() { + @Override + public void setup(VersionCopyConfiguration config) { + config.setCopyVersions(betweenHistories); + config.setCopyOrphanedVersions(null); + } + }); + assertVersionableProperties(session, VERSIONABLES_YOUNG); + assertExistingHistories(session, VERSIONABLES_YOUNG); + assertVersionablePaths(session, VERSIONABLES_YOUNG); + assertMissingHistories(session, VERSIONABLES_OLD, VERSIONABLES_OLD_ORPHANED, VERSIONABLES_YOUNG_ORPHANED); + assertVersionsCanBeRestored(session, VERSIONABLES_YOUNG); + } + + @Test + public void overrideOrphaned() throws RepositoryException, IOException { + Session session = performCopy(new VersionCopySetup() { + @Override + public void setup(VersionCopyConfiguration config) { + config.setCopyVersions(null); + config.setCopyOrphanedVersions(betweenHistories); + } + }); + + assertMissingHistories(session, + VERSIONABLES_OLD, VERSIONABLES_OLD_ORPHANED, VERSIONABLES_YOUNG, VERSIONABLES_YOUNG_ORPHANED); + } + + @Test + public void dontCopyVersionHistory() throws RepositoryException, IOException { + Session session = performCopy(new VersionCopySetup() { + @Override + public void setup(VersionCopyConfiguration config) { + config.setCopyVersions(null); + config.setCopyOrphanedVersions(null); + } + }); + + assertMissingHistories(session, + VERSIONABLES_OLD, VERSIONABLES_OLD_ORPHANED, VERSIONABLES_YOUNG, VERSIONABLES_YOUNG_ORPHANED); + assertNotNull(session.getNode("/jcr:system/jcr:versionStorage") + .getPrimaryNodeType()); + } + + protected Session performCopy(VersionCopySetup setup) 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); + setup.setup(upgrade.versionCopyConfiguration); + upgrade.setEarlyShutdown(true); + 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 + public void closeRepository() { + for (Session s : sessions) { + s.logout(); + } + sessions.clear(); + repository.shutdown(); + } + + private static String rel(final String path) { + if (path.startsWith("/")) { + return path.substring(1); + } + return path; + } + + private static VersionHistory getVersionHistoryForPath(Session session, String path) + throws RepositoryException { + final Node root = session.getRootNode(); + if (root.hasNode(rel(pathToVersionHistory.get(path)))) { + return (VersionHistory)session.getNode(pathToVersionHistory.get(path)); + } + return null; + } + + private static void assertVersionableProperties(final Session session, final String... names) throws RepositoryException { + VersionManager vMgr = session.getWorkspace().getVersionManager(); + for (final String mixin : MIXINS) { + final String pathPrefix = VERSIONABLES_PATH_PREFIX + mixin + "/"; + for (final String name : names) { + final String path = pathPrefix + name; + Node versionable = session.getNode(path); + + String versionHistoryUuid = versionable.getProperty(JCR_VERSIONHISTORY).getString(); + assertEquals(getVersionHistoryForPath(session, path).getIdentifier(), versionHistoryUuid); + + final Version baseVersion = vMgr.getBaseVersion(path); + assertEquals("1.2", baseVersion.getName()); + final Value[] predecessors = versionable.getProperty(JCR_PREDECESSORS).getValues(); + assertEquals(1, predecessors.length); + assertEquals(baseVersion.getIdentifier(), predecessors[0].getString()); + } + } + } + + private static void assertExistingHistories(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 VersionHistory history = getVersionHistoryForPath(session, path); + assertNotNull("No history found for " + path, history); + VersionCopyTestUtils.assertLabeledVersions(history); + } + } + } + + private static void assertMissingHistories(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 VersionHistory history = getVersionHistoryForPath(session, path); + assertNull("Should not have found history for " + path, history); + } + } + } + + private static void assertVersionablePaths(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); + assertTrue("Node " + path + " should have mix:versionable mixin", node.isNodeType(MIX_VERSIONABLE)); + final VersionHistory history = getVersionHistoryForPath(session, path); + assertVersionablePath(history, path); + } + } + } + + private static void assertVersionablePath(final VersionHistory history, final String versionablePath) + throws RepositoryException { + final String workspaceName = history.getSession().getWorkspace().getName(); + assertTrue(history.isNodeType(MIX_REP_VERSIONABLE_PATHS)); + assertTrue(history.hasProperty(workspaceName)); + final Property pathProperty = history.getProperty(workspaceName); + assertEquals(PropertyType.PATH, pathProperty.getType()); + assertEquals(versionablePath, pathProperty.getString()); + } + + private static void assertVersionsCanBeRestored(final Session session, final String... names) throws RepositoryException { + VersionManager vMgr = session.getWorkspace().getVersionManager(); + for (final String mixin : MIXINS) { + final String pathPrefix = VERSIONABLES_PATH_PREFIX + mixin + "/"; + for (final String name : names) { + final String path = pathPrefix + name; + VersionHistory history = vMgr.getVersionHistory(path); + assertEquals("1.2", session.getNode(path).getProperty("version").getString()); + vMgr.restore(history.getVersion("1.0"), false); + + Node versionable = session.getNode(path); + assertEquals("1.0", versionable.getProperty("version").getString()); + + // restored node should have correct properties + String versionHistoryUuid = versionable.getProperty(JCR_VERSIONHISTORY).getString(); + assertEquals(history.getIdentifier(), versionHistoryUuid); + + final Version baseVersion = vMgr.getBaseVersion(path); + assertEquals("1.0", baseVersion.getName()); + final Value[] predecessors = versionable.getProperty(JCR_PREDECESSORS).getValues(); + assertEquals(0, predecessors.length); + assertFalse(vMgr.isCheckedOut(path)); + } + } + // after restoring, the paths should be still versionable + assertVersionablePaths(session, names); + } +}
Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IgnoreMissingBinariesTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IgnoreMissingBinariesTest.java?rev=1792993&view=auto ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IgnoreMissingBinariesTest.java (added) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IgnoreMissingBinariesTest.java Fri Apr 28 07:16:13 2017 @@ -0,0 +1,95 @@ +/* + * 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.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.FileDataStoreContainer; +import org.apache.jackrabbit.oak.upgrade.cli.container.NodeStoreContainer; +import org.apache.jackrabbit.oak.upgrade.cli.container.SegmentNodeStoreContainer; +import org.junit.Before; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.jcr.RepositoryException; +import java.io.File; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class IgnoreMissingBinariesTest extends AbstractOak2OakTest { + + private static final Logger log = LoggerFactory.getLogger(IgnoreMissingBinariesTest.class); + + private final FileDataStoreContainer blob; + + private final NodeStoreContainer source; + + private final NodeStoreContainer destination; + + @Before + public void prepare() throws Exception { + NodeStore source = getSourceContainer().open(); + try { + initContent(source); + } finally { + getSourceContainer().close(); + } + + assertTrue(new File(blob.getDirectory(), "c2/b2/b5/c2b2b532305bf4b7c73ea4f2747a788bb668cedc").delete()); + + String[] args = getArgs(); + log.info("oak2oak {}", Joiner.on(' ').join(args)); + OakUpgrade.main(args); + + createSession(); + } + + public IgnoreMissingBinariesTest() throws IOException { + blob = new FileDataStoreContainer(); + source = new SegmentNodeStoreContainer(blob); + destination = new SegmentNodeStoreContainer(blob); + } + + @Override + protected NodeStoreContainer getSourceContainer() { + return source; + } + + @Override + protected NodeStoreContainer getDestinationContainer() { + return destination; + } + + @Override + protected String[] getArgs() { + return new String[]{"--ignore-missing-binaries", "--src-datastore", blob.getDescription(), source.getDescription(), destination.getDescription()}; + } + + @Test + public void validateMigration() throws RepositoryException, IOException { + verifyContent(session); + verifyBlob(session); + assertEquals(0, session.getNode("/libs/sling/xss/config.xml/jcr:content").getProperty("jcr:data").getLength()); + } +} \ No newline at end of file Added: 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=1792993&view=auto ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java (added) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeSidegradeTest.java Fri Apr 28 07:16:13 2017 @@ -0,0 +1,80 @@ +/* + * 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 java.io.File; +import java.io.IOException; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; + +import org.apache.jackrabbit.oak.Oak; +import org.apache.jackrabbit.oak.jcr.Jcr; +import org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl; +import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore; +import org.apache.jackrabbit.oak.plugins.segment.file.FileStore; +import org.apache.jackrabbit.oak.spi.state.NodeStore; +import org.junit.Before; + +public class IncludeExcludeSidegradeTest extends IncludeExcludeUpgradeTest { + + @Before + public synchronized void upgradeRepository() throws Exception { + if (targetNodeStore == null) { + File directory = getTestDirectory(); + File source = new File(directory, "source"); + source.mkdirs(); + FileStore fileStore = FileStore.newFileStore(source).create(); + SegmentNodeStore segmentNodeStore = new SegmentNodeStore(fileStore); + RepositoryImpl repository = (RepositoryImpl) new Jcr(new Oak(segmentNodeStore).with("oak.sling")).createRepository(); + Session session = repository.login(CREDENTIALS); + try { + createSourceContent(session); + } finally { + session.save(); + session.logout(); + repository.shutdown(); + fileStore.close(); + } + final NodeStore target = getTargetNodeStore(); + doUpgradeRepository(source, target); + targetNodeStore = target; + } + } + + @Override + protected void doUpgradeRepository(File source, NodeStore target) throws RepositoryException, IOException { + FileStore fileStore = FileStore.newFileStore(source).create(); + SegmentNodeStore segmentNodeStore = new SegmentNodeStore(fileStore); + try { + final RepositorySidegrade sidegrade = new RepositorySidegrade(segmentNodeStore, target); + sidegrade.setIncludes( + "/content/foo/en", + "/content/assets/foo" + ); + sidegrade.setExcludes( + "/content/assets/foo/2013", + "/content/assets/foo/2012", + "/content/assets/foo/2011", + "/content/assets/foo/2010" + ); + sidegrade.copy(); + } finally { + fileStore.close(); + } + } +} Added: 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=1792993&view=auto ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeUpgradeTest.java (added) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/IncludeExcludeUpgradeTest.java Fri Apr 28 07:16:13 2017 @@ -0,0 +1,111 @@ +/* + * 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 org.apache.jackrabbit.commons.JcrUtils; +import org.apache.jackrabbit.core.RepositoryContext; +import org.apache.jackrabbit.core.config.RepositoryConfig; +import org.apache.jackrabbit.oak.jcr.Jcr; +import org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl; +import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore; +import org.apache.jackrabbit.oak.spi.state.NodeStore; +import org.junit.Test; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import java.io.File; +import java.io.IOException; + +public class IncludeExcludeUpgradeTest extends AbstractRepositoryUpgradeTest { + + protected NodeStore createTargetNodeStore() { + NodeStore ns = new SegmentNodeStore(); + ((RepositoryImpl) new Jcr(ns).createRepository()).shutdown(); + return ns; + } + + @Override + protected void createSourceContent(Session session) throws Exception { + JcrUtils.getOrCreateByPath("/content/foo/de", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/foo/en", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/foo/fr", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/foo/it", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/assets/foo", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/assets/foo/2015", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/assets/foo/2015/02", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/assets/foo/2015/01", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/assets/foo/2014", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/assets/foo/2013", "nt:folder", session); + JcrUtils.getOrCreateByPath("/content/assets/foo/2012", "nt:folder", session); + 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); + session.save(); + } + + @Override + protected void doUpgradeRepository(File source, NodeStore target) throws RepositoryException, IOException { + final RepositoryConfig config = RepositoryConfig.create(source); + final RepositoryContext context = RepositoryContext.create(config); + try { + final RepositoryUpgrade upgrade = new RepositoryUpgrade(context, target); + upgrade.setIncludes( + "/content/foo/en", + "/content/assets/foo" + ); + upgrade.setExcludes( + "/content/assets/foo/2013", + "/content/assets/foo/2012", + "/content/assets/foo/2011", + "/content/assets/foo/2010" + ); + upgrade.copy(null); + } finally { + context.getRepository().shutdown(); + } + } + + @Test + public void shouldHaveIncludedPaths() throws RepositoryException { + assertExisting( + "/content/foo/en", + "/content/assets/foo/2015/02", + "/content/assets/foo/2015/01", + "/content/assets/foo/2014" + ); + } + + @Test + public void shouldLackPathsThatWereNotIncluded() throws RepositoryException { + assertMissing( + "/content/foo/de", + "/content/foo/fr", + "/content/foo/it" + ); + } + + @Test + public void shouldLackExcludedPaths() throws RepositoryException { + assertMissing( + "/content/assets/foo/2013", + "/content/assets/foo/2012", + "/content/assets/foo/2011", + "/content/assets/foo/2010" + ); + } +} Added: 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=1792993&view=auto ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java (added) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/LongNameTest.java Fri Apr 28 07:16:13 2017 @@ -0,0 +1,185 @@ +/* + * 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 static com.google.common.collect.Iterables.cycle; +import static com.google.common.collect.Iterables.limit; +import static org.junit.Assert.fail; + +import java.io.File; +import java.io.IOException; + +import javax.jcr.Credentials; +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.SimpleCredentials; + +import org.apache.commons.io.FileUtils; +import org.apache.jackrabbit.core.RepositoryContext; +import org.apache.jackrabbit.core.RepositoryImpl; +import org.apache.jackrabbit.core.config.RepositoryConfig; +import org.apache.jackrabbit.oak.plugins.document.DocumentMK; +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; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +public class LongNameTest { + + public static final Credentials CREDENTIALS = new SimpleCredentials("admin", "admin".toCharArray()); + + private static final String TOO_LONG_NAME = "this string is an example of a very long node name which is approximately one hundred fifty eight bytes long so too long for the document node store to handle"; + + private static final String NOT_TOO_LONG_NAME = "this string despite it is very long as well is not too long for the document node store to handle so it may be migrated succesfully without troubles"; + + private static RepositoryConfig sourceRepositoryConfig; + + private static File crx2RepoDir; + + @BeforeClass + public static void prepareSourceRepository() throws RepositoryException, IOException, InterruptedException { + crx2RepoDir = new File("target", "upgrade-" + Clock.SIMPLE.getTimeIncreasing()); + FileUtils.deleteQuietly(crx2RepoDir); + + sourceRepositoryConfig = createCrx2Config(crx2RepoDir); + RepositoryContext ctx = RepositoryContext.create(sourceRepositoryConfig); + RepositoryImpl sourceRepository = ctx.getRepository(); + Session session = sourceRepository.login(CREDENTIALS); + try { + Assert.assertTrue(TOO_LONG_NAME.getBytes().length > 150); + Assert.assertTrue(NOT_TOO_LONG_NAME.getBytes().length < 150); + + Node longNameParent = createParent(session.getRootNode()); + Assert.assertTrue(longNameParent.getPath().length() >= 350); + + longNameParent.addNode(TOO_LONG_NAME); + longNameParent.addNode(NOT_TOO_LONG_NAME); + session.save(); + + Assert.assertTrue(longNameParent.hasNode(TOO_LONG_NAME)); + Assert.assertTrue(longNameParent.hasNode(NOT_TOO_LONG_NAME)); + + } finally { + session.logout(); + } + sourceRepository.shutdown(); + } + + private static RepositoryConfig createCrx2Config(File crx2RepoDir) throws RepositoryException, IOException { + File source = new File(crx2RepoDir, "source"); + source.mkdirs(); + return RepositoryConfig.install(source); + } + + @Test + public void longNameShouldBeSkipped() throws RepositoryException, IOException { + DocumentNodeStore nodeStore = new DocumentMK.Builder().getNodeStore(); + try { + upgrade(nodeStore, false, true); + + NodeState parent = getParent(nodeStore.getRoot()); + Assert.assertTrue(parent.hasChildNode(NOT_TOO_LONG_NAME)); + Assert.assertEquals(1, parent.getChildNodeCount(10)); + + // The following throws an DocumentStoreException: + // Assert.assertFalse(parent.hasChildNode(TOO_LONG_NAME)); + } finally { + nodeStore.dispose(); + } + } + + @Test + public void assertNoLongNamesTest() throws IOException, RepositoryException { + RepositoryConfig config = createCrx2Config(crx2RepoDir); + RepositoryContext context = RepositoryContext.create(config); + try { + RepositoryUpgrade upgrade = new RepositoryUpgrade(context, new MemoryNodeStore()); + try { + upgrade.assertNoLongNames(); + fail("Exception should be thrown"); + } catch (RepositoryException e) { + // that's fine + } + } finally { + context.getRepository().shutdown(); + } + } + + @Test(expected = RepositoryException.class) + public void longNameOnDocumentStoreThrowsAnException() throws RepositoryException, IOException { + DocumentNodeStore nodeStore = new DocumentMK.Builder().getNodeStore(); + try { + upgrade(nodeStore, false, false); + } finally { + nodeStore.dispose(); + } + } + + @Test + public void longNameOnSegmentStoreWorksFine() throws RepositoryException, IOException { + NodeStore nodeStore = new SegmentNodeStore(new MemoryStore()); + upgrade(nodeStore, false, false); + + NodeState parent = getParent(nodeStore.getRoot()); + Assert.assertTrue(parent.hasChildNode(NOT_TOO_LONG_NAME)); + Assert.assertTrue(parent.hasChildNode(TOO_LONG_NAME)); + } + + private static void upgrade(NodeStore target, boolean skipNameCheck, boolean filterLongNames) throws RepositoryException, IOException { + RepositoryConfig config = createCrx2Config(crx2RepoDir); + RepositoryContext context = RepositoryContext.create(config); + try { + RepositoryUpgrade upgrade = new RepositoryUpgrade(context, target); + upgrade.setCheckLongNames(skipNameCheck); + upgrade.setFilterLongNames(filterLongNames); + upgrade.copy(null); + } finally { + context.getRepository().shutdown(); + } + } + + private static Node createParent(Node root) throws RepositoryException { + Node current = root; + for (String segment : getParentSegments()) { + current = current.addNode(segment); + } + return current; + } + + private static NodeState getParent(NodeState root) throws RepositoryException { + NodeState current = root; + for (String segment : getParentSegments()) { + current = current.getChildNode(segment); + } + return current; + } + + private static Iterable<String> getParentSegments() { + return limit(cycle("this", "is", "a", "path"), 100); // total path + // length + // = 350 + } +} Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/PrivilegeUpgradeTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/PrivilegeUpgradeTest.java?rev=1792993&view=auto ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/PrivilegeUpgradeTest.java (added) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/PrivilegeUpgradeTest.java Fri Apr 28 07:16:13 2017 @@ -0,0 +1,267 @@ +/* + * 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 java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.jcr.NamespaceRegistry; +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.security.Privilege; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import org.apache.jackrabbit.api.JackrabbitSession; +import org.apache.jackrabbit.api.JackrabbitWorkspace; +import org.apache.jackrabbit.api.security.authorization.PrivilegeManager; +import org.apache.jackrabbit.oak.plugins.memory.PropertyStates; +import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeBits; +import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants; +import org.junit.Test; + +import static com.google.common.collect.Sets.newHashSet; +import static java.util.Arrays.asList; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertTrue; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_ADD_CHILD_NODES; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_ALL; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_LIFECYCLE_MANAGEMENT; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_LOCK_MANAGEMENT; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_MODIFY_ACCESS_CONTROL; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_MODIFY_PROPERTIES; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NODE_TYPE_MANAGEMENT; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ_ACCESS_CONTROL; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_REMOVE_CHILD_NODES; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_REMOVE_NODE; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_RETENTION_MANAGEMENT; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_VERSION_MANAGEMENT; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WORKSPACE_MANAGEMENT; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WRITE; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_ADD_PROPERTIES; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_ALTER_PROPERTIES; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_INDEX_DEFINITION_MANAGEMENT; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_PRIVILEGE_MANAGEMENT; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_NODES; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_PROPERTIES; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_REMOVE_PROPERTIES; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_USER_MANAGEMENT; +import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_WRITE; + +public class PrivilegeUpgradeTest extends AbstractRepositoryUpgradeTest { + + @Override + protected void createSourceContent(Session session) throws Exception { + JackrabbitWorkspace workspace = (JackrabbitWorkspace) session.getWorkspace(); + + NamespaceRegistry registry = workspace.getNamespaceRegistry(); + registry.registerNamespace("test", "http://www.example.org/"); + + PrivilegeManager privilegeManager = workspace.getPrivilegeManager(); + privilegeManager.registerPrivilege("test:privilege", false, null); + privilegeManager.registerPrivilege("test:aggregate", false, new String[] { "jcr:read", "test:privilege" }); + privilegeManager.registerPrivilege("test:privilege2", true, null); + privilegeManager.registerPrivilege("test:aggregate2", true, + new String[] { "test:aggregate", "test:privilege2" }); + } + + @Test + public void verifyPrivileges() throws RepositoryException { + Set<String> nonAggregatePrivileges = newHashSet( + REP_READ_NODES, REP_READ_PROPERTIES, REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, + REP_REMOVE_PROPERTIES, JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE, + JCR_READ_ACCESS_CONTROL, JCR_MODIFY_ACCESS_CONTROL, JCR_NODE_TYPE_MANAGEMENT, + JCR_VERSION_MANAGEMENT, JCR_LOCK_MANAGEMENT, JCR_LIFECYCLE_MANAGEMENT, + JCR_RETENTION_MANAGEMENT, JCR_WORKSPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT, + JCR_NAMESPACE_MANAGEMENT, REP_PRIVILEGE_MANAGEMENT, REP_USER_MANAGEMENT, + REP_INDEX_DEFINITION_MANAGEMENT, "test:privilege", "test:privilege2"); + + Map<String, Set<String>> aggregatePrivileges = Maps.newHashMap(); + aggregatePrivileges.put(JCR_READ, + ImmutableSet.of(REP_READ_NODES, REP_READ_PROPERTIES)); + aggregatePrivileges.put(JCR_MODIFY_PROPERTIES, + ImmutableSet.of(REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, REP_REMOVE_PROPERTIES)); + aggregatePrivileges.put(JCR_WRITE, + ImmutableSet.of(JCR_MODIFY_PROPERTIES, REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, + REP_REMOVE_PROPERTIES, JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, + JCR_REMOVE_NODE)); + aggregatePrivileges.put(REP_WRITE, + ImmutableSet.of(JCR_WRITE, JCR_MODIFY_PROPERTIES, REP_ADD_PROPERTIES, + REP_ALTER_PROPERTIES, REP_REMOVE_PROPERTIES, JCR_ADD_CHILD_NODES, + JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE, JCR_NODE_TYPE_MANAGEMENT)); + aggregatePrivileges.put(JCR_ALL, + ImmutableSet.of(REP_READ_NODES, REP_READ_PROPERTIES, REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, + REP_REMOVE_PROPERTIES, JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE, + JCR_READ_ACCESS_CONTROL, JCR_MODIFY_ACCESS_CONTROL, JCR_NODE_TYPE_MANAGEMENT, + JCR_VERSION_MANAGEMENT, JCR_LOCK_MANAGEMENT, JCR_LIFECYCLE_MANAGEMENT, + JCR_RETENTION_MANAGEMENT, JCR_WORKSPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT, + JCR_NAMESPACE_MANAGEMENT, REP_PRIVILEGE_MANAGEMENT, REP_USER_MANAGEMENT, + REP_INDEX_DEFINITION_MANAGEMENT, JCR_READ, JCR_MODIFY_PROPERTIES, JCR_WRITE, REP_WRITE, + "test:privilege", "test:privilege2", "test:aggregate", "test:aggregate2")); + aggregatePrivileges.put("test:aggregate", + ImmutableSet.of(JCR_READ, REP_READ_NODES, REP_READ_PROPERTIES, "test:privilege")); + aggregatePrivileges.put("test:aggregate2", + ImmutableSet.of(JCR_READ, REP_READ_NODES, REP_READ_PROPERTIES, "test:privilege", "test:privilege2", "test:aggregate")); + + JackrabbitSession session = createAdminSession(); + try { + JackrabbitWorkspace workspace = (JackrabbitWorkspace) session.getWorkspace(); + PrivilegeManager manager = workspace.getPrivilegeManager(); + Privilege[] privileges = manager.getRegisteredPrivileges(); + + for (Privilege privilege : privileges) { + if (privilege.isAggregate()) { + Set<String> expected = aggregatePrivileges.remove(privilege.getName()); + if (expected != null) { + String[] actual = getNames(privilege.getAggregatePrivileges()); + assertTrue("Miss match in aggregate privilege " + privilege.getName() + + " expected " + expected + + " actual " + Arrays.toString(actual), + newHashSet(expected).equals(newHashSet(actual))); + } + } else { + nonAggregatePrivileges.remove(privilege.getName()); + } + } + + assertTrue("Missing non aggregate privileges: " + nonAggregatePrivileges, nonAggregatePrivileges.isEmpty()); + assertTrue("Missing aggregate privileges: " + aggregatePrivileges.keySet(), aggregatePrivileges.isEmpty()); + } + finally { + session.logout(); + } + } + + private static String[] getNames(Privilege[] privileges) { + String[] names = new String[privileges.length]; + for (int i = 0; i < privileges.length; i++) { + names[i] = privileges[i].getName(); + } + return names; + } + + @Test + public void verifyCustomPrivileges() throws Exception { + JackrabbitSession session = createAdminSession(); + try { + JackrabbitWorkspace workspace = (JackrabbitWorkspace) session.getWorkspace(); + PrivilegeManager manager = workspace.getPrivilegeManager(); + + Privilege privilege = manager.getPrivilege("test:privilege"); + assertNotNull(privilege); + assertFalse(privilege.isAbstract()); + assertFalse(privilege.isAggregate()); + assertEquals(0, privilege.getDeclaredAggregatePrivileges().length); + + Privilege privilege2 = manager.getPrivilege("test:privilege2"); + assertNotNull(privilege2); + assertTrue(privilege2.isAbstract()); + assertFalse(privilege2.isAggregate()); + assertEquals(0, privilege.getDeclaredAggregatePrivileges().length); + + Privilege aggregate = manager.getPrivilege("test:aggregate"); + assertNotNull(aggregate); + assertFalse(aggregate.isAbstract()); + assertTrue(aggregate.isAggregate()); + List<Privilege> agg = ImmutableList.copyOf(aggregate.getDeclaredAggregatePrivileges()); + assertEquals(2, agg.size()); + assertTrue(agg.contains(privilege)); + assertTrue(agg.contains(manager.getPrivilege(JCR_READ))); + + Privilege aggregate2 = manager.getPrivilege("test:aggregate2"); + assertNotNull(aggregate2); + assertTrue(aggregate2.isAbstract()); + assertTrue(aggregate2.isAggregate()); + List<Privilege> agg2 = ImmutableList.copyOf(aggregate2.getDeclaredAggregatePrivileges()); + assertEquals(2, agg2.size()); + assertTrue(agg2.contains(aggregate)); + assertTrue(agg2.contains(privilege2)); + + Privilege jcrAll = manager.getPrivilege("jcr:all"); + List<Privilege> privileges = asList(jcrAll.getAggregatePrivileges()); + assertTrue(privileges.contains(privilege)); + assertTrue(privileges.contains(privilege2)); + assertTrue(privileges.contains(aggregate)); + assertTrue(privileges.contains(aggregate2)); + } finally { + session.logout(); + } + } + + @Test + public void verifyCustomPrivilegeBits() throws Exception { + JackrabbitSession session = createAdminSession(); + try { + Node privilegeRoot = session.getNode(PrivilegeConstants.PRIVILEGES_PATH); + + Node testPrivilegeNode = privilegeRoot.getNode("test:privilege"); + long l = getLong(testPrivilegeNode); + PrivilegeBits pb = readBits(testPrivilegeNode, PrivilegeConstants.REP_BITS); + + + Node testPrivilege2Node = privilegeRoot.getNode("test:privilege2"); + long l2 = getLong(testPrivilege2Node); + PrivilegeBits pb2 = readBits(testPrivilege2Node, PrivilegeConstants.REP_BITS); + + PrivilegeBits nextExpected; + if (l < l2) { + assertEquals(PrivilegeBits.NEXT_AFTER_BUILT_INS, pb); + assertEquals(pb.nextBits(), pb2); + nextExpected = pb2.nextBits(); + } else { + assertEquals(PrivilegeBits.NEXT_AFTER_BUILT_INS, pb2); + assertEquals(pb2.nextBits(), pb); + nextExpected = pb.nextBits(); + } + + // make sure the next-value has been properly set + PrivilegeBits nextBits = readBits(privilegeRoot, PrivilegeConstants.REP_NEXT); + assertEquals(nextExpected, nextBits); + + Node testAggregateNode = privilegeRoot.getNode("test:aggregate"); + PrivilegeBits aggrPb = readBits(testAggregateNode, PrivilegeConstants.REP_BITS); + PrivilegeBits expected = PrivilegeBits.getInstance(PrivilegeBits.BUILT_IN.get(PrivilegeConstants.JCR_READ), pb).unmodifiable(); + assertEquals(expected, aggrPb); + + Node testAggregate2Node = privilegeRoot.getNode("test:aggregate2"); + PrivilegeBits aggr2Pb = readBits(testAggregate2Node, PrivilegeConstants.REP_BITS); + PrivilegeBits expected2 = PrivilegeBits.getInstance(aggrPb, pb2).unmodifiable(); + assertEquals(expected2, aggr2Pb); + + } finally { + session.logout(); + } + } + + private static PrivilegeBits readBits(Node node, String name) throws RepositoryException { + return PrivilegeBits.getInstance(PropertyStates.createProperty(name, Arrays.asList(node.getProperty(name).getValues()))); + } + + private static long getLong(Node node) throws RepositoryException { + return node.getProperty(PrivilegeConstants.REP_BITS).getValues()[0].getLong(); + } +} Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositorySidegradeTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositorySidegradeTest.java?rev=1792993&view=auto ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositorySidegradeTest.java (added) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositorySidegradeTest.java Fri Apr 28 07:16:13 2017 @@ -0,0 +1,102 @@ +/* + * 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 org.apache.jackrabbit.oak.Oak; +import org.apache.jackrabbit.oak.api.CommitFailedException; +import org.apache.jackrabbit.oak.jcr.Jcr; +import org.apache.jackrabbit.oak.jcr.repository.RepositoryImpl; +import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore; +import org.apache.jackrabbit.oak.plugins.segment.file.FileStore; +import org.apache.jackrabbit.oak.spi.commit.CommitInfo; +import org.apache.jackrabbit.oak.spi.commit.EmptyHook; +import org.apache.jackrabbit.oak.spi.state.NodeBuilder; +import org.apache.jackrabbit.oak.spi.state.NodeStore; +import org.junit.Before; + +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import java.io.File; +import java.io.IOException; + +public class RepeatedRepositorySidegradeTest extends RepeatedRepositoryUpgradeTest { + + @Before + public synchronized void upgradeRepository() throws Exception { + if (!upgradeComplete) { + final File sourceDir = new File(getTestDirectory(), "jackrabbit2"); + + sourceDir.mkdirs(); + + FileStore fileStore = FileStore.newFileStore(sourceDir).create(); + SegmentNodeStore segmentNodeStore = new SegmentNodeStore(fileStore); + RepositoryImpl repository = (RepositoryImpl) new Jcr(new Oak(segmentNodeStore)).createRepository(); + Session session = repository.login(CREDENTIALS); + try { + createSourceContent(session); + } finally { + session.save(); + session.logout(); + repository.shutdown(); + fileStore.close(); + } + + final NodeStore target = getTargetNodeStore(); + doUpgradeRepository(sourceDir, target, false); + fileStore.flush(); + + fileStore = FileStore.newFileStore(sourceDir).create(); + segmentNodeStore = new SegmentNodeStore(fileStore); + repository = (RepositoryImpl) new Jcr(new Oak(segmentNodeStore)).createRepository(); + session = repository.login(CREDENTIALS); + try { + modifySourceContent(session); + } finally { + session.save(); + session.logout(); + repository.shutdown(); + fileStore.close(); + } + + doUpgradeRepository(sourceDir, target, true); + fileStore.flush(); + + upgradeComplete = true; + } + } + + @Override + protected void doUpgradeRepository(File source, NodeStore target, boolean skipInit) throws RepositoryException, IOException { + FileStore fileStore = FileStore.newFileStore(source).create(); + SegmentNodeStore segmentNodeStore = new SegmentNodeStore(fileStore); + try { + final RepositorySidegrade repositoryUpgrade = new RepositorySidegrade(segmentNodeStore, target); + + NodeBuilder builder = target.getRoot().builder(); + builder.child("foo").child("bar"); + target.merge(builder, EmptyHook.INSTANCE, CommitInfo.EMPTY); + + repositoryUpgrade.copy(); + } catch (CommitFailedException e) { + throw new RepositoryException(e); + } finally { + fileStore.close(); + } + } +} Added: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositoryUpgradeTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositoryUpgradeTest.java?rev=1792993&view=auto ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositoryUpgradeTest.java (added) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepeatedRepositoryUpgradeTest.java Fri Apr 28 07:16:13 2017 @@ -0,0 +1,208 @@ +/* + * 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 org.apache.jackrabbit.api.JackrabbitWorkspace; +import org.apache.jackrabbit.api.security.authorization.PrivilegeManager; +import org.apache.jackrabbit.commons.JcrUtils; +import org.apache.jackrabbit.core.RepositoryContext; +import org.apache.jackrabbit.core.RepositoryImpl; +import org.apache.jackrabbit.core.config.RepositoryConfig; +import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore; +import org.apache.jackrabbit.oak.plugins.segment.file.FileStore; +import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer; +import org.apache.jackrabbit.oak.spi.state.NodeBuilder; +import org.apache.jackrabbit.oak.spi.state.NodeStore; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.annotation.Nonnull; +import javax.jcr.NamespaceRegistry; +import javax.jcr.Node; +import javax.jcr.Repository; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import java.io.File; +import java.io.IOException; + +/** + * Test case to simulate an incremental upgrade, where a source repository is + * copied to target initially. Then some modifications are made in the source + * repository and these are (incrementally) copied to the target repository. + * <br> + * The expectation is that in the end the state in the target repository is + * identical to the state in the source repository, with the exception of any + * initial content that the upgrade tool created. + */ +public class RepeatedRepositoryUpgradeTest extends AbstractRepositoryUpgradeTest { + + protected static boolean upgradeComplete; + private static FileStore fileStore; + + @Override + protected NodeStore createTargetNodeStore() { + return new SegmentNodeStore(fileStore); + } + + @BeforeClass + public static void initialize() { + final File dir = new File(getTestDirectory(), "segments"); + dir.mkdirs(); + try { + fileStore = FileStore.newFileStore(dir).withMaxFileSize(128).create(); + upgradeComplete = false; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + @AfterClass + public static void cleanup() { + fileStore.close(); + fileStore = null; + } + + @Before + public synchronized void upgradeRepository() throws Exception { + if (!upgradeComplete) { + final File sourceDir = new File(getTestDirectory(), "jackrabbit2"); + + sourceDir.mkdirs(); + + RepositoryImpl source = createSourceRepository(sourceDir); + Session session = source.login(CREDENTIALS); + try { + createSourceContent(session); + } finally { + session.save(); + session.logout(); + source.shutdown(); + } + + final NodeStore target = getTargetNodeStore(); + doUpgradeRepository(sourceDir, target, false); + fileStore.flush(); + + // re-create source repo + source = createSourceRepository(sourceDir); + session = source.login(CREDENTIALS); + try { + modifySourceContent(session); + } finally { + session.save(); + session.logout(); + source.shutdown(); + } + + doUpgradeRepository(sourceDir, target, true); + fileStore.flush(); + + upgradeComplete = true; + } + } + + protected void doUpgradeRepository(File source, NodeStore target, boolean skipInit) throws RepositoryException, IOException { + final RepositoryConfig config = RepositoryConfig.create(source); + final RepositoryContext context = RepositoryContext.create(config); + try { + final RepositoryUpgrade repositoryUpgrade = new RepositoryUpgrade(context, target); + repositoryUpgrade.setSkipInitialization(skipInit); + repositoryUpgrade.copy(new RepositoryInitializer() { + @Override + public void initialize(@Nonnull NodeBuilder builder) { + builder.child("foo").child("bar"); + } + }); + } finally { + context.getRepository().shutdown(); + } + } + + @Override + protected void createSourceContent(Session session) throws RepositoryException { + registerCustomPrivileges(session); + + JcrUtils.getOrCreateByPath("/content/child1/grandchild1", "nt:unstructured", session); + JcrUtils.getOrCreateByPath("/content/child1/grandchild2", "nt:unstructured", session); + JcrUtils.getOrCreateByPath("/content/child1/grandchild3", "nt:unstructured", session); + JcrUtils.getOrCreateByPath("/content/child2/grandchild1", "nt:unstructured", session); + JcrUtils.getOrCreateByPath("/content/child2/grandchild2", "nt:unstructured", session); + + session.save(); + } + + protected void modifySourceContent(Session session) throws RepositoryException { + JcrUtils.getOrCreateByPath("/content/child2/grandchild3", "nt:unstructured", session); + JcrUtils.getOrCreateByPath("/content/child3", "nt:unstructured", session); + + final Node child1 = JcrUtils.getOrCreateByPath("/content/child1", "nt:unstructured", session); + child1.remove(); + + session.save(); + } + + private void registerCustomPrivileges(Session session) throws RepositoryException { + final JackrabbitWorkspace workspace = (JackrabbitWorkspace) session.getWorkspace(); + + final NamespaceRegistry registry = workspace.getNamespaceRegistry(); + registry.registerNamespace("test", "http://www.example.org/"); + + final PrivilegeManager privilegeManager = workspace.getPrivilegeManager(); + privilegeManager.registerPrivilege("test:privilege", false, null); + privilegeManager.registerPrivilege( + "test:aggregate", false, new String[]{"jcr:read", "test:privilege"}); + } + + @Test + public void shouldReflectSourceAfterModifications() throws Exception { + + assertExisting( + "/", + "/content", + "/content/child2", + "/content/child2/grandchild1", + "/content/child2/grandchild2", + "/content/child2/grandchild3", + "/content/child3" + ); + + assertMissing( + "/content/child1" + ); + } + + @Test + public void shouldContainCustomInitializerContent() throws Exception { + assertExisting( + "/foo", + "/foo/bar" + ); + } + + @Test + public void shouldContainUpgradeInitializedContent() throws Exception { + assertExisting( + "/rep:security", + "/oak:index" + ); + } + +} \ No newline at end of file Modified: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositoryGroupMemberUpgradeTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositoryGroupMemberUpgradeTest.java?rev=1792993&r1=1792992&r2=1792993&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositoryGroupMemberUpgradeTest.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositoryGroupMemberUpgradeTest.java Fri Apr 28 07:16:13 2017 @@ -24,7 +24,7 @@ import java.util.Iterator; import java.util.Set; import javax.jcr.Node; -import javax.jcr.Repository; +import javax.jcr.Session; import javax.jcr.nodetype.NodeType; import org.apache.jackrabbit.api.JackrabbitSession; @@ -59,27 +59,23 @@ public class RepositoryGroupMemberUpgrad return 2; } - protected void createSourceContent(Repository repository) throws Exception { - JackrabbitSession session = (JackrabbitSession) repository.login(CREDENTIALS); - try { - UserManager userMgr = session.getUserManager(); - userMgr.autoSave(false); - User users[] = new User[getNumUsers()]; - for (int i=0; i<users.length; i++) { - String userId = TEST_USER_PREFIX + i; - users[i] = userMgr.createUser(userId, userId); - } + @Override + protected void createSourceContent(Session session) throws Exception { + UserManager userMgr = ((JackrabbitSession) session).getUserManager(); + userMgr.autoSave(false); + User users[] = new User[getNumUsers()]; + for (int i = 0; i < users.length; i++) { + String userId = TEST_USER_PREFIX + i; + users[i] = userMgr.createUser(userId, userId); + } - for (int i=0; i< getNumGroups(); i++) { - Group g = userMgr.createGroup(TEST_GROUP_PREFIX + i); - for (User user : users) { - g.addMember(user); - } + for (int i = 0; i < getNumGroups(); i++) { + Group g = userMgr.createGroup(TEST_GROUP_PREFIX + i); + for (User user : users) { + g.addMember(user); } - session.save(); - } finally { - session.logout(); } + session.save(); } @Test @@ -87,7 +83,7 @@ public class RepositoryGroupMemberUpgrad JackrabbitSession session = createAdminSession(); try { UserManager userMgr = session.getUserManager(); - for (int i=0; i<getNumGroups(); i++) { + for (int i = 0; i < getNumGroups(); i++) { Group grp = (Group) userMgr.getAuthorizable(TEST_GROUP_PREFIX + i); assertNotNull(grp); Node grpNode = session.getNode(grp.getPath()); @@ -105,13 +101,13 @@ public class RepositoryGroupMemberUpgrad JackrabbitSession session = createAdminSession(); try { UserManager userMgr = session.getUserManager(); - for (int i=0; i<getNumGroups(); i++) { + for (int i = 0; i < getNumGroups(); i++) { Group grp = (Group) userMgr.getAuthorizable(TEST_GROUP_PREFIX + i); assertNotNull(grp); // check if groups have all members Set<String> testUsers = new HashSet<String>(); - for (int j=0; j<getNumUsers(); j++) { + for (int j = 0; j < getNumUsers(); j++) { testUsers.add(TEST_USER_PREFIX + j); } Iterator<Authorizable> declaredMembers = grp.getDeclaredMembers(); @@ -131,12 +127,12 @@ public class RepositoryGroupMemberUpgrad JackrabbitSession session = createAdminSession(); try { UserManager userMgr = session.getUserManager(); - for (int i=0; i<getNumUsers(); i++) { + for (int i = 0; i < getNumUsers(); i++) { User user = (User) userMgr.getAuthorizable(TEST_USER_PREFIX + i); assertNotNull(user); Set<String> groups = new HashSet<String>(); - for (int j=0; j<getNumGroups(); j++) { + for (int j = 0; j < getNumGroups(); j++) { groups.add(TEST_GROUP_PREFIX + j); } Copied: jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java (from r1792992, jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgradeTest.java) URL: http://svn.apache.org/viewvc/jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java?p2=jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java&p1=jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgradeTest.java&r1=1792992&r2=1792993&rev=1792993&view=diff ============================================================================== --- jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositoryUpgradeTest.java (original) +++ jackrabbit/oak/branches/1.0/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/RepositorySidegradeTest.java Fri Apr 28 07:16:13 2017 @@ -18,8 +18,6 @@ */ package org.apache.jackrabbit.oak.upgrade; -import static com.google.common.collect.Sets.newHashSet; -import static java.util.Arrays.asList; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertFalse; import static junit.framework.Assert.assertNotNull; @@ -30,44 +28,15 @@ import static org.apache.jackrabbit.JcrC import static org.apache.jackrabbit.JcrConstants.JCR_UUID; import static org.apache.jackrabbit.JcrConstants.MIX_VERSIONABLE; import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_ADD_CHILD_NODES; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_ALL; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_LIFECYCLE_MANAGEMENT; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_LOCK_MANAGEMENT; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_MODIFY_ACCESS_CONTROL; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_MODIFY_PROPERTIES; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NAMESPACE_MANAGEMENT; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NODE_TYPE_DEFINITION_MANAGEMENT; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_NODE_TYPE_MANAGEMENT; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_READ_ACCESS_CONTROL; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_REMOVE_CHILD_NODES; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_REMOVE_NODE; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_RETENTION_MANAGEMENT; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_VERSION_MANAGEMENT; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WORKSPACE_MANAGEMENT; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.JCR_WRITE; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_ADD_PROPERTIES; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_ALTER_PROPERTIES; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_INDEX_DEFINITION_MANAGEMENT; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_PRIVILEGE_MANAGEMENT; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_NODES; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_READ_PROPERTIES; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_REMOVE_PROPERTIES; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_USER_MANAGEMENT; -import static org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConstants.REP_WRITE; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.math.BigDecimal; -import java.util.Arrays; import java.util.Calendar; -import java.util.List; -import java.util.Map; import java.util.Random; -import java.util.Set; import javax.jcr.Binary; +import javax.jcr.Credentials; import javax.jcr.NamespaceRegistry; import javax.jcr.Node; import javax.jcr.Property; @@ -76,26 +45,33 @@ import javax.jcr.PropertyType; import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; +import javax.jcr.SimpleCredentials; import javax.jcr.Value; import javax.jcr.nodetype.NodeType; import javax.jcr.nodetype.NodeTypeManager; import javax.jcr.nodetype.NodeTypeTemplate; import javax.jcr.nodetype.PropertyDefinition; import javax.jcr.nodetype.PropertyDefinitionTemplate; -import javax.jcr.security.Privilege; import javax.jcr.version.Version; import javax.jcr.version.VersionHistory; import javax.jcr.version.VersionManager; -import com.google.common.collect.Maps; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.JackrabbitWorkspace; -import org.apache.jackrabbit.api.security.authorization.PrivilegeManager; +import org.apache.jackrabbit.oak.Oak; +import org.apache.jackrabbit.oak.jcr.Jcr; import org.apache.jackrabbit.oak.plugins.index.IndexConstants; +import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore; +import org.apache.jackrabbit.oak.spi.commit.CommitInfo; +import org.apache.jackrabbit.oak.spi.commit.EmptyHook; import org.apache.jackrabbit.oak.spi.security.user.UserConstants; +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 RepositoryUpgradeTest extends AbstractRepositoryUpgradeTest { +public class RepositorySidegradeTest { private static final Calendar DATE = Calendar.getInstance(); @@ -104,10 +80,30 @@ public class RepositoryUpgradeTest exten static { new Random().nextBytes(BINARY); } + + private static final Credentials CREDENTIALS = new SimpleCredentials("admin", "admin".toCharArray()); + + private NodeStore targetNodeStore; + private Repository targetRepository; + + @Before + public synchronized void upgradeRepository() throws Exception { + targetNodeStore = new SegmentNodeStore(); + targetRepository = new Jcr(new Oak(targetNodeStore)).createRepository(); + NodeStore source = createSourceContent(); + RepositorySidegrade sidegrade = new RepositorySidegrade(source, targetNodeStore); + sidegrade.copy(); + } + + public JackrabbitSession createAdminSession() throws RepositoryException { + return (JackrabbitSession) targetRepository.login(CREDENTIALS); + } - @Override @SuppressWarnings("unchecked") - protected void createSourceContent(Repository repository) throws Exception { + protected NodeStore createSourceContent() throws Exception { + NodeStore source = new SegmentNodeStore(); + Repository repository = new Jcr(new Oak(source)).createRepository(); + Session session = repository.login(CREDENTIALS); try { JackrabbitWorkspace workspace = @@ -116,11 +112,6 @@ public class RepositoryUpgradeTest exten NamespaceRegistry registry = workspace.getNamespaceRegistry(); registry.registerNamespace("test", "http://www.example.org/"); - PrivilegeManager privilegeManager = workspace.getPrivilegeManager(); - privilegeManager.registerPrivilege("test:privilege", false, null); - privilegeManager.registerPrivilege( - "test:aggregate", false, new String[] { "jcr:read", "test:privilege" }); - NodeTypeManager nodeTypeManager = workspace.getNodeTypeManager(); NodeTypeTemplate template = nodeTypeManager.createNodeTypeTemplate(); template.setName("test:unstructured"); @@ -196,6 +187,7 @@ public class RepositoryUpgradeTest exten } finally { binary.dispose(); } + return source; } finally { session.logout(); } @@ -214,108 +206,6 @@ public class RepositoryUpgradeTest exten } @Test - public void verifyPrivileges() throws RepositoryException { - Set<String> nonAggregatePrivileges = newHashSet( - REP_READ_NODES, REP_READ_PROPERTIES, REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, - REP_REMOVE_PROPERTIES, JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE, - JCR_READ_ACCESS_CONTROL, JCR_MODIFY_ACCESS_CONTROL, JCR_NODE_TYPE_MANAGEMENT, - JCR_VERSION_MANAGEMENT, JCR_LOCK_MANAGEMENT, JCR_LIFECYCLE_MANAGEMENT, - JCR_RETENTION_MANAGEMENT, JCR_WORKSPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT, - JCR_NAMESPACE_MANAGEMENT, REP_PRIVILEGE_MANAGEMENT, REP_USER_MANAGEMENT, - REP_INDEX_DEFINITION_MANAGEMENT); - - Map<String, String[]> aggregatePrivileges = Maps.newHashMap(); - aggregatePrivileges.put(JCR_READ, - new String[] {REP_READ_NODES, REP_READ_PROPERTIES}); - aggregatePrivileges.put(JCR_MODIFY_PROPERTIES, - new String[] {REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, REP_REMOVE_PROPERTIES}); - aggregatePrivileges.put(JCR_WRITE, - new String[] {JCR_MODIFY_PROPERTIES, REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, - REP_REMOVE_PROPERTIES, JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, - JCR_REMOVE_NODE}); - aggregatePrivileges.put(REP_WRITE, - new String[] {JCR_WRITE, JCR_MODIFY_PROPERTIES, REP_ADD_PROPERTIES, - REP_ALTER_PROPERTIES, REP_REMOVE_PROPERTIES, JCR_ADD_CHILD_NODES, - JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE, JCR_NODE_TYPE_MANAGEMENT}); - aggregatePrivileges.put(JCR_ALL, - new String[] {REP_READ_NODES, REP_READ_PROPERTIES, REP_ADD_PROPERTIES, REP_ALTER_PROPERTIES, - REP_REMOVE_PROPERTIES, JCR_ADD_CHILD_NODES, JCR_REMOVE_CHILD_NODES, JCR_REMOVE_NODE, - JCR_READ_ACCESS_CONTROL, JCR_MODIFY_ACCESS_CONTROL, JCR_NODE_TYPE_MANAGEMENT, - JCR_VERSION_MANAGEMENT, JCR_LOCK_MANAGEMENT, JCR_LIFECYCLE_MANAGEMENT, - JCR_RETENTION_MANAGEMENT, JCR_WORKSPACE_MANAGEMENT, JCR_NODE_TYPE_DEFINITION_MANAGEMENT, - JCR_NAMESPACE_MANAGEMENT, REP_PRIVILEGE_MANAGEMENT, REP_USER_MANAGEMENT, - REP_INDEX_DEFINITION_MANAGEMENT, JCR_READ, JCR_MODIFY_PROPERTIES, JCR_WRITE, REP_WRITE, - "test:privilege", "test:aggregate"}); - - JackrabbitSession session = createAdminSession(); - try { - JackrabbitWorkspace workspace = (JackrabbitWorkspace) session.getWorkspace(); - PrivilegeManager manager = workspace.getPrivilegeManager(); - Privilege[] privileges = manager.getRegisteredPrivileges(); - - for (Privilege privilege : privileges) { - if (privilege.isAggregate()) { - String[] expected = aggregatePrivileges.remove(privilege.getName()); - if (expected != null) { - String[] actual = getNames(privilege.getAggregatePrivileges()); - assertTrue("Miss match in aggregate privilege " + privilege.getName() + - " expected " + Arrays.toString(expected) + - " actual " + Arrays.toString(actual), - newHashSet(expected).equals(newHashSet(actual))); - } - } else { - nonAggregatePrivileges.remove(privilege.getName()); - } - } - - assertTrue("Missing non aggregate privileges: " + nonAggregatePrivileges, - nonAggregatePrivileges.isEmpty()); - assertTrue("Missing aggregate privileges: " + aggregatePrivileges.keySet(), - aggregatePrivileges.isEmpty()); - } - finally { - session.logout(); - } - } - - private static String[] getNames(Privilege[] privileges) { - String[] names = new String[privileges.length]; - for (int i = 0; i < privileges.length; i++) { - names[i] = privileges[i].getName(); - } - return names; - } - - @Test - public void verifyCustomPrivileges() throws Exception { - JackrabbitSession session = createAdminSession(); - try { - JackrabbitWorkspace workspace = - (JackrabbitWorkspace) session.getWorkspace(); - PrivilegeManager manager = workspace.getPrivilegeManager(); - - Privilege privilege = manager.getPrivilege("test:privilege"); - assertNotNull(privilege); - assertFalse(privilege.isAbstract()); - assertFalse(privilege.isAggregate()); - assertEquals(0, privilege.getDeclaredAggregatePrivileges().length); - - Privilege aggregate = manager.getPrivilege("test:aggregate"); - assertNotNull(aggregate); - assertFalse(aggregate.isAbstract()); - assertTrue(aggregate.isAggregate()); - assertEquals(2, aggregate.getDeclaredAggregatePrivileges().length); - - Privilege jcrAll = manager.getPrivilege("jcr:all"); - List<Privilege> privileges = asList(jcrAll.getAggregatePrivileges()); - assertTrue(privileges.contains(privilege)); - assertTrue(privileges.contains(aggregate)); - } finally { - session.logout(); - } - } - - @Test public void verifyCustomNodeTypes() throws Exception { Session session = createAdminSession(); try { @@ -546,6 +436,7 @@ public class RepositoryUpgradeTest exten frozenChild2.getProperty(JCR_FROZENUUID).getString()); VersionHistory history = manager.getVersionHistory("/versionable"); + assertTrue(history.isNodeType("rep:VersionablePaths")); Property versionablePath = history.getProperty("default"); assertEquals("/versionable", versionablePath.getString()); } finally {
