Author: thomasm Date: Fri Sep 25 10:18:10 2015 New Revision: 1705265 URL: http://svn.apache.org/viewvc?rev=1705265&view=rev Log: OAK-2171 oak-run should support repository upgrades with all available options
Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/BlobStoreFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/DummyBlobStoreFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileBlobStoreFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileDataStoreFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/Jackrabbit2Factory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/CliArgumentException.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationCliArguments.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/StoreArguments.java jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/StoreType.java jackrabbit/oak/trunk/oak-upgrade/src/main/resources/ jackrabbit/oak/trunk/oak-upgrade/src/main/resources/logback.xml jackrabbit/oak/trunk/oak-upgrade/src/main/resources/upgrade_usage.txt jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/ jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/AbstractOak2OakTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/Jcr2ToSegmentTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/JdbcToSegmentTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFbsTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToMongoFds.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/MongoToSegmentTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToJdbcTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToMongoTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/SegmentToSegmentTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/Util.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/ jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/CopyReferencesTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFbsTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToFdsTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FbsToS3Test.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FdsToFbsTest.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/ jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/BlobStoreContainer.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/DummyBlobStoreContainer.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileBlobStoreContainer.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/FileDataStoreContainer.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/JdbcNodeStoreContainer.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/MongoNodeStoreContainer.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/NodeStoreContainer.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/S3DataStoreContainer.java jackrabbit/oak/trunk/oak-upgrade/src/test/java/org/apache/jackrabbit/oak/upgrade/cli/container/SegmentNodeStoreContainer.java jackrabbit/oak/trunk/oak-upgrade/src/test/resources/jcr2.zip (with props) jackrabbit/oak/trunk/oak-upgrade/src/test/resources/segmentstore.zip (with props) Removed: jackrabbit/oak/trunk/oak-run/src/test/java/org/apache/jackrabbit/oak/run/ParseVersionCopyArgumentTest.java Modified: jackrabbit/oak/trunk/oak-run/pom.xml jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java jackrabbit/oak/trunk/oak-upgrade/pom.xml jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStore.java Modified: jackrabbit/oak/trunk/oak-run/pom.xml URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/pom.xml?rev=1705265&r1=1705264&r2=1705265&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-run/pom.xml (original) +++ jackrabbit/oak/trunk/oak-run/pom.xml Fri Sep 25 10:18:10 2015 @@ -247,11 +247,6 @@ </dependency> <dependency> <groupId>org.apache.jackrabbit</groupId> - <artifactId>oak-upgrade</artifactId> - <version>${project.version}</version> - </dependency> - <dependency> - <groupId>org.apache.jackrabbit</groupId> <artifactId>oak-lucene</artifactId> <version>${project.version}</version> </dependency> Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java?rev=1705265&r1=1705264&r2=1705265&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java (original) +++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/run/Main.java Fri Sep 25 10:18:10 2015 @@ -28,12 +28,8 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.sql.Timestamp; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Calendar; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -67,9 +63,6 @@ import joptsimple.OptionSet; import joptsimple.OptionSpec; import org.apache.commons.io.FileUtils; -import org.apache.commons.lang.time.DateUtils; -import org.apache.jackrabbit.core.RepositoryContext; -import org.apache.jackrabbit.core.config.RepositoryConfig; import org.apache.jackrabbit.oak.Oak; import org.apache.jackrabbit.oak.api.ContentRepository; import org.apache.jackrabbit.oak.benchmark.BenchmarkRunner; @@ -114,7 +107,6 @@ import org.apache.jackrabbit.oak.plugins import org.apache.jackrabbit.oak.scalability.ScalabilityRunner; import org.apache.jackrabbit.oak.spi.state.NodeState; import org.apache.jackrabbit.oak.spi.state.NodeStore; -import org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade; import org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet; import org.apache.jackrabbit.webdav.jcr.JCRWebdavServerServlet; import org.apache.jackrabbit.webdav.server.AbstractWebdavServlet; @@ -176,7 +168,7 @@ public final class Main { server(URI, args); break; case UPGRADE: - upgrade(args); + System.out.println("This command was moved to the oak-upgrade module"); break; case SCALABILITY: ScalabilityRunner.main(args); @@ -961,89 +953,6 @@ public final class Main { return false; } - private static void upgrade(String[] args) throws Exception { - OptionParser parser = new OptionParser(); - parser.accepts("datastore", "keep data store"); - ArgumentAcceptingOptionSpec<String> copyVersions = parser.accepts("copy-versions", "copy referenced versions. valid arguments: true|false|yyyy-mm-dd").withRequiredArg().defaultsTo("true"); - ArgumentAcceptingOptionSpec<String> copyOrphanedVersions = parser.accepts("copy-orphaned-versions", "copy all versions. valid arguments: true|false|yyyy-mm-dd").withRequiredArg().defaultsTo("true"); - OptionSpec<String> nonOption = parser.nonOptions(); - OptionSet options = parser.parse(args); - - List<String> argList = nonOption.values(options); - if (argList.size() == 2 || argList.size() == 3) { - File dir = new File(argList.get(0)); - File xml = new File(dir, "repository.xml"); - String dst = argList.get(1); - if (argList.size() == 3) { - xml = new File(dst); - dst = argList.get(2); - } - - RepositoryContext source = - RepositoryContext.create(RepositoryConfig.create(xml, dir)); - try { - if (dst.startsWith("mongodb://")) { - MongoClientURI uri = new MongoClientURI(dst); - MongoClient client = new MongoClient(uri); - try { - DocumentNodeStore target = new DocumentMK.Builder() - .setMongoDB(client.getDB(uri.getDatabase())) - .getNodeStore(); - try { - RepositoryUpgrade upgrade = - new RepositoryUpgrade(source, target); - upgrade.setCopyBinariesByReference( - options.has("datastore")); - setCopyVersionOptions(copyVersions.value(options), copyOrphanedVersions.value(options), upgrade); - upgrade.copy(null); - } finally { - target.dispose(); - } - } finally { - client.close(); - } - } else { - FileStore store = new FileStore(new File(dst), 256); - try { - NodeStore target = new SegmentNodeStore(store); - RepositoryUpgrade upgrade = - new RepositoryUpgrade(source, target); - upgrade.setCopyBinariesByReference( - options.has("datastore")); - upgrade.copy(null); - } finally { - store.close(); - } - } - } finally { - source.getRepository().shutdown(); - } - } else { - System.err.println("usage: upgrade <olddir> <newdir>"); - System.exit(1); - } - } - - private static void setCopyVersionOptions(String copyVersions, String copyOrphanedVersions, RepositoryUpgrade upgrade) throws ParseException { - upgrade.setCopyVersions(parseVersionCopyArgument(copyVersions)); - upgrade.setCopyOrphanedVersions(parseVersionCopyArgument(copyOrphanedVersions)); - } - - static Calendar parseVersionCopyArgument(String string) throws ParseException { - final DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); - final Calendar calendar; - - if (Boolean.parseBoolean(string)) { - calendar = Calendar.getInstance(); - calendar.setTimeInMillis(0); - } else if (string != null && string.matches("^\\d{4}-\\d{2}-\\d{2}$")) { - calendar = DateUtils.toCalendar(df.parse(string)); - } else { - calendar = null; - } - return calendar; - } - private static void server(String defaultUri, String[] args) throws Exception { OptionParser parser = new OptionParser(); Modified: jackrabbit/oak/trunk/oak-upgrade/pom.xml URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/pom.xml?rev=1705265&r1=1705264&r2=1705265&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/pom.xml (original) +++ jackrabbit/oak/trunk/oak-upgrade/pom.xml Fri Sep 25 10:18:10 2015 @@ -38,15 +38,50 @@ <configuration> <systemPropertyVariables> <derby.stream.error.file>target/derby.log</derby.stream.error.file> + <s3.properties>${s3.properties}</s3.properties> </systemPropertyVariables> </configuration> </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-shade-plugin</artifactId> + <version>1.6</version> + <executions> + <execution> + <phase>package</phase> + <goals> + <goal>shade</goal> + </goals> + <configuration> + <createDependencyReducedPom>false</createDependencyReducedPom> + <filters> + <filter> + <artifact>*</artifact> + <excludes> + </excludes> + </filter> + </filters> + <transformers> + <transformer + implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> + <mainClass>org.apache.jackrabbit.oak.upgrade.cli.OakUpgrade</mainClass> + </transformer> + </transformers> + </configuration> + </execution> + </executions> + </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.apache.jackrabbit</groupId> + <artifactId>oak-blob-cloud</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.apache.jackrabbit</groupId> <artifactId>oak-core</artifactId> <version>${project.version}</version> </dependency> @@ -61,17 +96,40 @@ <version>${jackrabbit.version}</version> </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + <dependency> + <groupId>net.sf.jopt-simple</groupId> + <artifactId>jopt-simple</artifactId> + <version>4.6</version> + </dependency> + + <dependency> + <groupId>org.mongodb</groupId> + <artifactId>mongo-java-driver</artifactId> + </dependency> + <dependency> + <groupId>org.apache.tomcat</groupId> + <artifactId>tomcat-jdbc</artifactId> + <version>7.0.64</version> + </dependency> + <!-- Logging --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> + <dependency> + <groupId>ch.qos.logback</groupId> + <artifactId>logback-classic</artifactId> + </dependency> <!-- Findbugs annotations --> <dependency> <groupId>com.google.code.findbugs</groupId> <artifactId>jsr305</artifactId> - <version>2.0.0</version> <scope>provided</scope> </dependency> @@ -93,11 +151,6 @@ <version>${h2.version}</version> <scope>test</scope> </dependency> - <dependency> - <groupId>ch.qos.logback</groupId> - <artifactId>logback-classic</artifactId> - <scope>test</scope> - </dependency> </dependencies> <!-- Workaround for http://bugs.java.com/view_bug.do?bug_id=6550655 --> @@ -116,5 +169,4 @@ </dependencies> </profile> </profiles> - </project> Modified: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStore.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStore.java?rev=1705265&r1=1705264&r2=1705265&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStore.java (original) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/blob/LengthCachingDataStore.java Fri Sep 25 10:18:10 2015 @@ -210,6 +210,7 @@ public class LengthCachingDataStore exte this.mapping = recordSizeMapping; } + @Override public long getLength() throws DataStoreException { Long size = mapping.get(getIdentifier().toString()); if (size == null) { Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/CliUtils.java Fri Sep 25 10:18:10 2015 @@ -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.cli; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.util.regex.Pattern; + +import org.apache.commons.io.IOUtils; +import org.apache.jackrabbit.oak.upgrade.cli.parser.CliArgumentException; +import org.apache.jackrabbit.oak.upgrade.cli.parser.MigrationCliArguments; +import org.apache.jackrabbit.oak.upgrade.cli.parser.OptionParserFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.io.Closer; + +import joptsimple.OptionParser; +import joptsimple.OptionSet; +import sun.misc.Signal; +import sun.misc.SignalHandler; + +@SuppressWarnings("restriction") +public class CliUtils { + + private static final Logger log = LoggerFactory.getLogger(OakUpgrade.class); + + public static MigrationCliArguments parseOrExit(OptionParser op, String... args) { + try { + OptionSet options = op.parse(args); + if (options.has(OptionParserFactory.HELP) || options.nonOptionArguments().isEmpty()) { + displayUsage(); + return null; + } + return new MigrationCliArguments(options); + } catch (Exception e) { + System.exit(getReturnCode(e)); + return null; + } + } + + public static void displayUsage() throws IOException { + System.out.println(getUsage().replace("${command}", "java -jar oak-run-*-jr2.jar upgrade")); + } + + public static String getUsage() throws IOException { + InputStream is = CliUtils.class.getClassLoader().getResourceAsStream("upgrade_usage.txt"); + try { + return IOUtils.toString(is); + } finally { + IOUtils.closeQuietly(is); + } + } + + public static int getReturnCode(Exception e) { + if (e.getMessage() != null) { + System.err.println(e.getMessage()); + } + if (e instanceof CliArgumentException) { + return ((CliArgumentException) e).getExitCode(); + } else { + e.printStackTrace(System.err); + return 1; + } + } + + public static void handleSigInt(final Closer closer) { + SignalHandler handler = new SignalHandler() { + @Override + public void handle(Signal signal) { + try { + closer.close(); + } catch (IOException e) { + log.error("Can't close", e); + } + System.exit(0); + } + }; + Signal.handle(new Signal("INT"), handler); + } + + public static void backupOldJcr2Files(String repositoryDirPath) { + // backup old jcr2 files when doing an in-place upgrade + File repositoryDir = new File(repositoryDirPath); + File crx2 = new File(repositoryDir, "crx2"); + log.info("Moving existing repository under {}", crx2.getAbsolutePath()); + crx2.mkdir(); + Pattern pattern = Pattern.compile("crx2|segmentstore"); + for (File file : repositoryDir.listFiles()) { + String name = file.getName(); + if (!pattern.matcher(name).matches()) { + file.renameTo(new File(crx2, name)); + } + } + } +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/MigrationFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,115 @@ +/* + * 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; + +import java.io.IOException; +import java.util.Iterator; +import java.util.ServiceLoader; + +import javax.jcr.RepositoryException; + +import org.apache.jackrabbit.core.RepositoryContext; +import org.apache.jackrabbit.oak.plugins.blob.datastore.DataStoreBlobStore; +import org.apache.jackrabbit.oak.spi.blob.BlobStore; +import org.apache.jackrabbit.oak.spi.commit.CommitHook; +import org.apache.jackrabbit.oak.spi.state.NodeStore; +import org.apache.jackrabbit.oak.upgrade.RepositorySidegrade; +import org.apache.jackrabbit.oak.upgrade.RepositoryUpgrade; +import org.apache.jackrabbit.oak.upgrade.cli.parser.MigrationOptions; +import org.apache.jackrabbit.oak.upgrade.cli.parser.StoreArguments; + +import com.google.common.collect.ImmutableList; +import com.google.common.io.Closer; + +public class MigrationFactory { + + protected final MigrationOptions options; + + protected final StoreArguments stores; + + protected final Closer closer; + + public MigrationFactory(MigrationOptions options, StoreArguments stores, Closer closer) { + this.options = options; + this.stores = stores; + this.closer = closer; + } + + public RepositoryUpgrade createUpgrade() throws IOException, RepositoryException { + RepositoryContext src = stores.getSrcStore().create(closer); + BlobStore srcBlobStore = new DataStoreBlobStore(src.getDataStore()); + NodeStore dstStore = createTarget(closer, srcBlobStore); + return createUpgrade(src, dstStore); + } + + public RepositorySidegrade createSidegrade() throws IOException { + BlobStore srcBlobStore = stores.getSrcBlobStore().create(closer); + NodeStore srcStore = stores.getSrcStore().create(srcBlobStore, closer); + NodeStore dstStore = createTarget(closer, srcBlobStore); + return createSidegrade(srcStore, dstStore); + } + + protected NodeStore createTarget(Closer closer, BlobStore srcBlobStore) throws IOException { + BlobStore dstBlobStore; + if (options.isCopyBinariesByReference()) { + dstBlobStore = srcBlobStore; + } else { + dstBlobStore = stores.getDstBlobStore().create(closer); + } + NodeStore dstStore = stores.getDstStore().create(dstBlobStore, closer); + return dstStore; + } + + protected RepositoryUpgrade createUpgrade(RepositoryContext source, NodeStore dstStore) { + RepositoryUpgrade upgrade = new RepositoryUpgrade(source, dstStore); + if (source.getDataStore() != null && options.isCopyBinariesByReference()) { + upgrade.setCopyBinariesByReference(true); + } + upgrade.setCopyVersions(options.getCopyVersions()); + upgrade.setCopyOrphanedVersions(options.getCopyOrphanedVersions()); + if (options.getIncludePaths() != null) { + upgrade.setIncludes(options.getIncludePaths()); + } + if (options.getExcludePaths() != null) { + upgrade.setExcludes(options.getExcludePaths()); + } + upgrade.setSkipOnError(!options.isFailOnError()); + upgrade.setEarlyShutdown(options.isEarlyShutdown()); + ServiceLoader<CommitHook> loader = ServiceLoader.load(CommitHook.class); + Iterator<CommitHook> iterator = loader.iterator(); + ImmutableList.Builder<CommitHook> builder = ImmutableList.<CommitHook> builder().addAll(iterator); + upgrade.setCustomCommitHooks(builder.build()); + return upgrade; + } + + private RepositorySidegrade createSidegrade(NodeStore srcStore, NodeStore dstStore) { + RepositorySidegrade sidegrade = new RepositorySidegrade(srcStore, dstStore); + sidegrade.setCopyVersions(options.getCopyVersions()); + sidegrade.setCopyOrphanedVersions(options.getCopyOrphanedVersions()); + if (options.getIncludePaths() != null) { + sidegrade.setIncludes(options.getIncludePaths()); + } + if (options.getExcludePaths() != null) { + sidegrade.setExcludes(options.getExcludePaths()); + } + if (options.getMergePaths() != null) { + sidegrade.setMerges(options.getMergePaths()); + } + return sidegrade; + } + +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/OakUpgrade.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,81 @@ +/* + * 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; + +import java.io.IOException; +import java.util.List; +import java.util.ServiceLoader; + +import javax.jcr.RepositoryException; + +import com.google.common.collect.Lists; +import com.google.common.io.Closer; + +import org.apache.jackrabbit.oak.spi.lifecycle.CompositeInitializer; +import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer; +import org.apache.jackrabbit.oak.upgrade.cli.parser.MigrationCliArguments; +import org.apache.jackrabbit.oak.upgrade.cli.parser.MigrationOptions; +import org.apache.jackrabbit.oak.upgrade.cli.parser.OptionParserFactory; +import org.apache.jackrabbit.oak.upgrade.cli.parser.StoreArguments; + +public class OakUpgrade { + + public static void main(String... args) throws IOException { + MigrationCliArguments cliArguments = CliUtils.parseOrExit(OptionParserFactory.create(), args); + if (cliArguments == null) { + return; + } + migrate(cliArguments); + } + + public static void migrate(MigrationCliArguments argumentParser) throws IOException { + MigrationOptions options = argumentParser.getOptions(); + StoreArguments stores = argumentParser.getStoreArguments(); + Closer closer = Closer.create(); + CliUtils.handleSigInt(closer); + MigrationFactory factory = new MigrationFactory(options, stores, closer); + try { + if (stores.getSrcStore().isJcr2()) { + upgrade(factory); + } else { + sidegrade(factory); + } + } catch (Throwable t) { + throw closer.rethrow(t); + } finally { + closer.close(); + } + if (stores.isInPlaceUpgrade()) { + CliUtils.backupOldJcr2Files(stores.getSrcPaths()[0]); + } + } + + private static void upgrade(MigrationFactory migrationFactory) throws IOException, RepositoryException { + migrationFactory.createUpgrade().copy(createCompositeInitializer()); + } + + private static void sidegrade(MigrationFactory migrationFactory) throws IOException, RepositoryException { + migrationFactory.createSidegrade().copy(); + } + + private static RepositoryInitializer createCompositeInitializer() { + ServiceLoader<RepositoryInitializer> loader = ServiceLoader.load(RepositoryInitializer.class); + List<RepositoryInitializer> initializers = Lists.newArrayList(loader.iterator()); + return new CompositeInitializer(initializers); + } + +} \ No newline at end of file Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/BlobStoreFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/BlobStoreFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/BlobStoreFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/BlobStoreFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,27 @@ +/* + * 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 java.io.IOException; + +import org.apache.jackrabbit.oak.spi.blob.BlobStore; + +import com.google.common.io.Closer; + +public interface BlobStoreFactory { + BlobStore create(Closer closer) throws IOException; +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/DummyBlobStoreFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/DummyBlobStoreFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/DummyBlobStoreFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/DummyBlobStoreFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,30 @@ +/* + * 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.oak.spi.blob.BlobStore; + +import com.google.common.io.Closer; + +public class DummyBlobStoreFactory implements BlobStoreFactory { + + @Override + public BlobStore create(Closer closer) { + return null; + } + +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileBlobStoreFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileBlobStoreFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileBlobStoreFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileBlobStoreFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,37 @@ +/* + * 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.oak.spi.blob.BlobStore; +import org.apache.jackrabbit.oak.spi.blob.FileBlobStore; + +import com.google.common.io.Closer; + +public class FileBlobStoreFactory implements BlobStoreFactory { + + private final String directory; + + public FileBlobStoreFactory(String directory) { + this.directory = directory; + } + + @Override + public BlobStore create(Closer closer) { + return new FileBlobStore(directory); + } + +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileDataStoreFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileDataStoreFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileDataStoreFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/FileDataStoreFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,54 @@ +/* + * 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 java.io.Closeable; +import java.io.IOException; + +import org.apache.jackrabbit.core.data.FileDataStore; +import org.apache.jackrabbit.oak.plugins.blob.datastore.DataStoreBlobStore; +import org.apache.jackrabbit.oak.plugins.blob.datastore.OakFileDataStore; +import org.apache.jackrabbit.oak.spi.blob.BlobStore; + +import com.google.common.io.Closer; + +public class FileDataStoreFactory implements BlobStoreFactory { + + private final String directory; + + public FileDataStoreFactory(String directory) { + this.directory = directory; + } + + @Override + public BlobStore create(Closer closer) { + OakFileDataStore delegate = new OakFileDataStore(); + delegate.setPath(directory); + delegate.init(null); + closer.register(asCloseable(delegate)); + return new DataStoreBlobStore(delegate); + } + + private static Closeable asCloseable(final FileDataStore store) { + return new Closeable() { + @Override + public void close() throws IOException { + store.close(); + } + }; + } +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/blob/S3DataStoreFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,89 @@ +/* + * 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 java.io.Closeable; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.util.Properties; + +import javax.jcr.RepositoryException; + +import org.apache.commons.io.IOUtils; +import org.apache.jackrabbit.core.data.CachingDataStore; +import org.apache.jackrabbit.core.data.DataStoreException; +import org.apache.jackrabbit.oak.blob.cloud.aws.s3.S3DataStore; +import org.apache.jackrabbit.oak.plugins.blob.datastore.DataStoreBlobStore; +import org.apache.jackrabbit.oak.spi.blob.BlobStore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.io.Closer; + +public class S3DataStoreFactory implements BlobStoreFactory { + + private static final Logger log = LoggerFactory.getLogger(S3DataStoreFactory.class); + + private final Properties props; + + private final String directory; + + public S3DataStoreFactory(String configuration, String directory) throws IOException { + this.props = new Properties(); + FileReader reader = new FileReader(new File(configuration)); + try { + props.load(reader); + } finally { + IOUtils.closeQuietly(reader); + } + this.directory = directory; + } + + @Override + public BlobStore create(Closer closer) throws IOException { + S3DataStore delegate = new S3DataStore(); + delegate.setProperties(props); + delegate.setPath(props.getProperty("path")); + try { + delegate.init(directory); + } catch (RepositoryException e) { + throw new IOException(e); + } + closer.register(asCloseable(delegate)); + return new DataStoreBlobStore(delegate); + } + + private static Closeable asCloseable(final CachingDataStore store) { + return new Closeable() { + @Override + public void close() throws IOException { + try { + while (!store.getPendingUploads().isEmpty()) { + log.info("Waiting for following uploads to finish: " + store.getPendingUploads()); + Thread.sleep(1000); + } + store.close(); + } catch (DataStoreException e) { + throw new IOException(e); + } catch (InterruptedException e) { + throw new IOException(e); + } + } + }; + } +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/Jackrabbit2Factory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/Jackrabbit2Factory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/Jackrabbit2Factory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/Jackrabbit2Factory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,107 @@ +/* + * 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.node; + +import java.io.BufferedReader; +import java.io.Closeable; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +import javax.jcr.RepositoryException; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang.StringUtils; +import org.apache.jackrabbit.core.RepositoryContext; +import org.apache.jackrabbit.core.config.RepositoryConfig; + +import com.google.common.io.Closer; + +public class Jackrabbit2Factory { + + private final File repositoryDir; + + private final File repositoryFile; + + public Jackrabbit2Factory(String repositoryDir, String repositoryFile) { + if (!isJcr2Repository(repositoryDir)) { + throw new IllegalArgumentException("Repository directory not found: " + repositoryDir); + } + this.repositoryDir = new File(repositoryDir); + this.repositoryFile = new File(repositoryFile); + if (!isRepositoryXml(repositoryFile)) { + throw new IllegalArgumentException("Repository configuration not found: " + repositoryFile); + } + } + + public RepositoryContext create(Closer closer) throws RepositoryException { + RepositoryContext source = RepositoryContext.create(RepositoryConfig.create(repositoryFile, repositoryDir)); + closer.register(asCloseable(source)); + return source; + } + + public File getRepositoryDir() { + return repositoryDir; + } + + private static Closeable asCloseable(final RepositoryContext context) { + return new Closeable() { + @Override + public void close() throws IOException { + context.getRepository().shutdown(); + } + }; + } + + public static boolean isRepositoryXml(String path) { + File file = new File(path); + if (file.isFile()) { + BufferedReader reader = null; + try { + reader = new BufferedReader(new FileReader(file)); + String line; + while ((line = reader.readLine()) != null) { + if (StringUtils.containsIgnoreCase(line, "<Repository>")) { + return true; + } + } + } catch (FileNotFoundException e) { + return false; + } catch (IOException e) { + return false; + } finally { + IOUtils.closeQuietly(reader); + } + } + return false; + } + + public static boolean isJcr2Repository(String directory) { + File dir = new File(directory); + if (!dir.isDirectory()) { + return false; + } + File workspaces = new File(dir, "workspaces"); + return workspaces.isDirectory(); + } + + @Override + public String toString() { + return String.format("JCR2[%s, %s]", repositoryDir, repositoryFile); + } +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/JdbcFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,72 @@ +/* + * 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.node; + +import org.apache.jackrabbit.oak.plugins.document.DocumentMK; +import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore; +import org.apache.jackrabbit.oak.plugins.document.rdb.RDBDataSourceFactory; +import org.apache.jackrabbit.oak.spi.blob.BlobStore; +import org.apache.jackrabbit.oak.spi.state.NodeStore; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.io.Closer; + +import javax.sql.DataSource; + +public class JdbcFactory implements NodeStoreFactory { + + private static final Logger log = LoggerFactory.getLogger(JdbcFactory.class); + + private final String jdbcUri; + + private final int cacheSize; + + private final String user; + + private final String password; + + public JdbcFactory(String jdbcUri, int cacheSize, String user, String password) { + this.jdbcUri = jdbcUri; + this.cacheSize = cacheSize; + if (user == null || password == null) { + throw new IllegalArgumentException("RBD requires username and password parameters."); + } + this.user = user; + this.password = password; + } + + @Override + public NodeStore create(BlobStore blobStore, Closer closer) { + DataSource ds = RDBDataSourceFactory.forJdbcUrl(jdbcUri, user, password); + DocumentMK.Builder builder = MongoFactory.getBuilder(cacheSize); + if (blobStore != null) { + builder.setBlobStore(blobStore); + } + builder.setRDBConnection(ds); + log.info("Initialized DocumentNodeStore on RDB with Cache size : {} MB, Fast migration : {}", cacheSize, + builder.isDisableBranches()); + DocumentNodeStore documentNodeStore = builder.getNodeStore(); + closer.register(MongoFactory.asCloseable(documentNodeStore)); + return documentNodeStore; + } + + @Override + public String toString() { + return String.format("DocumentNodeStore[%s]", jdbcUri); + } +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/MongoFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,97 @@ +/* + * 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.node; + +import org.apache.jackrabbit.oak.plugins.document.DocumentMK; +import org.apache.jackrabbit.oak.plugins.document.DocumentNodeStore; +import org.apache.jackrabbit.oak.spi.blob.BlobStore; +import org.apache.jackrabbit.oak.spi.state.NodeStore; + +import com.google.common.io.Closer; +import com.mongodb.MongoClient; +import com.mongodb.MongoClientURI; + +import java.io.Closeable; +import java.io.IOException; +import java.net.UnknownHostException; + +public class MongoFactory implements NodeStoreFactory { + + private static final long MB = 1024 * 1024; + + private final MongoClientURI uri; + + private final int cacheSize; + + public MongoFactory(String repoDesc, int cacheSize) { + this.uri = new MongoClientURI(repoDesc); + this.cacheSize = cacheSize; + } + + @Override + public NodeStore create(BlobStore blobStore, Closer closer) throws UnknownHostException { + String db; + if (uri.getDatabase() == null) { + db = "aem-author"; // assume an author instance + } else { + db = uri.getDatabase(); + } + DocumentMK.Builder builder = getBuilder(cacheSize); + MongoClient client = new MongoClient(uri); + closer.register(asCloseable(client)); + builder.setMongoDB(client.getDB(db)); + if (blobStore != null) { + builder.setBlobStore(blobStore); + } + DocumentNodeStore documentNodeStore = builder.getNodeStore(); + closer.register(asCloseable(documentNodeStore)); + return documentNodeStore; + } + + static Closeable asCloseable(final DocumentNodeStore documentNodeStore) { + return new Closeable() { + @Override + public void close() throws IOException { + documentNodeStore.dispose(); + } + }; + } + + private static Closeable asCloseable(final MongoClient client) { + return new Closeable() { + @Override + public void close() throws IOException { + client.close(); + } + }; + } + + static DocumentMK.Builder getBuilder(int cacheSize) { + boolean fastMigration = !Boolean.getBoolean("mongomk.disableFastMigration"); + DocumentMK.Builder builder = new DocumentMK.Builder(); + builder.memoryCacheSize(cacheSize * MB); + if (fastMigration) { + builder.disableBranches(); + } + return builder; + } + + @Override + public String toString() { + return String.format("DocumentNodeStore[%s]", uri.toString()); + } +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/NodeStoreFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,29 @@ +/* + * 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.node; + +import java.io.IOException; + +import org.apache.jackrabbit.oak.spi.blob.BlobStore; +import org.apache.jackrabbit.oak.spi.state.NodeStore; + +import com.google.common.io.Closer; + +public interface NodeStoreFactory { + + NodeStore create(BlobStore blobStore, Closer closer) throws IOException; +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/SegmentFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,74 @@ +/* + * 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.node; + +import java.io.Closeable; +import java.io.File; +import java.io.IOException; + +import org.apache.jackrabbit.oak.plugins.segment.SegmentNodeStore; +import org.apache.jackrabbit.oak.plugins.segment.file.FileStore; +import org.apache.jackrabbit.oak.plugins.segment.file.FileStore.Builder; +import org.apache.jackrabbit.oak.spi.blob.BlobStore; +import org.apache.jackrabbit.oak.spi.state.NodeStore; + +import com.google.common.io.Closer; + +public class SegmentFactory implements NodeStoreFactory { + + private final File dir; + + private final boolean mmap; + + public SegmentFactory(String directory, boolean mmap) { + this.dir = new File(directory); + this.mmap = mmap; + if (!dir.isDirectory()) { + throw new IllegalArgumentException("Not a directory: " + dir.getPath()); + } + } + + @Override + public NodeStore create(BlobStore blobStore, Closer closer) throws IOException { + Builder builder = FileStore.newFileStore(new File(dir, "segmentstore")); + if (blobStore != null) { + builder.withBlobStore(blobStore); + } + builder.withMaxFileSize(256).withMemoryMapping(mmap); + FileStore fs = builder.create(); + closer.register(asCloseable(fs)); + return SegmentNodeStore.newSegmentNodeStore(fs).create(); + } + + public File getRepositoryDir() { + return dir; + } + + private static Closeable asCloseable(final FileStore fs) { + return new Closeable() { + @Override + public void close() throws IOException { + fs.close(); + } + }; + } + + @Override + public String toString() { + return String.format("SegmentNodeStore[%s]", dir); + } +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/node/StoreFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,62 @@ +/* + * 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.node; + +import java.io.IOException; + +import javax.jcr.RepositoryException; + +import org.apache.jackrabbit.core.RepositoryContext; +import org.apache.jackrabbit.oak.spi.blob.BlobStore; +import org.apache.jackrabbit.oak.spi.state.NodeStore; + +import com.google.common.io.Closer; + +public class StoreFactory { + + private final Jackrabbit2Factory jcr2Factory; + + private final NodeStoreFactory nodeStoreFactory; + + public StoreFactory(Jackrabbit2Factory crx2Factory) { + this.jcr2Factory = crx2Factory; + this.nodeStoreFactory = null; + } + + public StoreFactory(NodeStoreFactory nodeStoreFactory) { + this.jcr2Factory = null; + this.nodeStoreFactory = nodeStoreFactory; + } + + public RepositoryContext create(Closer closer) throws IOException, RepositoryException { + if (jcr2Factory == null) { + throw new UnsupportedOperationException(); + } + return jcr2Factory.create(closer); + } + + public NodeStore create(BlobStore blobStore, Closer closer) throws IOException { + if (nodeStoreFactory == null) { + throw new UnsupportedOperationException(); + } + return nodeStoreFactory.create(blobStore, closer); + } + + public boolean isJcr2() { + return jcr2Factory != null; + } +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/CliArgumentException.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/CliArgumentException.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/CliArgumentException.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/CliArgumentException.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,38 @@ +/* + * 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.parser; + +public class CliArgumentException extends Exception { + + private static final long serialVersionUID = -7579563789244874904L; + + private final int exitCode; + + public CliArgumentException(int exitCode) { + super(); + this.exitCode = exitCode; + } + + public CliArgumentException(String message, int exitCode) { + super(message); + this.exitCode = exitCode; + } + + public int getExitCode() { + return exitCode; + } +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationCliArguments.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationCliArguments.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationCliArguments.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationCliArguments.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,81 @@ +/* + * 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.parser; + +import java.util.ArrayList; +import java.util.List; + +import joptsimple.OptionSet; + +public final class MigrationCliArguments { + + private final OptionSet options; + + private final List<String> arguments; + + private final MigrationOptions migrationOptions; + + private final StoreArguments storeArguments; + + public MigrationCliArguments(OptionSet options) throws CliArgumentException { + this.options = options; + arguments = getNonOptionArguments(); + migrationOptions = new MigrationOptions(this); + storeArguments = new StoreArguments(this); + } + + private List<String> getNonOptionArguments() { + List<String> args = new ArrayList<String>(); + for (Object o : options.nonOptionArguments()) { + args.add(o.toString()); + } + return args; + } + + public boolean hasOption(String optionName) { + return options.has(optionName); + } + + public String getOption(String optionName) { + return (String) options.valueOf(optionName); + } + + public int getIntOption(String optionName) { + return (Integer) options.valueOf(optionName); + } + + public String[] getOptionList(String optionName) { + String option = getOption(optionName); + if (option == null) { + return null; + } else { + return option.split(","); + } + } + + public MigrationOptions getOptions() { + return migrationOptions; + } + + public StoreArguments getStoreArguments() { + return storeArguments; + } + + List<String> getArguments() { + return arguments; + } +} Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/MigrationOptions.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,192 @@ +/* + * 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.parser; + +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class MigrationOptions { + + private static final Logger log = LoggerFactory.getLogger(MigrationOptions.class); + + private static final DateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd"); + + private final boolean copyBinariesByReference; + + private final boolean mmap; + + private final int cacheSizeInMB; + + private final Calendar copyVersions; + + private final Calendar copyOrphanedVersions; + + private final String[] includePaths; + + private final String[] excludePaths; + + private final String[] mergePaths; + + private final boolean failOnError; + + private final boolean earlyShutdown; + + public MigrationOptions(MigrationCliArguments args) { + this.copyBinariesByReference = !args.hasOption(OptionParserFactory.COPY_BINARIES); + this.mmap = args.hasOption(OptionParserFactory.MMAP); + if (args.hasOption(OptionParserFactory.CACHE_SIZE)) { + this.cacheSizeInMB = args.getIntOption(OptionParserFactory.CACHE_SIZE); + } else { + this.cacheSizeInMB = 256; + } + + final Calendar epoch = Calendar.getInstance(); + epoch.setTimeInMillis(0); + if (args.hasOption(OptionParserFactory.COPY_VERSIONS)) { + this.copyVersions = parseVersionCopyArgument(args.getOption(OptionParserFactory.COPY_VERSIONS)); + } else { + this.copyVersions = epoch; + } + if (args.hasOption(OptionParserFactory.COPY_ORPHANED_VERSIONS)) { + this.copyOrphanedVersions = parseVersionCopyArgument(args.getOption(OptionParserFactory.COPY_ORPHANED_VERSIONS)); + } else { + this.copyOrphanedVersions = epoch; + } + this.includePaths = split(args.getOption(OptionParserFactory.INCLUDE_PATHS)); + this.excludePaths = split(args.getOption(OptionParserFactory.EXCLUDE_PATHS)); + this.mergePaths = split(args.getOption(OptionParserFactory.MERGE_PATHS)); + this.failOnError = args.hasOption(OptionParserFactory.FAIL_ON_ERROR); + this.earlyShutdown = args.hasOption(OptionParserFactory.EARLY_SHUTDOWN); + logOptions(); + } + + public boolean isCopyBinariesByReference() { + return copyBinariesByReference; + } + + public boolean isMmap() { + return mmap; + } + + public int getCacheSizeInMB() { + return cacheSizeInMB; + } + + public Calendar getCopyVersions() { + return copyVersions; + } + + public Calendar getCopyOrphanedVersions() { + return copyOrphanedVersions; + } + + public String[] getIncludePaths() { + return includePaths; + } + + public String[] getExcludePaths() { + return excludePaths; + } + + public String[] getMergePaths() { + return mergePaths; + } + + public boolean isFailOnError() { + return failOnError; + } + + public boolean isEarlyShutdown() { + return earlyShutdown; + } + + private void logOptions() { + if (copyBinariesByReference) { + log.info("DataStore needs to be shared with new repository"); + } else { + log.info("Binary content would be copied to the NodeStore."); + } + + if (mmap) { + log.info("Enabling memory mapped file access for Segment Store"); + } + + if (copyVersions == null) { + log.info("copyVersions parameter set to false"); + } else { + log.info("copyVersions parameter set to {}", DATE_FORMAT.format(copyVersions.getTime())); + } + + if (copyOrphanedVersions == null) { + log.info("copyOrphanedVersions parameter set to false"); + } else { + log.info("copyOrphanedVersions parameter set to {}", DATE_FORMAT.format(copyOrphanedVersions.getTime())); + } + + if (includePaths != null) { + log.info("paths to include: {}", (Object) includePaths); + } + + if (excludePaths != null) { + log.info("paths to exclude: {}", (Object) excludePaths); + } + + if (failOnError) { + log.info("Unreadable nodes will cause failure of the entire transaction"); + } + + if (earlyShutdown) { + log.info("Source repository would be shutdown post copying of nodes"); + } + + log.info("Cache size: {} MB", cacheSizeInMB); + + } + + private static String[] split(String list) { + if (list == null) { + return null; + } else { + return list.split(","); + } + } + + private static Calendar parseVersionCopyArgument(String string) { + final Calendar calendar; + + if (Boolean.parseBoolean(string)) { + calendar = Calendar.getInstance(); + calendar.setTimeInMillis(0); + } else if (string != null && string.matches("^\\d{4}-\\d{2}-\\d{2}$")) { + calendar = Calendar.getInstance(); + try { + calendar.setTime(DATE_FORMAT.parse(string)); + } catch (ParseException e) { + return null; + } + } else { + calendar = null; + } + return calendar; + } + +} \ No newline at end of file Added: jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java?rev=1705265&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java (added) +++ jackrabbit/oak/trunk/oak-upgrade/src/main/java/org/apache/jackrabbit/oak/upgrade/cli/parser/OptionParserFactory.java Fri Sep 25 10:18:10 2015 @@ -0,0 +1,133 @@ +/* + * 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.parser; + +import static java.util.Arrays.asList; + +import joptsimple.OptionParser; + +public class OptionParserFactory { + + public static final String COPY_BINARIES = "copy-binaries"; + + public static final String MMAP = "mmap"; + + public static final String FAIL_ON_ERROR = "fail-on-error"; + + public static final String EARLY_SHUTDOWN = "early-shutdown"; + + public static final String CACHE_SIZE = "cache"; + + public static final String HELP = "help"; + + public static final String DST_USER = "user"; + + public static final String DST_PASSWORD = "password"; + + public static final String SRC_USER = "src-user"; + + public static final String SRC_PASSWORD = "src-password"; + + public static final String SRC_FBS = "src-fileblobstore"; + + public static final String SRC_FDS = "src-datastore"; + + public static final String DST_FDS = "datastore"; + + public static final String DST_FBS = "fileblobstore"; + + public static final String DST_S3 = "s3datastore"; + + public static final String DST_S3_CONFIG = "s3config"; + + public static final String COPY_VERSIONS = "copy-versions"; + + public static final String COPY_ORPHANED_VERSIONS = "copy-orphaned-versions"; + + public static final String INCLUDE_PATHS = "include-paths"; + + public static final String EXCLUDE_PATHS = "exclude-paths"; + + public static final String MERGE_PATHS = "merge-paths"; + + public static OptionParser create() { + OptionParser op = new OptionParser(); + addUsageOptions(op); + addBlobOptions(op); + addRdbOptions(op); + addPathsOptions(op); + addVersioningOptions(op); + addMiscOptions(op); + +// op.nonOptions( +// "[/path/to/oak/repository|/path/to/crx2/repository|mongodb://host:port|<Jdbc URI>] [/path/to/repository.xml] {/path/to/oak/repository|mongodb://host:port|<Jdbc URI>}"); + + return op; + } + + private static void addUsageOptions(OptionParser op) { + op.acceptsAll(asList("h", "?", HELP), "show help").forHelp(); + } + + private static void addBlobOptions(OptionParser op) { + op.accepts(COPY_BINARIES, "Copy binary content. Use this to disable use of existing DataStore in new repo"); + op.accepts(SRC_FDS, "Datastore directory to be used as a source FileDataStore").withRequiredArg() + .ofType(String.class); + op.accepts(SRC_FBS, "Datastore directory to be used as a source FileBlobStore").withRequiredArg() + .ofType(String.class); + op.accepts(DST_FDS, "Datastore directory to be used as a target FileDataStore").withRequiredArg() + .ofType(String.class); + op.accepts(DST_FBS, "Datastore directory to be used as a target FileBlobStore").withRequiredArg() + .ofType(String.class); + op.accepts(DST_S3, "Repository home to be used for the target S3").withRequiredArg().ofType(String.class); + op.accepts(DST_S3_CONFIG, "Configuration file for the target S3DataStore").withRequiredArg() + .ofType(String.class); + } + + private static void addRdbOptions(OptionParser op) { + op.accepts(SRC_USER, "Source rdb user").withRequiredArg().ofType(String.class); + op.accepts(SRC_PASSWORD, "Source rdb password").withRequiredArg().ofType(String.class); + op.accepts(DST_USER, "Target rdb user").withRequiredArg().ofType(String.class); + op.accepts(DST_PASSWORD, "Target rdb password").withRequiredArg().ofType(String.class); + } + + private static void addPathsOptions(OptionParser op) { + op.accepts(INCLUDE_PATHS, "Comma-separated list of paths to include during copy.").withRequiredArg() + .ofType(String.class); + op.accepts(EXCLUDE_PATHS, "Comma-separated list of paths to exclude during copy.").withRequiredArg() + .ofType(String.class); + op.accepts(MERGE_PATHS, "Comma-separated list of paths to merge during copy.").withRequiredArg() + .ofType(String.class); + } + + private static void addVersioningOptions(OptionParser op) { + op.accepts(COPY_VERSIONS, + "Copy the version storage. Parameters: { true | false | yyyy-mm-dd }. Defaults to true.") + .withRequiredArg().ofType(String.class); + op.accepts(COPY_ORPHANED_VERSIONS, + "Allows to skip copying orphaned versions. Parameters: { true | false | yyyy-mm-dd }. Defaults to true.") + .withRequiredArg().ofType(String.class); + } + + private static void addMiscOptions(OptionParser op) { + op.accepts(MMAP, "Enable memory mapped file access for Segment Store"); + op.accepts(FAIL_ON_ERROR, "Fail completely if nodes can't be read from the source repo"); + op.accepts(EARLY_SHUTDOWN, + "Shutdown the source repository after nodes are copied and before the commit hooks are applied"); + op.accepts(CACHE_SIZE, "Cache size in MB").withRequiredArg().ofType(Integer.class).defaultsTo(256); + } +}